mirror of
https://github.com/reactos/reactos.git
synced 2025-07-23 02:53:38 +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;
|
||||
PSAM_RID_ENUMERATION Buffer;
|
||||
ULONG Returned;
|
||||
ULONG Count;
|
||||
ULONG Index;
|
||||
BOOLEAN BuiltinDone;
|
||||
|
||||
|
@ -246,7 +246,7 @@ BuildUserInfoBuffer(PUSER_ACCOUNT_INFORMATION UserInfo,
|
|||
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 @@ BuildUserInfoBuffer(PUSER_ACCOUNT_INFORMATION UserInfo,
|
|||
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;
|
||||
|
||||
|
@ -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.@)
|
||||
*/
|
||||
|
@ -409,72 +534,89 @@ NetUserAdd(LPCWSTR servername,
|
|||
LPBYTE bufptr,
|
||||
LPDWORD parm_err)
|
||||
{
|
||||
NET_API_STATUS status;
|
||||
struct sam_user * su = NULL;
|
||||
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) 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)
|
||||
return status;
|
||||
/* Check the info level */
|
||||
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 */
|
||||
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;
|
||||
ERR("SamConnect failed (Status %08lx)\n", Status);
|
||||
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, su);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
return status;
|
||||
/* 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 @@ NetUserEnum(LPCWSTR servername,
|
|||
|
||||
EnumContext->EnumerationContext = 0;
|
||||
EnumContext->Buffer = NULL;
|
||||
EnumContext->Returned = 0;
|
||||
EnumContext->Count = 0;
|
||||
EnumContext->Index = 0;
|
||||
EnumContext->BuiltinDone = FALSE;
|
||||
|
||||
|
@ -639,9 +781,9 @@ NetUserEnum(LPCWSTR servername,
|
|||
// while (TRUE)
|
||||
// {
|
||||
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)
|
||||
// {
|
||||
|
@ -655,7 +797,7 @@ NetUserEnum(LPCWSTR servername,
|
|||
0,
|
||||
(PVOID *)&EnumContext->Buffer,
|
||||
prefmaxlen,
|
||||
&EnumContext->Returned);
|
||||
&EnumContext->Count);
|
||||
|
||||
TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -677,7 +819,7 @@ NetUserEnum(LPCWSTR servername,
|
|||
}
|
||||
|
||||
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 @@ NetUserEnum(LPCWSTR servername,
|
|||
// }
|
||||
|
||||
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 @@ done:
|
|||
|
||||
if (EnumContext->Buffer != NULL)
|
||||
{
|
||||
for (i = 0; i < EnumContext->Returned; i++)
|
||||
for (i = 0; i < EnumContext->Count; i++)
|
||||
{
|
||||
SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue