Author: ekohl
Date: Mon Dec 31 18:39:19 2012
New Revision: 58071
URL:
http://svn.reactos.org/svn/reactos?rev=58071&view=rev
Log:
[NETAPI32]
Implement parts of NetUserAdd.
Modified:
trunk/reactos/dll/win32/netapi32/user.c
Modified: trunk/reactos/dll/win32/netapi32/user.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/netapi32/user.c?…
==============================================================================
--- trunk/reactos/dll/win32/netapi32/user.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/netapi32/user.c [iso-8859-1] Mon Dec 31 18:39:19 2012
@@ -31,7 +31,7 @@
SAM_ENUMERATE_HANDLE EnumerationContext;
PSAM_RID_ENUMERATION Buffer;
- ULONG Returned;
+ ULONG Count;
ULONG Index;
BOOLEAN BuiltinDone;
@@ -246,7 +246,7 @@
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)
{
@@ -342,7 +342,7 @@
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;
break;
@@ -396,6 +396,131 @@
SamFreeMemory(UserInfo->LogonHours.LogonHours);
SamFreeMemory(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;
}
@@ -409,72 +534,89 @@
LPBYTE bufptr,
LPDWORD parm_err)
{
- NET_API_STATUS status;
- struct sam_user * su = NULL;
-
- FIXME("(%s, %d, %p, %p) stub!\n", debugstr_w(servername), level, bufptr,
parm_err);
-
- if((status = NETAPI_ValidateServername(servername)) != NERR_Success)
- return status;
-
- switch(level)
- {
- /* Level 3 and 4 are identical for the purposes of NetUserAdd */
- case 4:
- case 3:
- 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)
- {
- status = NERR_BadUsername;
- break;
- }
-
- /*FIXME: do other checks for a valid username */
- lstrcpyW(su->user_name, ui->usri1_name);
-
- if(lstrlenW(ui->usri1_password) > PWLEN)
- {
- /* Always return PasswordTooShort on invalid passwords. */
- status = NERR_PasswordTooShort;
- break;
- }
- 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);
-
- return status;
+ UNICODE_STRING ServerName;
+ 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)\n", debugstr_w(servername), level, bufptr,
parm_err);
+
+ /* Check the info level */
+ if (level < 1 || level > 4)
+ return ERROR_INVALID_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))
+ {
+ ERR("SamConnect failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* Open the Account Domain */
+ Status = OpenAccountDomain(ServerHandle,
+ (servername != NULL) ? &ServerName : NULL,
+ DOMAIN_CREATE_USER | DOMAIN_LOOKUP,
+ &DomainHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* Initialize the user name string */
+ RtlInitUnicodeString(&UserName,
+ ((PUSER_INFO_1)bufptr)->usri1_name);
+
+ /* Create the user account */
+ Status = SamCreateUser2InDomain(DomainHandle,
+ &UserName,
+ USER_NORMAL_ACCOUNT,
+ USER_ALL_ACCESS | DELETE | WRITE_DAC,
+ &UserHandle,
+ &GrantedAccess,
+ &RelativeId);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamCreateUser2InDomain failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* Set user information */
+ ApiStatus = SetUserInfo(UserHandle,
+ bufptr,
+ level);
+ if (ApiStatus != NERR_Success)
+ {
+ ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);
+ goto done;
+ }
+
+done:
+ if (UserHandle != NULL)
+ SamCloseHandle(UserHandle);
+
+ if (DomainHandle != NULL)
+ SamCloseHandle(DomainHandle);
+
+ if (ServerHandle != NULL)
+ SamCloseHandle(ServerHandle);
+
+ return ApiStatus;
}
@@ -599,7 +741,7 @@
EnumContext->EnumerationContext = 0;
EnumContext->Buffer = NULL;
- EnumContext->Returned = 0;
+ EnumContext->Count = 0;
EnumContext->Index = 0;
EnumContext->BuiltinDone = FALSE;
@@ -639,9 +781,9 @@
// while (TRUE)
// {
TRACE("EnumContext->Index: %lu\n", EnumContext->Index);
- TRACE("EnumContext->Returned: %lu\n", EnumContext->Returned);
-
- if (EnumContext->Index >= EnumContext->Returned)
+ TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
+
+ if (EnumContext->Index >= EnumContext->Count)
{
// if (EnumContext->BuiltinDone == TRUE)
// {
@@ -655,7 +797,7 @@
0,
(PVOID *)&EnumContext->Buffer,
prefmaxlen,
- &EnumContext->Returned);
+ &EnumContext->Count);
TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n",
Status);
if (!NT_SUCCESS(Status))
@@ -677,7 +819,7 @@
}
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);
/* Get a pointer to the current user */
@@ -731,11 +873,11 @@
// }
done:
- if (ApiStatus == NERR_Success && EnumContext->Index <
EnumContext->Returned)
+ if (ApiStatus == NERR_Success && EnumContext->Index <
EnumContext->Count)
ApiStatus = ERROR_MORE_DATA;
if (EnumContext != NULL)
- *totalentries = EnumContext->Returned;
+ *totalentries = EnumContext->Count;
if (resume_handle == NULL || ApiStatus != ERROR_MORE_DATA)
{
@@ -752,7 +894,7 @@
if (EnumContext->Buffer != NULL)
{
- for (i = 0; i < EnumContext->Returned; i++)
+ for (i = 0; i < EnumContext->Count; i++)
{
SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
}