2 * Copyright 2006 Robert Reif
4 * netapi32 local group functions
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 WINE_DEFAULT_DEBUG_CHANNEL(netapi32
);
25 typedef enum _ENUM_PHASE
32 typedef struct _ENUM_CONTEXT
34 SAM_HANDLE ServerHandle
;
35 SAM_HANDLE DomainHandle
;
36 SAM_HANDLE BuiltinDomainHandle
;
37 SAM_HANDLE AccountDomainHandle
;
39 SAM_ENUMERATE_HANDLE EnumerationContext
;
40 PSAM_RID_ENUMERATION Buffer
;
45 } ENUM_CONTEXT
, *PENUM_CONTEXT
;
47 typedef struct _MEMBER_ENUM_CONTEXT
49 SAM_HANDLE ServerHandle
;
50 SAM_HANDLE DomainHandle
;
51 SAM_HANDLE AliasHandle
;
56 PLSA_REFERENCED_DOMAIN_LIST Domains
;
57 PLSA_TRANSLATED_NAME Names
;
59 } MEMBER_ENUM_CONTEXT
, *PMEMBER_ENUM_CONTEXT
;
64 BuildAliasInfoBuffer(PALIAS_GENERAL_INFORMATION AliasInfo
,
68 LPVOID LocalBuffer
= NULL
;
69 PLOCALGROUP_INFO_0 LocalInfo0
;
70 PLOCALGROUP_INFO_1 LocalInfo1
;
73 NET_API_STATUS ApiStatus
= NERR_Success
;
80 Size
= sizeof(LOCALGROUP_INFO_0
) +
81 AliasInfo
->Name
.Length
+ sizeof(WCHAR
);
85 Size
= sizeof(LOCALGROUP_INFO_1
) +
86 AliasInfo
->Name
.Length
+ sizeof(WCHAR
) +
87 AliasInfo
->AdminComment
.Length
+ sizeof(WCHAR
);
91 ApiStatus
= ERROR_INVALID_LEVEL
;
95 ApiStatus
= NetApiBufferAllocate(Size
, &LocalBuffer
);
96 if (ApiStatus
!= NERR_Success
)
99 ZeroMemory(LocalBuffer
, Size
);
104 LocalInfo0
= (PLOCALGROUP_INFO_0
)LocalBuffer
;
106 Ptr
= (LPWSTR
)((ULONG_PTR
)LocalInfo0
+ sizeof(LOCALGROUP_INFO_0
));
107 LocalInfo0
->lgrpi0_name
= Ptr
;
109 memcpy(LocalInfo0
->lgrpi0_name
,
110 AliasInfo
->Name
.Buffer
,
111 AliasInfo
->Name
.Length
);
112 LocalInfo0
->lgrpi0_name
[AliasInfo
->Name
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
116 LocalInfo1
= (PLOCALGROUP_INFO_1
)LocalBuffer
;
118 Ptr
= (LPWSTR
)((ULONG_PTR
)LocalInfo1
+ sizeof(LOCALGROUP_INFO_1
));
119 LocalInfo1
->lgrpi1_name
= Ptr
;
121 memcpy(LocalInfo1
->lgrpi1_name
,
122 AliasInfo
->Name
.Buffer
,
123 AliasInfo
->Name
.Length
);
124 LocalInfo1
->lgrpi1_name
[AliasInfo
->Name
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
126 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ AliasInfo
->Name
.Length
+ sizeof(WCHAR
));
127 LocalInfo1
->lgrpi1_comment
= Ptr
;
129 memcpy(LocalInfo1
->lgrpi1_comment
,
130 AliasInfo
->AdminComment
.Buffer
,
131 AliasInfo
->AdminComment
.Length
);
132 LocalInfo1
->lgrpi1_comment
[AliasInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
137 if (ApiStatus
== NERR_Success
)
139 *Buffer
= LocalBuffer
;
143 if (LocalBuffer
!= NULL
)
144 NetApiBufferFree(LocalBuffer
);
153 FreeAliasInfo(PALIAS_GENERAL_INFORMATION AliasInfo
)
155 if (AliasInfo
->Name
.Buffer
!= NULL
)
156 SamFreeMemory(AliasInfo
->Name
.Buffer
);
158 if (AliasInfo
->AdminComment
.Buffer
!= NULL
)
159 SamFreeMemory(AliasInfo
->AdminComment
.Buffer
);
161 SamFreeMemory(AliasInfo
);
167 OpenAliasByName(SAM_HANDLE DomainHandle
,
168 PUNICODE_STRING AliasName
,
170 PSAM_HANDLE AliasHandle
)
172 PULONG RelativeIds
= NULL
;
173 PSID_NAME_USE Use
= NULL
;
174 NET_API_STATUS ApiStatus
= NERR_Success
;
175 NTSTATUS Status
= STATUS_SUCCESS
;
177 /* Get the RID for the given user name */
178 Status
= SamLookupNamesInDomain(DomainHandle
,
183 if (!NT_SUCCESS(Status
))
185 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status
);
186 return NetpNtStatusToApiStatus(Status
);
189 /* Fail, if it is not an alias account */
190 if (Use
[0] != SidTypeAlias
)
192 ERR("Object is not an Alias!\n");
193 ApiStatus
= NERR_GroupNotFound
;
197 /* Open the alias account */
198 Status
= SamOpenAlias(DomainHandle
,
202 if (!NT_SUCCESS(Status
))
204 ERR("SamOpenDomain failed (Status %08lx)\n", Status
);
205 ApiStatus
= NetpNtStatusToApiStatus(Status
);
210 if (RelativeIds
!= NULL
)
211 SamFreeMemory(RelativeIds
);
222 BuildSidListFromDomainAndName(IN PUNICODE_STRING ServerName
,
223 IN PLOCALGROUP_MEMBERS_INFO_3 buf
,
225 OUT PLOCALGROUP_MEMBERS_INFO_0
*MemberList
)
227 OBJECT_ATTRIBUTES ObjectAttributes
;
228 LSA_HANDLE LsaHandle
= NULL
;
229 PUNICODE_STRING NamesArray
= NULL
;
231 PLSA_REFERENCED_DOMAIN_LIST Domains
= NULL
;
232 PLSA_TRANSLATED_SID Sids
= NULL
;
233 PLOCALGROUP_MEMBERS_INFO_0 MemberBuffer
= NULL
;
234 NET_API_STATUS ApiStatus
= NERR_Success
;
235 NTSTATUS Status
= STATUS_SUCCESS
;
237 ApiStatus
= NetApiBufferAllocate(sizeof(UNICODE_STRING
) * EntryCount
,
238 (LPVOID
*)&NamesArray
);
239 if (ApiStatus
!= NERR_Success
)
244 for (i
= 0; i
< EntryCount
; i
++)
246 RtlInitUnicodeString(&NamesArray
[i
],
247 buf
[i
].lgrmi3_domainandname
);
250 InitializeObjectAttributes(&ObjectAttributes
,
256 Status
= LsaOpenPolicy(ServerName
,
257 (PLSA_OBJECT_ATTRIBUTES
)&ObjectAttributes
,
260 if (!NT_SUCCESS(Status
))
262 ApiStatus
= NetpNtStatusToApiStatus(Status
);
266 Status
= LsaLookupNames(LsaHandle
,
271 if (!NT_SUCCESS(Status
))
273 ApiStatus
= NetpNtStatusToApiStatus(Status
);
277 ApiStatus
= NetApiBufferAllocate(sizeof(LOCALGROUP_MEMBERS_INFO_0
) * EntryCount
,
278 (LPVOID
*)&MemberBuffer
);
279 if (ApiStatus
!= NERR_Success
)
284 for (i
= 0; i
< EntryCount
; i
++)
286 ApiStatus
= BuildSidFromSidAndRid(Domains
->Domains
[Sids
[i
].DomainIndex
].Sid
,
288 &MemberBuffer
[i
].lgrmi0_sid
);
289 if (ApiStatus
!= NERR_Success
)
296 if (ApiStatus
!= NERR_Success
)
298 if (MemberBuffer
!= NULL
)
300 for (i
= 0; i
< EntryCount
; i
++)
302 if (MemberBuffer
[i
].lgrmi0_sid
!= NULL
)
303 NetApiBufferFree(MemberBuffer
[i
].lgrmi0_sid
);
306 NetApiBufferFree(MemberBuffer
);
315 LsaFreeMemory(Domains
);
317 if (LsaHandle
!= NULL
)
320 if (NamesArray
!= NULL
)
321 NetApiBufferFree(NamesArray
);
323 *MemberList
= MemberBuffer
;
329 /************************************************************
330 * NetLocalGroupAdd (NETAPI32.@)
340 ALIAS_ADM_COMMENT_INFORMATION AdminComment
;
341 UNICODE_STRING ServerName
;
342 UNICODE_STRING AliasName
;
343 SAM_HANDLE ServerHandle
= NULL
;
344 SAM_HANDLE DomainHandle
= NULL
;
345 SAM_HANDLE AliasHandle
= NULL
;
346 LPWSTR aliasname
= NULL
;
347 LPWSTR aliascomment
= NULL
;
349 NET_API_STATUS ApiStatus
= NERR_Success
;
350 NTSTATUS Status
= STATUS_SUCCESS
;
352 TRACE("(%s %d %p %p) stub!\n", debugstr_w(servername
), level
, buf
,
355 /* Initialize the Server name*/
356 if (servername
!= NULL
)
357 RtlInitUnicodeString(&ServerName
, servername
);
359 /* Initialize the Alias name*/
363 aliasname
= ((PLOCALGROUP_INFO_0
)buf
)->lgrpi0_name
;
368 aliasname
= ((PLOCALGROUP_INFO_1
)buf
)->lgrpi1_name
;
369 aliascomment
= ((PLOCALGROUP_INFO_1
)buf
)->lgrpi1_comment
;
373 return ERROR_INVALID_LEVEL
;
376 RtlInitUnicodeString(&AliasName
, aliasname
);
378 /* Connect to the SAM Server */
379 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
381 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
383 if (!NT_SUCCESS(Status
))
385 ERR("SamConnect failed (Status %08lx)\n", Status
);
386 ApiStatus
= NetpNtStatusToApiStatus(Status
);
390 /* Open the Builtin Domain */
391 Status
= OpenBuiltinDomain(ServerHandle
,
394 if (!NT_SUCCESS(Status
))
396 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
397 ApiStatus
= NetpNtStatusToApiStatus(Status
);
401 /* Try to open the Alias Account in the Builtin Domain */
402 ApiStatus
= OpenAliasByName(DomainHandle
,
404 ALIAS_READ_INFORMATION
,
406 if (ApiStatus
== NERR_Success
)
408 ERR("OpenAliasByName: alias %wZ already exists!\n", &AliasName
);
410 SamCloseHandle(AliasHandle
);
411 ApiStatus
= ERROR_ALIAS_EXISTS
;
415 ApiStatus
= NERR_Success
;
417 /* Close the Builtin Domain */
418 SamCloseHandle(DomainHandle
);
421 /* Open the account domain */
422 Status
= OpenAccountDomain(ServerHandle
,
423 (servername
!= NULL
) ? &ServerName
: NULL
,
424 DOMAIN_CREATE_ALIAS
| DOMAIN_LOOKUP
,
426 if (!NT_SUCCESS(Status
))
428 ERR("SamOpenDomain failed (Status %08lx)\n", Status
);
429 ApiStatus
= NetpNtStatusToApiStatus(Status
);
433 /* Create the alias */
434 Status
= SamCreateAliasInDomain(DomainHandle
,
436 DELETE
| ALIAS_WRITE_ACCOUNT
,
439 if (!NT_SUCCESS(Status
))
441 ERR("SamCreateAliasInDomain failed (Status %08lx)\n", Status
);
442 ApiStatus
= NetpNtStatusToApiStatus(Status
);
446 TRACE("Created alias \"%wZ\" (RID: %lu)\n", &AliasName
, RelativeId
);
448 /* Set the admin comment */
451 RtlInitUnicodeString(&AdminComment
.AdminComment
, aliascomment
);
453 Status
= SamSetInformationAlias(AliasHandle
,
454 AliasAdminCommentInformation
,
456 if (!NT_SUCCESS(Status
))
458 ERR("SamSetInformationAlias failed (Status %08lx)\n", Status
);
459 ApiStatus
= NetpNtStatusToApiStatus(Status
);
461 /* Delete the Alias if the Comment could not be set */
462 SamDeleteAlias(AliasHandle
);
469 if (AliasHandle
!= NULL
)
471 if (ApiStatus
!= NERR_Success
)
472 SamDeleteAlias(AliasHandle
);
474 SamCloseHandle(AliasHandle
);
477 if (DomainHandle
!= NULL
)
478 SamCloseHandle(DomainHandle
);
480 if (ServerHandle
!= NULL
)
481 SamCloseHandle(ServerHandle
);
487 /************************************************************
488 * NetLocalGroupAddMember (NETAPI32.@)
492 NetLocalGroupAddMember(
497 LOCALGROUP_MEMBERS_INFO_0 Member
;
499 TRACE("(%s %s %p)\n", debugstr_w(servername
),
500 debugstr_w(groupname
), membersid
);
502 Member
.lgrmi0_sid
= membersid
;
504 return NetLocalGroupAddMembers(servername
,
512 /************************************************************
513 * NetLocalGroupAddMembers (NETAPI32.@)
517 NetLocalGroupAddMembers(
524 UNICODE_STRING ServerName
;
525 UNICODE_STRING AliasName
;
526 SAM_HANDLE ServerHandle
= NULL
;
527 SAM_HANDLE DomainHandle
= NULL
;
528 SAM_HANDLE AliasHandle
= NULL
;
529 PLOCALGROUP_MEMBERS_INFO_0 MemberList
= NULL
;
531 NET_API_STATUS ApiStatus
= NERR_Success
;
532 NTSTATUS Status
= STATUS_SUCCESS
;
534 TRACE("(%s %s %d %p %d)\n", debugstr_w(servername
),
535 debugstr_w(groupname
), level
, buf
, totalentries
);
537 if (servername
!= NULL
)
538 RtlInitUnicodeString(&ServerName
, servername
);
540 RtlInitUnicodeString(&AliasName
, groupname
);
545 MemberList
= (PLOCALGROUP_MEMBERS_INFO_0
)buf
;
549 Status
= BuildSidListFromDomainAndName((servername
!= NULL
) ? &ServerName
: NULL
,
550 (PLOCALGROUP_MEMBERS_INFO_3
)buf
,
553 if (!NT_SUCCESS(Status
))
555 ERR("BuildSidListFromDomainAndName failed (Status %08lx)\n", Status
);
556 ApiStatus
= NetpNtStatusToApiStatus(Status
);
562 ApiStatus
= ERROR_INVALID_LEVEL
;
566 /* Connect to the SAM Server */
567 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
569 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
571 if (!NT_SUCCESS(Status
))
573 ERR("SamConnect failed (Status %08lx)\n", Status
);
574 ApiStatus
= NetpNtStatusToApiStatus(Status
);
578 /* Open the Builtin Domain */
579 Status
= OpenBuiltinDomain(ServerHandle
,
582 if (!NT_SUCCESS(Status
))
584 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
585 ApiStatus
= NetpNtStatusToApiStatus(Status
);
589 /* Open the alias account in the builtin domain */
590 ApiStatus
= OpenAliasByName(DomainHandle
,
594 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
596 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
600 if (AliasHandle
== NULL
)
602 if (DomainHandle
!= NULL
)
603 SamCloseHandle(DomainHandle
);
605 /* Open the Acount Domain */
606 Status
= OpenAccountDomain(ServerHandle
,
607 (servername
!= NULL
) ? &ServerName
: NULL
,
610 if (!NT_SUCCESS(Status
))
612 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
613 ApiStatus
= NetpNtStatusToApiStatus(Status
);
617 /* Open the alias account in the account domain */
618 ApiStatus
= OpenAliasByName(DomainHandle
,
622 if (ApiStatus
!= NERR_Success
)
624 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
625 if (ApiStatus
== ERROR_NONE_MAPPED
)
626 ApiStatus
= NERR_GroupNotFound
;
631 /* Add new members to the alias */
632 for (i
= 0; i
< totalentries
; i
++)
634 Status
= SamAddMemberToAlias(AliasHandle
,
635 MemberList
[i
].lgrmi0_sid
);
636 if (!NT_SUCCESS(Status
))
638 ERR("SamAddMemberToAlias failed (Status %lu)\n", Status
);
639 ApiStatus
= NetpNtStatusToApiStatus(Status
);
645 if (level
== 3 && MemberList
!= NULL
)
647 for (i
= 0; i
< totalentries
; i
++)
649 if (MemberList
[i
].lgrmi0_sid
!= NULL
)
650 NetApiBufferFree(MemberList
[i
].lgrmi0_sid
);
653 NetApiBufferFree(MemberList
);
656 if (AliasHandle
!= NULL
)
657 SamCloseHandle(AliasHandle
);
659 if (DomainHandle
!= NULL
)
660 SamCloseHandle(DomainHandle
);
662 if (ServerHandle
!= NULL
)
663 SamCloseHandle(ServerHandle
);
669 /************************************************************
670 * NetLocalGroupDel (NETAPI32.@)
678 UNICODE_STRING ServerName
;
679 UNICODE_STRING GroupName
;
680 SAM_HANDLE ServerHandle
= NULL
;
681 SAM_HANDLE DomainHandle
= NULL
;
682 SAM_HANDLE AliasHandle
= NULL
;
683 NET_API_STATUS ApiStatus
= NERR_Success
;
684 NTSTATUS Status
= STATUS_SUCCESS
;
686 TRACE("(%s %s)\n", debugstr_w(servername
), debugstr_w(groupname
));
688 if (servername
!= NULL
)
689 RtlInitUnicodeString(&ServerName
, servername
);
691 RtlInitUnicodeString(&GroupName
, groupname
);
693 /* Connect to the SAM Server */
694 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
696 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
698 if (!NT_SUCCESS(Status
))
700 ERR("SamConnect failed (Status %08lx)\n", Status
);
701 ApiStatus
= NetpNtStatusToApiStatus(Status
);
705 /* Open the Builtin Domain */
706 Status
= OpenBuiltinDomain(ServerHandle
,
709 if (!NT_SUCCESS(Status
))
711 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
712 ApiStatus
= NetpNtStatusToApiStatus(Status
);
716 /* Open the alias account in the builtin domain */
717 ApiStatus
= OpenAliasByName(DomainHandle
,
721 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
723 TRACE("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
727 if (AliasHandle
== NULL
)
729 if (DomainHandle
!= NULL
)
731 SamCloseHandle(DomainHandle
);
735 /* Open the Acount Domain */
736 Status
= OpenAccountDomain(ServerHandle
,
737 (servername
!= NULL
) ? &ServerName
: NULL
,
740 if (!NT_SUCCESS(Status
))
742 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
743 ApiStatus
= NetpNtStatusToApiStatus(Status
);
747 /* Open the alias account in the account domain */
748 ApiStatus
= OpenAliasByName(DomainHandle
,
752 if (ApiStatus
!= NERR_Success
)
754 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
755 if (ApiStatus
== ERROR_NONE_MAPPED
)
756 ApiStatus
= NERR_GroupNotFound
;
761 /* Delete the alias */
762 Status
= SamDeleteAlias(AliasHandle
);
763 if (!NT_SUCCESS(Status
))
765 ERR("SamDeleteAlias failed (Status %08lx)\n", Status
);
766 ApiStatus
= NetpNtStatusToApiStatus(Status
);
771 if (AliasHandle
!= NULL
)
772 SamCloseHandle(AliasHandle
);
774 if (DomainHandle
!= NULL
)
775 SamCloseHandle(DomainHandle
);
777 if (ServerHandle
!= NULL
)
778 SamCloseHandle(ServerHandle
);
784 /************************************************************
785 * NetLocalGroupDelMember (NETAPI32.@)
789 NetLocalGroupDelMember(
794 LOCALGROUP_MEMBERS_INFO_0 Member
;
796 TRACE("(%s %s %p)\n", debugstr_w(servername
),
797 debugstr_w(groupname
), membersid
);
799 Member
.lgrmi0_sid
= membersid
;
801 return NetLocalGroupDelMembers(servername
,
809 /************************************************************
810 * NetLocalGroupDelMembers (NETAPI32.@)
814 NetLocalGroupDelMembers(
821 UNICODE_STRING ServerName
;
822 UNICODE_STRING AliasName
;
823 SAM_HANDLE ServerHandle
= NULL
;
824 SAM_HANDLE DomainHandle
= NULL
;
825 SAM_HANDLE AliasHandle
= NULL
;
826 PLOCALGROUP_MEMBERS_INFO_0 MemberList
= NULL
;
828 NET_API_STATUS ApiStatus
= NERR_Success
;
829 NTSTATUS Status
= STATUS_SUCCESS
;
831 TRACE("(%s %s %d %p %d)\n", debugstr_w(servername
),
832 debugstr_w(groupname
), level
, buf
, totalentries
);
834 if (servername
!= NULL
)
835 RtlInitUnicodeString(&ServerName
, servername
);
837 RtlInitUnicodeString(&AliasName
, groupname
);
842 MemberList
= (PLOCALGROUP_MEMBERS_INFO_0
)buf
;
846 Status
= BuildSidListFromDomainAndName((servername
!= NULL
) ? &ServerName
: NULL
,
847 (PLOCALGROUP_MEMBERS_INFO_3
)buf
,
850 if (!NT_SUCCESS(Status
))
852 ERR("BuildSidListFromDomainAndName failed (Status %08lx)\n", Status
);
853 ApiStatus
= NetpNtStatusToApiStatus(Status
);
859 ApiStatus
= ERROR_INVALID_LEVEL
;
863 /* Connect to the SAM Server */
864 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
866 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
868 if (!NT_SUCCESS(Status
))
870 ERR("SamConnect failed (Status %08lx)\n", Status
);
871 ApiStatus
= NetpNtStatusToApiStatus(Status
);
875 /* Open the Builtin Domain */
876 Status
= OpenBuiltinDomain(ServerHandle
,
879 if (!NT_SUCCESS(Status
))
881 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
882 ApiStatus
= NetpNtStatusToApiStatus(Status
);
886 /* Open the alias account in the builtin domain */
887 ApiStatus
= OpenAliasByName(DomainHandle
,
891 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
893 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
897 if (AliasHandle
== NULL
)
899 if (DomainHandle
!= NULL
)
900 SamCloseHandle(DomainHandle
);
902 /* Open the Acount Domain */
903 Status
= OpenAccountDomain(ServerHandle
,
904 (servername
!= NULL
) ? &ServerName
: NULL
,
907 if (!NT_SUCCESS(Status
))
909 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
910 ApiStatus
= NetpNtStatusToApiStatus(Status
);
914 /* Open the alias account in the account domain */
915 ApiStatus
= OpenAliasByName(DomainHandle
,
919 if (ApiStatus
!= NERR_Success
)
921 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
922 if (ApiStatus
== ERROR_NONE_MAPPED
)
923 ApiStatus
= NERR_GroupNotFound
;
928 /* Remove members from the alias */
929 for (i
= 0; i
< totalentries
; i
++)
931 Status
= SamRemoveMemberFromAlias(AliasHandle
,
932 MemberList
[i
].lgrmi0_sid
);
933 if (!NT_SUCCESS(Status
))
935 ERR("SamAddMemberToAlias failed (Status %lu)\n", Status
);
936 ApiStatus
= NetpNtStatusToApiStatus(Status
);
942 if (level
== 3 && MemberList
!= NULL
)
944 for (i
= 0; i
< totalentries
; i
++)
946 if (MemberList
[i
].lgrmi0_sid
!= NULL
)
947 NetApiBufferFree(MemberList
[i
].lgrmi0_sid
);
950 NetApiBufferFree(MemberList
);
953 if (AliasHandle
!= NULL
)
954 SamCloseHandle(AliasHandle
);
956 if (DomainHandle
!= NULL
)
957 SamCloseHandle(DomainHandle
);
959 if (ServerHandle
!= NULL
)
960 SamCloseHandle(ServerHandle
);
966 /************************************************************
967 * NetLocalGroupEnum (NETAPI32.@)
977 LPDWORD totalentries
,
978 PDWORD_PTR resumehandle
)
980 UNICODE_STRING ServerName
;
981 PSAM_RID_ENUMERATION CurrentAlias
;
982 PENUM_CONTEXT EnumContext
= NULL
;
984 SAM_HANDLE AliasHandle
= NULL
;
985 PALIAS_GENERAL_INFORMATION AliasInfo
= NULL
;
986 LPVOID Buffer
= NULL
;
987 NET_API_STATUS ApiStatus
= NERR_Success
;
988 NTSTATUS Status
= STATUS_SUCCESS
;
990 TRACE("(%s %d %p %d %p %p %p) stub!\n", debugstr_w(servername
),
991 level
, bufptr
, prefmaxlen
, entriesread
, totalentries
, resumehandle
);
997 if (servername
!= NULL
)
998 RtlInitUnicodeString(&ServerName
, servername
);
1000 if (resumehandle
!= NULL
&& *resumehandle
!= 0)
1002 EnumContext
= (PENUM_CONTEXT
)*resumehandle
;
1006 ApiStatus
= NetApiBufferAllocate(sizeof(ENUM_CONTEXT
), (PVOID
*)&EnumContext
);
1007 if (ApiStatus
!= NERR_Success
)
1010 EnumContext
->EnumerationContext
= 0;
1011 EnumContext
->Buffer
= NULL
;
1012 EnumContext
->Returned
= 0;
1013 EnumContext
->Index
= 0;
1015 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
1016 &EnumContext
->ServerHandle
,
1017 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
1019 if (!NT_SUCCESS(Status
))
1021 ERR("SamConnect failed (Status %08lx)\n", Status
);
1022 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1026 Status
= OpenAccountDomain(EnumContext
->ServerHandle
,
1027 (servername
!= NULL
) ? &ServerName
: NULL
,
1028 DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
,
1029 &EnumContext
->AccountDomainHandle
);
1030 if (!NT_SUCCESS(Status
))
1032 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
1033 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1037 Status
= OpenBuiltinDomain(EnumContext
->ServerHandle
,
1038 DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
,
1039 &EnumContext
->BuiltinDomainHandle
);
1040 if (!NT_SUCCESS(Status
))
1042 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
1043 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1047 EnumContext
->Phase
= BuiltinPhase
;
1048 EnumContext
->DomainHandle
= EnumContext
->BuiltinDomainHandle
;
1054 TRACE("EnumContext->Index: %lu\n", EnumContext
->Index
);
1055 TRACE("EnumContext->Returned: %lu\n", EnumContext
->Returned
);
1057 if (EnumContext
->Index
>= EnumContext
->Returned
)
1059 TRACE("Calling SamEnumerateAliasesInDomain\n");
1061 Status
= SamEnumerateAliasesInDomain(EnumContext
->DomainHandle
,
1062 &EnumContext
->EnumerationContext
,
1063 (PVOID
*)&EnumContext
->Buffer
,
1065 &EnumContext
->Returned
);
1067 TRACE("SamEnumerateAliasesInDomain returned (Status %08lx)\n", Status
);
1068 if (!NT_SUCCESS(Status
))
1070 ERR("SamEnumerateAliasesInDomain failed (Status %08lx)\n", Status
);
1071 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1075 if (Status
== STATUS_MORE_ENTRIES
)
1077 ApiStatus
= NERR_BufTooSmall
;
1082 TRACE("EnumContext: %lu\n", EnumContext
);
1083 TRACE("EnumContext->Returned: %lu\n", EnumContext
->Returned
);
1084 TRACE("EnumContext->Buffer: %p\n", EnumContext
->Buffer
);
1086 /* Get a pointer to the current alias */
1087 CurrentAlias
= &EnumContext
->Buffer
[EnumContext
->Index
];
1089 TRACE("RID: %lu\n", CurrentAlias
->RelativeId
);
1091 Status
= SamOpenAlias(EnumContext
->DomainHandle
,
1092 ALIAS_READ_INFORMATION
,
1093 CurrentAlias
->RelativeId
,
1095 if (!NT_SUCCESS(Status
))
1097 ERR("SamOpenAlias failed (Status %08lx)\n", Status
);
1098 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1102 Status
= SamQueryInformationAlias(AliasHandle
,
1103 AliasGeneralInformation
,
1104 (PVOID
*)&AliasInfo
);
1105 if (!NT_SUCCESS(Status
))
1107 ERR("SamQueryInformationAlias failed (Status %08lx)\n", Status
);
1108 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1112 SamCloseHandle(AliasHandle
);
1115 TRACE("Name: %S\n", AliasInfo
->Name
.Buffer
);
1116 TRACE("Comment: %S\n", AliasInfo
->AdminComment
.Buffer
);
1118 ApiStatus
= BuildAliasInfoBuffer(AliasInfo
,
1121 if (ApiStatus
!= NERR_Success
)
1124 if (AliasInfo
!= NULL
)
1126 FreeAliasInfo(AliasInfo
);
1130 EnumContext
->Index
++;
1134 if (EnumContext
->Index
== EnumContext
->Returned
)
1136 switch (EnumContext
->Phase
)
1139 EnumContext
->Phase
= AccountPhase
;
1140 EnumContext
->DomainHandle
= EnumContext
->AccountDomainHandle
;
1141 EnumContext
->EnumerationContext
= 0;
1142 EnumContext
->Index
= 0;
1143 EnumContext
->Returned
= 0;
1145 if (EnumContext
->Buffer
!= NULL
)
1147 for (i
= 0; i
< EnumContext
->Returned
; i
++)
1149 SamFreeMemory(EnumContext
->Buffer
[i
].Name
.Buffer
);
1152 SamFreeMemory(EnumContext
->Buffer
);
1153 EnumContext
->Buffer
= NULL
;
1159 EnumContext
->Phase
= DonePhase
;
1166 if (ApiStatus
== NERR_Success
&& EnumContext
!= NULL
&& EnumContext
->Phase
!= DonePhase
)
1167 ApiStatus
= ERROR_MORE_DATA
;
1169 if (EnumContext
!= NULL
)
1170 *totalentries
= EnumContext
->Returned
;
1172 if (resumehandle
== NULL
|| ApiStatus
!= ERROR_MORE_DATA
)
1174 if (EnumContext
!= NULL
)
1176 if (EnumContext
->BuiltinDomainHandle
!= NULL
)
1177 SamCloseHandle(EnumContext
->BuiltinDomainHandle
);
1179 if (EnumContext
->AccountDomainHandle
!= NULL
)
1180 SamCloseHandle(EnumContext
->AccountDomainHandle
);
1182 if (EnumContext
->ServerHandle
!= NULL
)
1183 SamCloseHandle(EnumContext
->ServerHandle
);
1185 if (EnumContext
->Buffer
!= NULL
)
1187 for (i
= 0; i
< EnumContext
->Returned
; i
++)
1189 SamFreeMemory(EnumContext
->Buffer
[i
].Name
.Buffer
);
1192 SamFreeMemory(EnumContext
->Buffer
);
1195 NetApiBufferFree(EnumContext
);
1200 if (AliasHandle
!= NULL
)
1201 SamCloseHandle(AliasHandle
);
1203 if (AliasInfo
!= NULL
)
1204 FreeAliasInfo(AliasInfo
);
1206 if (resumehandle
!= NULL
)
1207 *resumehandle
= (DWORD_PTR
)EnumContext
;
1209 *bufptr
= (LPBYTE
)Buffer
;
1211 TRACE ("return %lu\n", ApiStatus
);
1217 /************************************************************
1218 * NetLocalGroupGetInfo (NETAPI32.@)
1222 NetLocalGroupGetInfo(
1228 UNICODE_STRING ServerName
;
1229 UNICODE_STRING GroupName
;
1230 SAM_HANDLE ServerHandle
= NULL
;
1231 SAM_HANDLE DomainHandle
= NULL
;
1232 SAM_HANDLE AliasHandle
= NULL
;
1233 PALIAS_GENERAL_INFORMATION AliasInfo
= NULL
;
1234 LPVOID Buffer
= NULL
;
1235 NET_API_STATUS ApiStatus
= NERR_Success
;
1236 NTSTATUS Status
= STATUS_SUCCESS
;
1238 TRACE("(%s %s %d %p) stub!\n", debugstr_w(servername
),
1239 debugstr_w(groupname
), level
, bufptr
);
1241 if (servername
!= NULL
)
1242 RtlInitUnicodeString(&ServerName
, servername
);
1244 RtlInitUnicodeString(&GroupName
, groupname
);
1246 /* Connect to the SAM Server */
1247 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
1249 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
1251 if (!NT_SUCCESS(Status
))
1253 ERR("SamConnect failed (Status %08lx)\n", Status
);
1254 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1258 /* Open the Builtin Domain */
1259 Status
= OpenBuiltinDomain(ServerHandle
,
1262 if (!NT_SUCCESS(Status
))
1264 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
1265 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1269 /* Open the alias account in the builtin domain */
1270 ApiStatus
= OpenAliasByName(DomainHandle
,
1272 ALIAS_READ_INFORMATION
,
1274 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
1276 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
1280 if (AliasHandle
== NULL
)
1282 if (DomainHandle
!= NULL
)
1283 SamCloseHandle(DomainHandle
);
1285 /* Open the Acount Domain */
1286 Status
= OpenAccountDomain(ServerHandle
,
1287 (servername
!= NULL
) ? &ServerName
: NULL
,
1290 if (!NT_SUCCESS(Status
))
1292 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
1293 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1297 /* Open the alias account in the account domain */
1298 ApiStatus
= OpenAliasByName(DomainHandle
,
1300 ALIAS_READ_INFORMATION
,
1302 if (ApiStatus
!= NERR_Success
)
1304 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
1305 if (ApiStatus
== ERROR_NONE_MAPPED
)
1306 ApiStatus
= NERR_GroupNotFound
;
1311 Status
= SamQueryInformationAlias(AliasHandle
,
1312 AliasGeneralInformation
,
1313 (PVOID
*)&AliasInfo
);
1314 if (!NT_SUCCESS(Status
))
1316 ERR("SamQueryInformationAlias failed (Status %08lx)\n", Status
);
1317 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1321 ApiStatus
= BuildAliasInfoBuffer(AliasInfo
,
1324 if (ApiStatus
!= NERR_Success
)
1328 if (AliasInfo
!= NULL
)
1329 FreeAliasInfo(AliasInfo
);
1331 if (AliasHandle
!= NULL
)
1332 SamCloseHandle(AliasHandle
);
1334 if (DomainHandle
!= NULL
)
1335 SamCloseHandle(DomainHandle
);
1337 if (ServerHandle
!= NULL
)
1338 SamCloseHandle(ServerHandle
);
1340 *bufptr
= (LPBYTE
)Buffer
;
1346 /************************************************************
1347 * NetLocalGroupGetMembers (NETAPI32.@)
1351 NetLocalGroupGetMembers(
1353 LPCWSTR localgroupname
,
1357 LPDWORD entriesread
,
1358 LPDWORD totalentries
,
1359 PDWORD_PTR resumehandle
)
1361 OBJECT_ATTRIBUTES ObjectAttributes
;
1362 UNICODE_STRING ServerName
;
1363 UNICODE_STRING AliasName
;
1364 PMEMBER_ENUM_CONTEXT EnumContext
= NULL
;
1365 LPVOID Buffer
= NULL
;
1366 PLOCALGROUP_MEMBERS_INFO_0 MembersInfo0
;
1367 PLOCALGROUP_MEMBERS_INFO_1 MembersInfo1
;
1368 PLOCALGROUP_MEMBERS_INFO_2 MembersInfo2
;
1369 PLOCALGROUP_MEMBERS_INFO_3 MembersInfo3
;
1374 NET_API_STATUS ApiStatus
= NERR_Success
;
1375 NTSTATUS Status
= STATUS_SUCCESS
;
1377 TRACE("(%s %s %d %p %d %p %p %p)\n", debugstr_w(servername
),
1378 debugstr_w(localgroupname
), level
, bufptr
, prefmaxlen
, entriesread
,
1379 totalentries
, resumehandle
);
1385 if (servername
!= NULL
)
1386 RtlInitUnicodeString(&ServerName
, servername
);
1388 RtlInitUnicodeString(&AliasName
, localgroupname
);
1390 if (resumehandle
!= NULL
&& *resumehandle
!= 0)
1392 EnumContext
= (PMEMBER_ENUM_CONTEXT
)*resumehandle
;
1396 /* Allocate the enumeration context */
1397 ApiStatus
= NetApiBufferAllocate(sizeof(MEMBER_ENUM_CONTEXT
), (PVOID
*)&EnumContext
);
1398 if (ApiStatus
!= NERR_Success
)
1401 /* Connect to the SAM Server */
1402 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
1403 &EnumContext
->ServerHandle
,
1404 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
1406 if (!NT_SUCCESS(Status
))
1408 ERR("SamConnect failed (Status %08lx)\n", Status
);
1409 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1413 /* Open the Builtin Domain */
1414 Status
= OpenBuiltinDomain(EnumContext
->ServerHandle
,
1416 &EnumContext
->DomainHandle
);
1417 if (!NT_SUCCESS(Status
))
1419 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
1420 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1424 /* Open the alias account in the builtin domain */
1425 ApiStatus
= OpenAliasByName(EnumContext
->DomainHandle
,
1428 &EnumContext
->AliasHandle
);
1429 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
1431 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
1435 if (EnumContext
->AliasHandle
== NULL
)
1437 if (EnumContext
->DomainHandle
!= NULL
)
1438 SamCloseHandle(EnumContext
->DomainHandle
);
1440 /* Open the Acount Domain */
1441 Status
= OpenAccountDomain(EnumContext
->ServerHandle
,
1442 (servername
!= NULL
) ? &ServerName
: NULL
,
1444 &EnumContext
->DomainHandle
);
1445 if (!NT_SUCCESS(Status
))
1447 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
1448 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1452 /* Open the alias account in the account domain */
1453 ApiStatus
= OpenAliasByName(EnumContext
->DomainHandle
,
1456 &EnumContext
->AliasHandle
);
1457 if (ApiStatus
!= NERR_Success
)
1459 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
1460 if (ApiStatus
== ERROR_NONE_MAPPED
)
1461 ApiStatus
= NERR_GroupNotFound
;
1466 /* Get the member list */
1467 Status
= SamGetMembersInAlias(EnumContext
->AliasHandle
,
1469 &EnumContext
->Count
);
1470 if (!NT_SUCCESS(Status
))
1472 ERR("SamGetMemberInAlias failed (Status %08lx)\n", Status
);
1473 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1477 if (EnumContext
->Count
== 0)
1479 TRACE("No member found. We're done.\n");
1480 ApiStatus
= NERR_Success
;
1484 /* Get name and domain information for all members */
1487 InitializeObjectAttributes(&ObjectAttributes
,
1493 Status
= LsaOpenPolicy((servername
!= NULL
) ? &ServerName
: NULL
,
1494 (PLSA_OBJECT_ATTRIBUTES
)&ObjectAttributes
,
1496 &EnumContext
->LsaHandle
);
1497 if (!NT_SUCCESS(Status
))
1499 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1503 Status
= LsaLookupSids(EnumContext
->LsaHandle
,
1506 &EnumContext
->Domains
,
1507 &EnumContext
->Names
);
1508 if (!NT_SUCCESS(Status
))
1510 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1516 /* Calculate the required buffer size */
1517 for (i
= 0; i
< EnumContext
->Count
; i
++)
1522 Size
+= sizeof(LOCALGROUP_MEMBERS_INFO_0
) +
1523 RtlLengthSid(EnumContext
->Sids
[i
]);
1527 Size
+= sizeof(LOCALGROUP_MEMBERS_INFO_1
) +
1528 RtlLengthSid(EnumContext
->Sids
[i
]) +
1529 EnumContext
->Names
[i
].Name
.Length
+ sizeof(WCHAR
);
1533 Size
+= sizeof(LOCALGROUP_MEMBERS_INFO_2
) +
1534 RtlLengthSid(EnumContext
->Sids
[i
]) +
1535 EnumContext
->Names
[i
].Name
.Length
+ sizeof(WCHAR
);
1536 if (EnumContext
->Names
[i
].DomainIndex
>= 0)
1537 Size
+= EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Length
+ sizeof(WCHAR
);
1541 Size
+= sizeof(LOCALGROUP_MEMBERS_INFO_3
) +
1542 EnumContext
->Names
[i
].Name
.Length
+ sizeof(WCHAR
);
1543 if (EnumContext
->Names
[i
].DomainIndex
>= 0)
1544 Size
+= EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Length
+ sizeof(WCHAR
);
1548 ApiStatus
= ERROR_INVALID_LEVEL
;
1553 /* Allocate the member buffer */
1554 ApiStatus
= NetApiBufferAllocate(Size
, &Buffer
);
1555 if (ApiStatus
!= NERR_Success
)
1558 ZeroMemory(Buffer
, Size
);
1560 /* Fill the member buffer */
1564 MembersInfo0
= (PLOCALGROUP_MEMBERS_INFO_0
)Buffer
;
1565 Ptr
= (PVOID
)((ULONG_PTR
)Buffer
+ sizeof(LOCALGROUP_MEMBERS_INFO_0
) * EnumContext
->Count
);
1569 MembersInfo1
= (PLOCALGROUP_MEMBERS_INFO_1
)Buffer
;
1570 Ptr
= (PVOID
)((ULONG_PTR
)Buffer
+ sizeof(LOCALGROUP_MEMBERS_INFO_1
) * EnumContext
->Count
);
1574 MembersInfo2
= (PLOCALGROUP_MEMBERS_INFO_2
)Buffer
;
1575 Ptr
= (PVOID
)((ULONG_PTR
)Buffer
+ sizeof(LOCALGROUP_MEMBERS_INFO_2
) * EnumContext
->Count
);
1579 MembersInfo3
= (PLOCALGROUP_MEMBERS_INFO_3
)Buffer
;
1580 Ptr
= (PVOID
)((ULONG_PTR
)Buffer
+ sizeof(LOCALGROUP_MEMBERS_INFO_3
) * EnumContext
->Count
);
1584 for (i
= 0; i
< EnumContext
->Count
; i
++)
1589 MembersInfo0
->lgrmi0_sid
= (PSID
)Ptr
;
1591 SidLength
= RtlLengthSid(EnumContext
->Sids
[i
]);
1592 memcpy(MembersInfo0
->lgrmi0_sid
,
1593 EnumContext
->Sids
[i
],
1595 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ SidLength
);
1600 MembersInfo1
->lgrmi1_sid
= (PSID
)Ptr
;
1602 SidLength
= RtlLengthSid(EnumContext
->Sids
[i
]);
1603 memcpy(MembersInfo1
->lgrmi1_sid
,
1604 EnumContext
->Sids
[i
],
1607 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ SidLength
);
1609 MembersInfo1
->lgrmi1_sidusage
= EnumContext
->Names
[i
].Use
;
1611 TRACE("Name: %S\n", EnumContext
->Names
[i
].Name
.Buffer
);
1613 MembersInfo1
->lgrmi1_name
= Ptr
;
1615 memcpy(MembersInfo1
->lgrmi1_name
,
1616 EnumContext
->Names
[i
].Name
.Buffer
,
1617 EnumContext
->Names
[i
].Name
.Length
);
1618 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ EnumContext
->Names
[i
].Name
.Length
+ sizeof(WCHAR
));
1623 MembersInfo2
->lgrmi2_sid
= (PSID
)Ptr
;
1625 SidLength
= RtlLengthSid(EnumContext
->Sids
[i
]);
1626 memcpy(MembersInfo2
->lgrmi2_sid
,
1627 EnumContext
->Sids
[i
],
1630 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ SidLength
);
1632 MembersInfo2
->lgrmi2_sidusage
= EnumContext
->Names
[i
].Use
;
1634 MembersInfo2
->lgrmi2_domainandname
= Ptr
;
1636 if (EnumContext
->Names
[i
].DomainIndex
>= 0)
1638 memcpy(MembersInfo2
->lgrmi2_domainandname
,
1639 EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Buffer
,
1640 EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Length
);
1642 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Length
);
1644 *((LPWSTR
)Ptr
) = L
'\\';
1646 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ sizeof(WCHAR
));
1650 EnumContext
->Names
[i
].Name
.Buffer
,
1651 EnumContext
->Names
[i
].Name
.Length
);
1652 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ EnumContext
->Names
[i
].Name
.Length
+ sizeof(WCHAR
));
1657 MembersInfo3
->lgrmi3_domainandname
= Ptr
;
1659 if (EnumContext
->Names
[i
].DomainIndex
>= 0)
1661 memcpy(MembersInfo3
->lgrmi3_domainandname
,
1662 EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Buffer
,
1663 EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Length
);
1665 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Length
);
1667 *((LPWSTR
)Ptr
) = L
'\\';
1669 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ sizeof(WCHAR
));
1673 EnumContext
->Names
[i
].Name
.Buffer
,
1674 EnumContext
->Names
[i
].Name
.Length
);
1675 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ EnumContext
->Names
[i
].Name
.Length
+ sizeof(WCHAR
));
1681 *entriesread
= EnumContext
->Count
;
1683 *bufptr
= (LPBYTE
)Buffer
;
1686 if (EnumContext
!= NULL
)
1687 *totalentries
= EnumContext
->Count
;
1689 if (resumehandle
== NULL
|| ApiStatus
!= ERROR_MORE_DATA
)
1691 /* Release the enumeration context */
1692 if (EnumContext
!= NULL
)
1694 if (EnumContext
->LsaHandle
!= NULL
)
1695 LsaClose(EnumContext
->LsaHandle
);
1697 if (EnumContext
->AliasHandle
!= NULL
)
1698 SamCloseHandle(EnumContext
->AliasHandle
);
1700 if (EnumContext
->DomainHandle
!= NULL
)
1701 SamCloseHandle(EnumContext
->DomainHandle
);
1703 if (EnumContext
->ServerHandle
!= NULL
)
1704 SamCloseHandle(EnumContext
->ServerHandle
);
1706 if (EnumContext
->Sids
!= NULL
)
1707 SamFreeMemory(EnumContext
->Sids
);
1709 if (EnumContext
->Domains
!= NULL
)
1710 LsaFreeMemory(EnumContext
->Domains
);
1712 if (EnumContext
->Names
!= NULL
)
1713 LsaFreeMemory(EnumContext
->Names
);
1715 NetApiBufferFree(EnumContext
);
1724 /************************************************************
1725 * NetLocalGroupSetInfo (NETAPI32.@)
1729 NetLocalGroupSetInfo(
1736 UNICODE_STRING ServerName
;
1737 UNICODE_STRING AliasName
;
1738 SAM_HANDLE ServerHandle
= NULL
;
1739 SAM_HANDLE DomainHandle
= NULL
;
1740 SAM_HANDLE AliasHandle
= NULL
;
1741 ALIAS_NAME_INFORMATION AliasNameInfo
;
1742 ALIAS_ADM_COMMENT_INFORMATION AdminCommentInfo
;
1743 NET_API_STATUS ApiStatus
= NERR_Success
;
1744 NTSTATUS Status
= STATUS_SUCCESS
;
1746 TRACE("(%s %s %d %p %p)\n", debugstr_w(servername
),
1747 debugstr_w(groupname
), level
, buf
, parm_err
);
1749 if (parm_err
!= NULL
)
1750 *parm_err
= PARM_ERROR_NONE
;
1752 if (servername
!= NULL
)
1753 RtlInitUnicodeString(&ServerName
, servername
);
1755 RtlInitUnicodeString(&AliasName
, groupname
);
1757 /* Connect to the SAM Server */
1758 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
1760 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
1762 if (!NT_SUCCESS(Status
))
1764 ERR("SamConnect failed (Status %08lx)\n", Status
);
1765 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1769 /* Open the Builtin Domain */
1770 Status
= OpenBuiltinDomain(ServerHandle
,
1773 if (!NT_SUCCESS(Status
))
1775 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
1776 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1780 /* Open the alias account in the builtin domain */
1781 ApiStatus
= OpenAliasByName(DomainHandle
,
1783 ALIAS_WRITE_ACCOUNT
,
1785 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
1787 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
1791 if (AliasHandle
== NULL
)
1793 if (DomainHandle
!= NULL
)
1794 SamCloseHandle(DomainHandle
);
1796 /* Open the Acount Domain */
1797 Status
= OpenAccountDomain(ServerHandle
,
1798 (servername
!= NULL
) ? &ServerName
: NULL
,
1801 if (!NT_SUCCESS(Status
))
1803 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
1804 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1808 /* Open the alias account in the account domain */
1809 ApiStatus
= OpenAliasByName(DomainHandle
,
1811 ALIAS_WRITE_ACCOUNT
,
1813 if (ApiStatus
!= NERR_Success
)
1815 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
1816 if (ApiStatus
== ERROR_NONE_MAPPED
)
1817 ApiStatus
= NERR_GroupNotFound
;
1825 /* Set the alias name */
1826 RtlInitUnicodeString(&AliasNameInfo
.Name
,
1827 ((PLOCALGROUP_INFO_0
)buf
)->lgrpi0_name
);
1829 Status
= SamSetInformationAlias(AliasHandle
,
1830 AliasNameInformation
,
1832 if (!NT_SUCCESS(Status
))
1834 TRACE("SamSetInformationAlias failed (ApiStatus %lu)\n", ApiStatus
);
1835 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1842 /* Set the alias admin comment */
1844 RtlInitUnicodeString(&AdminCommentInfo
.AdminComment
,
1845 ((PLOCALGROUP_INFO_1
)buf
)->lgrpi1_comment
);
1847 RtlInitUnicodeString(&AdminCommentInfo
.AdminComment
,
1848 ((PLOCALGROUP_INFO_1002
)buf
)->lgrpi1002_comment
);
1850 Status
= SamSetInformationAlias(AliasHandle
,
1851 AliasAdminCommentInformation
,
1853 if (!NT_SUCCESS(Status
))
1855 TRACE("SamSetInformationAlias failed (ApiStatus %lu)\n", ApiStatus
);
1856 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1862 ApiStatus
= ERROR_INVALID_LEVEL
;
1867 if (AliasHandle
!= NULL
)
1868 SamCloseHandle(AliasHandle
);
1870 if (DomainHandle
!= NULL
)
1871 SamCloseHandle(DomainHandle
);
1873 if (ServerHandle
!= NULL
)
1874 SamCloseHandle(ServerHandle
);
1880 /************************************************************
1881 * NetLocalGroupSetMember (NETAPI32.@)
1885 NetLocalGroupSetMembers(
1892 FIXME("(%s %s %d %p %d) stub!\n", debugstr_w(servername
),
1893 debugstr_w(groupname
), level
, buf
, totalentries
);
1894 return NERR_Success
;