Author: ekohl Date: Wed Dec 26 16:31:28 2012 New Revision: 58015
URL: http://svn.reactos.org/svn/reactos?rev=58015&view=rev Log: [NETAPI32] - Implement NetLocalGroupAdd. - Implement and use a helper function that opens aliases by name.
Modified: trunk/reactos/dll/win32/netapi32/local_group.c
Modified: trunk/reactos/dll/win32/netapi32/local_group.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/netapi32/local_gr... ============================================================================== --- trunk/reactos/dll/win32/netapi32/local_group.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/netapi32/local_group.c [iso-8859-1] Wed Dec 26 16:31:28 2012 @@ -160,19 +160,241 @@ }
-/************************************************************ - * NetLocalGroupAdd (NETAPI32.@) - */ -NET_API_STATUS WINAPI NetLocalGroupAdd( +static +NET_API_STATUS +OpenAliasByName(SAM_HANDLE DomainHandle, + PUNICODE_STRING AliasName, + ULONG DesiredAccess, + PSAM_HANDLE AliasHandle) +{ + PULONG RelativeIds = NULL; + PSID_NAME_USE Use = NULL; + NET_API_STATUS ApiStatus = NERR_Success; + NTSTATUS Status = STATUS_SUCCESS; + + /* Get the RID for the given user name */ + Status = SamLookupNamesInDomain(DomainHandle, + 1, + AliasName, + &RelativeIds, + &Use); + if (!NT_SUCCESS(Status)) + { + ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status); + return NetpNtStatusToApiStatus(Status); + } + + /* Fail, if it is not an alias account */ + if (Use[0] != SidTypeAlias) + { + ERR("Object is not an Alias!\n"); + ApiStatus = NERR_GroupNotFound; + goto done; + } + + /* Open the alias account */ + Status = SamOpenAlias(DomainHandle, + DesiredAccess, + RelativeIds[0], + AliasHandle); + if (!NT_SUCCESS(Status)) + { + ERR("SamOpenDomain failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; + } + +done: + if (RelativeIds != NULL) + SamFreeMemory(RelativeIds); + + if (Use != NULL) + SamFreeMemory(Use); + + return ApiStatus; +} + + +/************************************************************ + * NetLocalGroupAdd (NETAPI32.@) + */ +NET_API_STATUS +WINAPI +NetLocalGroupAdd( LPCWSTR servername, DWORD level, LPBYTE buf, LPDWORD parm_err) { - FIXME("(%s %d %p %p) stub!\n", debugstr_w(servername), level, buf, + ALIAS_ADM_COMMENT_INFORMATION AdminComment; + UNICODE_STRING ServerName; + UNICODE_STRING AliasName; + SAM_HANDLE ServerHandle = NULL; + SAM_HANDLE DomainHandle = NULL; + SAM_HANDLE AliasHandle = NULL; + PSID DomainSid = NULL; + LPWSTR aliasname = NULL; + LPWSTR aliascomment = NULL; + ULONG RelativeId; + NET_API_STATUS ApiStatus = NERR_Success; + NTSTATUS Status = STATUS_SUCCESS; + + TRACE("(%s %d %p %p) stub!\n", debugstr_w(servername), level, buf, parm_err); - return NERR_Success; -} + + /* Initialize the Server name*/ + if (servername != NULL) + RtlInitUnicodeString(&ServerName, servername); + + /* Initialize the Alias name*/ + switch (level) + { + case 0: + aliasname = ((PLOCALGROUP_INFO_0)buf)->lgrpi0_name; + aliascomment = NULL; + break; + + case 1: + aliasname = ((PLOCALGROUP_INFO_1)buf)->lgrpi1_name; + aliascomment = ((PLOCALGROUP_INFO_1)buf)->lgrpi1_comment; + break; + + default: + return ERROR_INVALID_LEVEL; + } + + RtlInitUnicodeString(&AliasName, aliasname); + + /* 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; + } + + /* Get the Builtin Domain SID */ + Status = GetBuiltinDomainSid(&DomainSid); + if (!NT_SUCCESS(Status)) + { + ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; + } + + /* Open the Builtin Domain */ + Status = SamOpenDomain(ServerHandle, + DOMAIN_LOOKUP, + DomainSid, + &DomainHandle); + if (!NT_SUCCESS(Status)) + { + ERR("SamOpenDomain failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; + } + + /* Try to open the Alias Account in the Builtin Domain */ + ApiStatus = OpenAliasByName(DomainHandle, + &AliasName, + ALIAS_READ_INFORMATION, + &AliasHandle); + if (ApiStatus == NERR_Success) + { + ERR("OpenAliasByName: alias %wZ already exists!\n", &AliasName); + + SamCloseHandle(AliasHandle); + ApiStatus = ERROR_ALIAS_EXISTS; + goto done; + } + + ApiStatus = NERR_Success; + + /* Free the Builtin Domain SID */ + RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid); + DomainSid = NULL; + + /* Close the Builtin Domain */ + SamCloseHandle(DomainHandle); + DomainHandle = NULL; + + /* Get the account domain SID */ + Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, + &DomainSid); + if (!NT_SUCCESS(Status)) + { + ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; + } + + /* Open the account domain */ + Status = SamOpenDomain(ServerHandle, + DOMAIN_CREATE_ALIAS | DOMAIN_LOOKUP, + DomainSid, + &DomainHandle); + if (!NT_SUCCESS(Status)) + { + ERR("SamOpenDomain failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; + } + + /* Create the alias */ + Status = SamCreateAliasInDomain(DomainHandle, + &AliasName, + DELETE | ALIAS_WRITE_ACCOUNT, + &AliasHandle, + &RelativeId); + if (!NT_SUCCESS(Status)) + { + ERR("SamCreateAliasInDomain failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; + } + + TRACE("Created alias "%wZ" (RID: %lu)\n", &AliasName, RelativeId); + + /* Set the admin comment */ + if (level == 1) + { + RtlInitUnicodeString(&AdminComment.AdminComment, aliascomment); + + Status = SamSetInformationAlias(AliasHandle, + AliasAdminCommentInformation, + &AdminComment); + if (!NT_SUCCESS(Status)) + { + ERR("SamSetInformationAlias failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + + /* Delete the Alias if the Comment could not be set */ + SamDeleteAlias(AliasHandle); + + goto done; + } + } + +done: + if (AliasHandle != NULL) + SamCloseHandle(AliasHandle); + + if (DomainSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid); + + if (DomainHandle != NULL) + SamCloseHandle(DomainHandle); + + if (ServerHandle != NULL) + SamCloseHandle(ServerHandle); + + return ApiStatus; +} +
/************************************************************ * NetLocalGroupAddMember (NETAPI32.@) @@ -264,7 +486,7 @@ NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS;
- FIXME("(%s %d %p %d %p %p %p) stub!\n", debugstr_w(servername), + TRACE("(%s %d %p %d %p %p %p) stub!\n", debugstr_w(servername), level, bufptr, prefmaxlen, entriesread, totalentries, resumehandle);
*entriesread = 0; @@ -511,14 +733,12 @@ SAM_HANDLE DomainHandle = NULL; SAM_HANDLE AliasHandle = NULL; PSID DomainSid = NULL; - PULONG RelativeIds = NULL; - PSID_NAME_USE Use = NULL; PALIAS_GENERAL_INFORMATION AliasInfo = NULL; LPVOID Buffer = NULL; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS;
- FIXME("(%s %s %d %p) stub!\n", debugstr_w(servername), + TRACE("(%s %s %d %p) stub!\n", debugstr_w(servername), debugstr_w(groupname), level, bufptr);
if (servername != NULL) @@ -559,49 +779,24 @@ goto done; }
- /* Get the RID for the given user name */ - Status = SamLookupNamesInDomain(DomainHandle, - 1, - &GroupName, - &RelativeIds, - &Use); - if (!NT_SUCCESS(Status) && Status != STATUS_NONE_MAPPED) - { - ERR("SamOpenDomain failed (Status %08lx)\n", Status); - ApiStatus = NetpNtStatusToApiStatus(Status); - goto done; - } - - if (Status == STATUS_SUCCESS) - { - /* FIXME: Check Use*/ - - Status = SamOpenAlias(DomainHandle, - ALIAS_READ_INFORMATION, - RelativeIds[0], - &AliasHandle); - if (!NT_SUCCESS(Status)) - { - ERR("SamOpenDomain failed (Status %08lx)\n", Status); - ApiStatus = NetpNtStatusToApiStatus(Status); - goto done; - } + /* Open the alias account in the builtin domain */ + ApiStatus = OpenAliasByName(DomainHandle, + &GroupName, + ALIAS_READ_INFORMATION, + &AliasHandle); + if (ApiStatus != NERR_Success) + { + ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus); + goto done; }
if (AliasHandle == NULL) { - if (RelativeIds != NULL) - SamFreeMemory(RelativeIds); - - if (Use != NULL) - SamFreeMemory(Use); - if (DomainSid != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
if (DomainHandle != NULL) SamCloseHandle(DomainHandle); -
/* Get the Account Domain SID */ Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, @@ -625,29 +820,14 @@ goto done; }
- /* Get the RID for the given user name */ - Status = SamLookupNamesInDomain(DomainHandle, - 1, - &GroupName, - &RelativeIds, - &Use); - if (!NT_SUCCESS(Status)) - { - ERR("SamOpenDomain failed (Status %08lx)\n", Status); - ApiStatus = NetpNtStatusToApiStatus(Status); - goto done; - } - - /* FIXME: Check Use*/ - - Status = SamOpenAlias(DomainHandle, - ALIAS_READ_INFORMATION, - RelativeIds[0], - &AliasHandle); - if (!NT_SUCCESS(Status)) - { - ERR("SamOpenDomain failed (Status %08lx)\n", Status); - ApiStatus = NetpNtStatusToApiStatus(Status); + /* Open the alias account in the account domain */ + ApiStatus = OpenAliasByName(DomainHandle, + &GroupName, + ALIAS_READ_INFORMATION, + &AliasHandle); + if (ApiStatus != NERR_Success) + { + ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus); goto done; } } @@ -675,12 +855,6 @@ if (AliasHandle != NULL) SamCloseHandle(AliasHandle);
- if (RelativeIds != NULL) - SamFreeMemory(RelativeIds); - - if (Use != NULL) - SamFreeMemory(Use); - if (DomainSid != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
@@ -692,7 +866,7 @@
*bufptr = (LPBYTE)Buffer;
- return NERR_Success; + return ApiStatus; }