mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 05:45:41 +00:00
[NETAPI32]
Implement parts of NetUserAdd. svn path=/trunk/; revision=58071
This commit is contained in:
parent
e2273f3e3e
commit
f039f501b4
1 changed files with 212 additions and 70 deletions
|
@ -31,7 +31,7 @@ typedef struct _ENUM_CONTEXT
|
||||||
|
|
||||||
SAM_ENUMERATE_HANDLE EnumerationContext;
|
SAM_ENUMERATE_HANDLE EnumerationContext;
|
||||||
PSAM_RID_ENUMERATION Buffer;
|
PSAM_RID_ENUMERATION Buffer;
|
||||||
ULONG Returned;
|
ULONG Count;
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
BOOLEAN BuiltinDone;
|
BOOLEAN BuiltinDone;
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ BuildUserInfoBuffer(PUSER_ACCOUNT_INFORMATION UserInfo,
|
||||||
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
|
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
|
||||||
}
|
}
|
||||||
|
|
||||||
UserInfo1->usri1_flags = UserInfo->UserAccountControl;
|
// UserInfo1->usri1_flags = UserInfo->UserAccountControl;
|
||||||
|
|
||||||
if (UserInfo->ScriptPath.Length > 0)
|
if (UserInfo->ScriptPath.Length > 0)
|
||||||
{
|
{
|
||||||
|
@ -342,7 +342,7 @@ BuildUserInfoBuffer(PUSER_ACCOUNT_INFORMATION UserInfo,
|
||||||
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
|
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
|
||||||
}
|
}
|
||||||
|
|
||||||
UserInfo20->usri20_flags = UserInfo->UserAccountControl;
|
// UserInfo20->usri20_flags = UserInfo->UserAccountControl;
|
||||||
UserInfo20->usri20_user_id = RelativeId;
|
UserInfo20->usri20_user_id = RelativeId;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -399,6 +399,131 @@ FreeUserInfo(PUSER_ACCOUNT_INFORMATION UserInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
NET_API_STATUS
|
||||||
|
SetUserInfo(SAM_HANDLE UserHandle,
|
||||||
|
LPBYTE UserInfo,
|
||||||
|
DWORD Level)
|
||||||
|
{
|
||||||
|
USER_ALL_INFORMATION UserAllInfo;
|
||||||
|
PUSER_INFO_1 UserInfo1;
|
||||||
|
PUSER_INFO_3 UserInfo3;
|
||||||
|
NET_API_STATUS ApiStatus = NERR_Success;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
ZeroMemory(&UserAllInfo, sizeof(USER_ALL_INFORMATION));
|
||||||
|
|
||||||
|
switch (Level)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
UserInfo1 = (PUSER_INFO_1)UserInfo;
|
||||||
|
// RtlInitUnicodeString(&UserAllInfo.UserName,
|
||||||
|
// UserInfo1->usri1_name);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&UserAllInfo.AdminComment,
|
||||||
|
UserInfo1->usri1_comment);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
|
||||||
|
UserInfo1->usri1_home_dir);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&UserAllInfo.ScriptPath,
|
||||||
|
UserInfo1->usri1_script_path);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&UserAllInfo.NtPassword,
|
||||||
|
UserInfo1->usri1_password);
|
||||||
|
UserAllInfo.NtPasswordPresent = TRUE;
|
||||||
|
|
||||||
|
// UserInfo1->usri1_flags
|
||||||
|
// UserInfo1->usri1_priv
|
||||||
|
|
||||||
|
UserAllInfo.WhichFields =
|
||||||
|
USER_ALL_ADMINCOMMENT |
|
||||||
|
USER_ALL_HOMEDIRECTORY |
|
||||||
|
USER_ALL_SCRIPTPATH |
|
||||||
|
USER_ALL_NTPASSWORDPRESENT
|
||||||
|
// USER_ALL_USERACCOUNTCONTROL
|
||||||
|
;
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
UserInfo3 = (PUSER_INFO_3)UserInfo;
|
||||||
|
|
||||||
|
// LPWSTR usri3_name;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&UserAllInfo.NtPassword,
|
||||||
|
UserInfo3->usri3_password);
|
||||||
|
UserAllInfo.NtPasswordPresent = TRUE;
|
||||||
|
|
||||||
|
// DWORD usri3_password_age; // ignored
|
||||||
|
// DWORD usri3_priv;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
|
||||||
|
UserInfo3->usri3_home_dir);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&UserAllInfo.AdminComment,
|
||||||
|
UserInfo3->usri3_comment);
|
||||||
|
|
||||||
|
// DWORD usri3_flags;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&UserAllInfo.ScriptPath,
|
||||||
|
UserInfo3->usri3_script_path);
|
||||||
|
|
||||||
|
// DWORD usri3_auth_flags;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&UserAllInfo.FullName,
|
||||||
|
UserInfo3->usri3_full_name);
|
||||||
|
|
||||||
|
// LPWSTR usri3_usr_comment;
|
||||||
|
// LPWSTR usri3_parms;
|
||||||
|
// LPWSTR usri3_workstations;
|
||||||
|
// DWORD usri3_last_logon;
|
||||||
|
// DWORD usri3_last_logoff;
|
||||||
|
// DWORD usri3_acct_expires;
|
||||||
|
// DWORD usri3_max_storage;
|
||||||
|
// DWORD usri3_units_per_week;
|
||||||
|
// PBYTE usri3_logon_hours;
|
||||||
|
// DWORD usri3_bad_pw_count;
|
||||||
|
// DWORD usri3_num_logons;
|
||||||
|
// LPWSTR usri3_logon_server;
|
||||||
|
// DWORD usri3_country_code;
|
||||||
|
// DWORD usri3_code_page;
|
||||||
|
// DWORD usri3_user_id; // ignored
|
||||||
|
// DWORD usri3_primary_group_id;
|
||||||
|
// LPWSTR usri3_profile;
|
||||||
|
// LPWSTR usri3_home_dir_drive;
|
||||||
|
// DWORD usri3_password_expired;
|
||||||
|
|
||||||
|
UserAllInfo.WhichFields =
|
||||||
|
USER_ALL_NTPASSWORDPRESENT |
|
||||||
|
USER_ALL_HOMEDIRECTORY |
|
||||||
|
USER_ALL_ADMINCOMMENT |
|
||||||
|
USER_ALL_SCRIPTPATH |
|
||||||
|
USER_ALL_FULLNAME
|
||||||
|
// USER_ALL_USERACCOUNTCONTROL
|
||||||
|
;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ERR("Unsupported level %lu!\n", Level);
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = SamSetInformationUser(UserHandle,
|
||||||
|
UserAllInformation,
|
||||||
|
&UserAllInfo);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("SamSetInformationUser failed (Status %08lx)\n", Status);
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
return ApiStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* NetUserAdd (NETAPI32.@)
|
* NetUserAdd (NETAPI32.@)
|
||||||
*/
|
*/
|
||||||
|
@ -409,72 +534,89 @@ NetUserAdd(LPCWSTR servername,
|
||||||
LPBYTE bufptr,
|
LPBYTE bufptr,
|
||||||
LPDWORD parm_err)
|
LPDWORD parm_err)
|
||||||
{
|
{
|
||||||
NET_API_STATUS status;
|
UNICODE_STRING ServerName;
|
||||||
struct sam_user * su = NULL;
|
UNICODE_STRING UserName;
|
||||||
|
SAM_HANDLE ServerHandle = NULL;
|
||||||
|
SAM_HANDLE DomainHandle = NULL;
|
||||||
|
SAM_HANDLE UserHandle = NULL;
|
||||||
|
ULONG GrantedAccess;
|
||||||
|
ULONG RelativeId;
|
||||||
|
NET_API_STATUS ApiStatus = NERR_Success;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
FIXME("(%s, %d, %p, %p) stub!\n", debugstr_w(servername), level, bufptr, parm_err);
|
FIXME("(%s, %d, %p, %p)\n", debugstr_w(servername), level, bufptr, parm_err);
|
||||||
|
|
||||||
if((status = NETAPI_ValidateServername(servername)) != NERR_Success)
|
/* Check the info level */
|
||||||
return status;
|
if (level < 1 || level > 4)
|
||||||
|
return ERROR_INVALID_LEVEL;
|
||||||
|
|
||||||
switch(level)
|
if (servername != NULL)
|
||||||
|
RtlInitUnicodeString(&ServerName, servername);
|
||||||
|
|
||||||
|
/* Connect to the SAM Server */
|
||||||
|
Status = SamConnect((servername != NULL) ? &ServerName : NULL,
|
||||||
|
&ServerHandle,
|
||||||
|
SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Level 3 and 4 are identical for the purposes of NetUserAdd */
|
ERR("SamConnect failed (Status %08lx)\n", Status);
|
||||||
case 4:
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
case 3:
|
goto done;
|
||||||
FIXME("Level 3 and 4 not implemented.\n");
|
|
||||||
/* Fall through */
|
|
||||||
case 2:
|
|
||||||
FIXME("Level 2 not implemented.\n");
|
|
||||||
/* Fall through */
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
PUSER_INFO_1 ui = (PUSER_INFO_1) bufptr;
|
|
||||||
su = HeapAlloc(GetProcessHeap(), 0, sizeof(struct sam_user));
|
|
||||||
if(!su)
|
|
||||||
{
|
|
||||||
status = NERR_InternalError;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lstrlenW(ui->usri1_name) > LM20_UNLEN)
|
/* Open the Account Domain */
|
||||||
|
Status = OpenAccountDomain(ServerHandle,
|
||||||
|
(servername != NULL) ? &ServerName : NULL,
|
||||||
|
DOMAIN_CREATE_USER | DOMAIN_LOOKUP,
|
||||||
|
&DomainHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
status = NERR_BadUsername;
|
ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
|
||||||
break;
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*FIXME: do other checks for a valid username */
|
/* Initialize the user name string */
|
||||||
lstrcpyW(su->user_name, ui->usri1_name);
|
RtlInitUnicodeString(&UserName,
|
||||||
|
((PUSER_INFO_1)bufptr)->usri1_name);
|
||||||
|
|
||||||
if(lstrlenW(ui->usri1_password) > PWLEN)
|
/* Create the user account */
|
||||||
|
Status = SamCreateUser2InDomain(DomainHandle,
|
||||||
|
&UserName,
|
||||||
|
USER_NORMAL_ACCOUNT,
|
||||||
|
USER_ALL_ACCESS | DELETE | WRITE_DAC,
|
||||||
|
&UserHandle,
|
||||||
|
&GrantedAccess,
|
||||||
|
&RelativeId);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Always return PasswordTooShort on invalid passwords. */
|
ERR("SamCreateUser2InDomain failed (Status %08lx)\n", Status);
|
||||||
status = NERR_PasswordTooShort;
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
break;
|
goto done;
|
||||||
}
|
|
||||||
lstrcpyW(su->user_password, ui->usri1_password);
|
|
||||||
|
|
||||||
su->sec_since_passwd_change = ui->usri1_password_age;
|
|
||||||
su->user_priv = ui->usri1_priv;
|
|
||||||
su->user_flags = ui->usri1_flags;
|
|
||||||
|
|
||||||
/*FIXME: set the other LPWSTRs to NULL for now */
|
|
||||||
su->home_dir = NULL;
|
|
||||||
su->user_comment = NULL;
|
|
||||||
su->user_logon_script_path = NULL;
|
|
||||||
|
|
||||||
list_add_head(&user_list, &su->entry);
|
|
||||||
return NERR_Success;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
TRACE("Invalid level %d specified.\n", level);
|
|
||||||
status = ERROR_INVALID_LEVEL;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, su);
|
/* Set user information */
|
||||||
|
ApiStatus = SetUserInfo(UserHandle,
|
||||||
|
bufptr,
|
||||||
|
level);
|
||||||
|
if (ApiStatus != NERR_Success)
|
||||||
|
{
|
||||||
|
ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
done:
|
||||||
|
if (UserHandle != NULL)
|
||||||
|
SamCloseHandle(UserHandle);
|
||||||
|
|
||||||
|
if (DomainHandle != NULL)
|
||||||
|
SamCloseHandle(DomainHandle);
|
||||||
|
|
||||||
|
if (ServerHandle != NULL)
|
||||||
|
SamCloseHandle(ServerHandle);
|
||||||
|
|
||||||
|
return ApiStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -599,7 +741,7 @@ NetUserEnum(LPCWSTR servername,
|
||||||
|
|
||||||
EnumContext->EnumerationContext = 0;
|
EnumContext->EnumerationContext = 0;
|
||||||
EnumContext->Buffer = NULL;
|
EnumContext->Buffer = NULL;
|
||||||
EnumContext->Returned = 0;
|
EnumContext->Count = 0;
|
||||||
EnumContext->Index = 0;
|
EnumContext->Index = 0;
|
||||||
EnumContext->BuiltinDone = FALSE;
|
EnumContext->BuiltinDone = FALSE;
|
||||||
|
|
||||||
|
@ -639,9 +781,9 @@ NetUserEnum(LPCWSTR servername,
|
||||||
// while (TRUE)
|
// while (TRUE)
|
||||||
// {
|
// {
|
||||||
TRACE("EnumContext->Index: %lu\n", EnumContext->Index);
|
TRACE("EnumContext->Index: %lu\n", EnumContext->Index);
|
||||||
TRACE("EnumContext->Returned: %lu\n", EnumContext->Returned);
|
TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
|
||||||
|
|
||||||
if (EnumContext->Index >= EnumContext->Returned)
|
if (EnumContext->Index >= EnumContext->Count)
|
||||||
{
|
{
|
||||||
// if (EnumContext->BuiltinDone == TRUE)
|
// if (EnumContext->BuiltinDone == TRUE)
|
||||||
// {
|
// {
|
||||||
|
@ -655,7 +797,7 @@ NetUserEnum(LPCWSTR servername,
|
||||||
0,
|
0,
|
||||||
(PVOID *)&EnumContext->Buffer,
|
(PVOID *)&EnumContext->Buffer,
|
||||||
prefmaxlen,
|
prefmaxlen,
|
||||||
&EnumContext->Returned);
|
&EnumContext->Count);
|
||||||
|
|
||||||
TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status);
|
TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -677,7 +819,7 @@ NetUserEnum(LPCWSTR servername,
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("EnumContext: %lu\n", EnumContext);
|
TRACE("EnumContext: %lu\n", EnumContext);
|
||||||
TRACE("EnumContext->Returned: %lu\n", EnumContext->Returned);
|
TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
|
||||||
TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
|
TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
|
||||||
|
|
||||||
/* Get a pointer to the current user */
|
/* Get a pointer to the current user */
|
||||||
|
@ -731,11 +873,11 @@ NetUserEnum(LPCWSTR servername,
|
||||||
// }
|
// }
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (ApiStatus == NERR_Success && EnumContext->Index < EnumContext->Returned)
|
if (ApiStatus == NERR_Success && EnumContext->Index < EnumContext->Count)
|
||||||
ApiStatus = ERROR_MORE_DATA;
|
ApiStatus = ERROR_MORE_DATA;
|
||||||
|
|
||||||
if (EnumContext != NULL)
|
if (EnumContext != NULL)
|
||||||
*totalentries = EnumContext->Returned;
|
*totalentries = EnumContext->Count;
|
||||||
|
|
||||||
if (resume_handle == NULL || ApiStatus != ERROR_MORE_DATA)
|
if (resume_handle == NULL || ApiStatus != ERROR_MORE_DATA)
|
||||||
{
|
{
|
||||||
|
@ -752,7 +894,7 @@ done:
|
||||||
|
|
||||||
if (EnumContext->Buffer != NULL)
|
if (EnumContext->Buffer != NULL)
|
||||||
{
|
{
|
||||||
for (i = 0; i < EnumContext->Returned; i++)
|
for (i = 0; i < EnumContext->Count; i++)
|
||||||
{
|
{
|
||||||
SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
|
SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue