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
);
26 typedef enum _ENUM_PHASE
33 typedef struct _ENUM_CONTEXT
35 SAM_HANDLE ServerHandle
;
36 SAM_HANDLE DomainHandle
;
37 SAM_HANDLE BuiltinDomainHandle
;
38 SAM_HANDLE AccountDomainHandle
;
40 SAM_ENUMERATE_HANDLE EnumerationContext
;
41 PSAM_RID_ENUMERATION Buffer
;
46 } ENUM_CONTEXT
, *PENUM_CONTEXT
;
48 typedef struct _MEMBER_ENUM_CONTEXT
50 SAM_HANDLE ServerHandle
;
51 SAM_HANDLE DomainHandle
;
52 SAM_HANDLE AliasHandle
;
57 PLSA_REFERENCED_DOMAIN_LIST Domains
;
58 PLSA_TRANSLATED_NAME Names
;
60 } MEMBER_ENUM_CONTEXT
, *PMEMBER_ENUM_CONTEXT
;
65 BuildAliasInfoBuffer(PALIAS_GENERAL_INFORMATION AliasInfo
,
69 LPVOID LocalBuffer
= NULL
;
70 PLOCALGROUP_INFO_0 LocalInfo0
;
71 PLOCALGROUP_INFO_1 LocalInfo1
;
74 NET_API_STATUS ApiStatus
= NERR_Success
;
81 Size
= sizeof(LOCALGROUP_INFO_0
) +
82 AliasInfo
->Name
.Length
+ sizeof(WCHAR
);
86 Size
= sizeof(LOCALGROUP_INFO_1
) +
87 AliasInfo
->Name
.Length
+ sizeof(WCHAR
) +
88 AliasInfo
->AdminComment
.Length
+ sizeof(WCHAR
);
92 ApiStatus
= ERROR_INVALID_LEVEL
;
96 ApiStatus
= NetApiBufferAllocate(Size
, &LocalBuffer
);
97 if (ApiStatus
!= NERR_Success
)
100 ZeroMemory(LocalBuffer
, Size
);
105 LocalInfo0
= (PLOCALGROUP_INFO_0
)LocalBuffer
;
107 Ptr
= (LPWSTR
)LocalInfo0
++;
108 LocalInfo0
->lgrpi0_name
= Ptr
;
110 memcpy(LocalInfo0
->lgrpi0_name
,
111 AliasInfo
->Name
.Buffer
,
112 AliasInfo
->Name
.Length
);
113 LocalInfo0
->lgrpi0_name
[AliasInfo
->Name
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
117 LocalInfo1
= (PLOCALGROUP_INFO_1
)LocalBuffer
;
119 Ptr
= (LPWSTR
)((ULONG_PTR
)LocalInfo1
+ sizeof(LOCALGROUP_INFO_1
));
120 LocalInfo1
->lgrpi1_name
= Ptr
;
122 memcpy(LocalInfo1
->lgrpi1_name
,
123 AliasInfo
->Name
.Buffer
,
124 AliasInfo
->Name
.Length
);
125 LocalInfo1
->lgrpi1_name
[AliasInfo
->Name
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
127 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ AliasInfo
->Name
.Length
+ sizeof(WCHAR
));
128 LocalInfo1
->lgrpi1_comment
= Ptr
;
130 memcpy(LocalInfo1
->lgrpi1_comment
,
131 AliasInfo
->AdminComment
.Buffer
,
132 AliasInfo
->AdminComment
.Length
);
133 LocalInfo1
->lgrpi1_comment
[AliasInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
138 if (ApiStatus
== NERR_Success
)
140 *Buffer
= LocalBuffer
;
144 if (LocalBuffer
!= NULL
)
145 NetApiBufferFree(LocalBuffer
);
154 FreeAliasInfo(PALIAS_GENERAL_INFORMATION AliasInfo
)
156 if (AliasInfo
->Name
.Buffer
!= NULL
)
157 SamFreeMemory(AliasInfo
->Name
.Buffer
);
159 if (AliasInfo
->AdminComment
.Buffer
!= NULL
)
160 SamFreeMemory(AliasInfo
->AdminComment
.Buffer
);
162 SamFreeMemory(AliasInfo
);
168 OpenAliasByName(SAM_HANDLE DomainHandle
,
169 PUNICODE_STRING AliasName
,
171 PSAM_HANDLE AliasHandle
)
173 PULONG RelativeIds
= NULL
;
174 PSID_NAME_USE Use
= NULL
;
175 NET_API_STATUS ApiStatus
= NERR_Success
;
176 NTSTATUS Status
= STATUS_SUCCESS
;
178 /* Get the RID for the given user name */
179 Status
= SamLookupNamesInDomain(DomainHandle
,
184 if (!NT_SUCCESS(Status
))
186 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status
);
187 return NetpNtStatusToApiStatus(Status
);
190 /* Fail, if it is not an alias account */
191 if (Use
[0] != SidTypeAlias
)
193 ERR("Object is not an Alias!\n");
194 ApiStatus
= NERR_GroupNotFound
;
198 /* Open the alias account */
199 Status
= SamOpenAlias(DomainHandle
,
203 if (!NT_SUCCESS(Status
))
205 ERR("SamOpenDomain failed (Status %08lx)\n", Status
);
206 ApiStatus
= NetpNtStatusToApiStatus(Status
);
211 if (RelativeIds
!= NULL
)
212 SamFreeMemory(RelativeIds
);
223 BuildSidListFromDomainAndName(IN PUNICODE_STRING ServerName
,
224 IN PLOCALGROUP_MEMBERS_INFO_3 buf
,
226 OUT PLOCALGROUP_MEMBERS_INFO_0
*MemberList
)
228 OBJECT_ATTRIBUTES ObjectAttributes
;
229 LSA_HANDLE LsaHandle
= NULL
;
230 PUNICODE_STRING NamesArray
= NULL
;
232 PLSA_REFERENCED_DOMAIN_LIST Domains
= NULL
;
233 PLSA_TRANSLATED_SID Sids
= NULL
;
234 PLOCALGROUP_MEMBERS_INFO_0 MemberBuffer
= NULL
;
235 NET_API_STATUS ApiStatus
= NERR_Success
;
236 NTSTATUS Status
= STATUS_SUCCESS
;
238 ApiStatus
= NetApiBufferAllocate(sizeof(UNICODE_STRING
) * EntryCount
,
239 (LPVOID
*)&NamesArray
);
240 if (ApiStatus
!= NERR_Success
)
245 for (i
= 0; i
< EntryCount
; i
++)
247 RtlInitUnicodeString(&NamesArray
[i
],
248 buf
[i
].lgrmi3_domainandname
);
251 InitializeObjectAttributes(&ObjectAttributes
,
257 Status
= LsaOpenPolicy(ServerName
,
258 (PLSA_OBJECT_ATTRIBUTES
)&ObjectAttributes
,
261 if (!NT_SUCCESS(Status
))
263 ApiStatus
= NetpNtStatusToApiStatus(Status
);
267 Status
= LsaLookupNames(LsaHandle
,
272 if (!NT_SUCCESS(Status
))
274 ApiStatus
= NetpNtStatusToApiStatus(Status
);
278 ApiStatus
= NetApiBufferAllocate(sizeof(LOCALGROUP_MEMBERS_INFO_0
) * EntryCount
,
279 (LPVOID
*)&MemberBuffer
);
280 if (ApiStatus
!= NERR_Success
)
285 for (i
= 0; i
< EntryCount
; i
++)
287 ApiStatus
= BuildSidFromSidAndRid(Domains
->Domains
[Sids
[i
].DomainIndex
].Sid
,
289 &MemberBuffer
[i
].lgrmi0_sid
);
290 if (ApiStatus
!= NERR_Success
)
297 if (ApiStatus
!= NERR_Success
)
299 if (MemberBuffer
!= NULL
)
301 for (i
= 0; i
< EntryCount
; i
++)
303 if (MemberBuffer
[i
].lgrmi0_sid
!= NULL
)
304 NetApiBufferFree(MemberBuffer
[i
].lgrmi0_sid
);
307 NetApiBufferFree(MemberBuffer
);
316 LsaFreeMemory(Domains
);
318 if (LsaHandle
!= NULL
)
321 if (NamesArray
!= NULL
)
322 NetApiBufferFree(NamesArray
);
324 *MemberList
= MemberBuffer
;
330 /************************************************************
331 * NetLocalGroupAdd (NETAPI32.@)
341 ALIAS_ADM_COMMENT_INFORMATION AdminComment
;
342 UNICODE_STRING ServerName
;
343 UNICODE_STRING AliasName
;
344 SAM_HANDLE ServerHandle
= NULL
;
345 SAM_HANDLE DomainHandle
= NULL
;
346 SAM_HANDLE AliasHandle
= NULL
;
347 LPWSTR aliasname
= NULL
;
348 LPWSTR aliascomment
= NULL
;
350 NET_API_STATUS ApiStatus
= NERR_Success
;
351 NTSTATUS Status
= STATUS_SUCCESS
;
353 TRACE("(%s %d %p %p) stub!\n", debugstr_w(servername
), level
, buf
,
356 /* Initialize the Server name*/
357 if (servername
!= NULL
)
358 RtlInitUnicodeString(&ServerName
, servername
);
360 /* Initialize the Alias name*/
364 aliasname
= ((PLOCALGROUP_INFO_0
)buf
)->lgrpi0_name
;
369 aliasname
= ((PLOCALGROUP_INFO_1
)buf
)->lgrpi1_name
;
370 aliascomment
= ((PLOCALGROUP_INFO_1
)buf
)->lgrpi1_comment
;
374 return ERROR_INVALID_LEVEL
;
377 RtlInitUnicodeString(&AliasName
, aliasname
);
379 /* Connect to the SAM Server */
380 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
382 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
384 if (!NT_SUCCESS(Status
))
386 ERR("SamConnect failed (Status %08lx)\n", Status
);
387 ApiStatus
= NetpNtStatusToApiStatus(Status
);
391 /* Open the Builtin Domain */
392 Status
= OpenBuiltinDomain(ServerHandle
,
395 if (!NT_SUCCESS(Status
))
397 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
398 ApiStatus
= NetpNtStatusToApiStatus(Status
);
402 /* Try to open the Alias Account in the Builtin Domain */
403 ApiStatus
= OpenAliasByName(DomainHandle
,
405 ALIAS_READ_INFORMATION
,
407 if (ApiStatus
== NERR_Success
)
409 ERR("OpenAliasByName: alias %wZ already exists!\n", &AliasName
);
411 SamCloseHandle(AliasHandle
);
412 ApiStatus
= ERROR_ALIAS_EXISTS
;
416 ApiStatus
= NERR_Success
;
418 /* Close the Builtin Domain */
419 SamCloseHandle(DomainHandle
);
422 /* Open the account domain */
423 Status
= OpenAccountDomain(ServerHandle
,
424 (servername
!= NULL
) ? &ServerName
: NULL
,
425 DOMAIN_CREATE_ALIAS
| DOMAIN_LOOKUP
,
427 if (!NT_SUCCESS(Status
))
429 ERR("SamOpenDomain failed (Status %08lx)\n", Status
);
430 ApiStatus
= NetpNtStatusToApiStatus(Status
);
434 /* Create the alias */
435 Status
= SamCreateAliasInDomain(DomainHandle
,
437 DELETE
| ALIAS_WRITE_ACCOUNT
,
440 if (!NT_SUCCESS(Status
))
442 ERR("SamCreateAliasInDomain failed (Status %08lx)\n", Status
);
443 ApiStatus
= NetpNtStatusToApiStatus(Status
);
447 TRACE("Created alias \"%wZ\" (RID: %lu)\n", &AliasName
, RelativeId
);
449 /* Set the admin comment */
452 RtlInitUnicodeString(&AdminComment
.AdminComment
, aliascomment
);
454 Status
= SamSetInformationAlias(AliasHandle
,
455 AliasAdminCommentInformation
,
457 if (!NT_SUCCESS(Status
))
459 ERR("SamSetInformationAlias failed (Status %08lx)\n", Status
);
460 ApiStatus
= NetpNtStatusToApiStatus(Status
);
462 /* Delete the Alias if the Comment could not be set */
463 SamDeleteAlias(AliasHandle
);
470 if (AliasHandle
!= NULL
)
471 SamCloseHandle(AliasHandle
);
473 if (DomainHandle
!= NULL
)
474 SamCloseHandle(DomainHandle
);
476 if (ServerHandle
!= NULL
)
477 SamCloseHandle(ServerHandle
);
483 /************************************************************
484 * NetLocalGroupAddMember (NETAPI32.@)
488 NetLocalGroupAddMember(
493 LOCALGROUP_MEMBERS_INFO_0 Member
;
495 TRACE("(%s %s %p)\n", debugstr_w(servername
),
496 debugstr_w(groupname
), membersid
);
498 Member
.lgrmi0_sid
= membersid
;
500 return NetLocalGroupAddMembers(servername
,
508 /************************************************************
509 * NetLocalGroupAddMembers (NETAPI32.@)
513 NetLocalGroupAddMembers(
520 UNICODE_STRING ServerName
;
521 UNICODE_STRING AliasName
;
522 SAM_HANDLE ServerHandle
= NULL
;
523 SAM_HANDLE DomainHandle
= NULL
;
524 SAM_HANDLE AliasHandle
= NULL
;
525 PLOCALGROUP_MEMBERS_INFO_0 MemberList
= NULL
;
527 NET_API_STATUS ApiStatus
= NERR_Success
;
528 NTSTATUS Status
= STATUS_SUCCESS
;
530 TRACE("(%s %s %d %p %d)\n", debugstr_w(servername
),
531 debugstr_w(groupname
), level
, buf
, totalentries
);
533 if (servername
!= NULL
)
534 RtlInitUnicodeString(&ServerName
, servername
);
536 RtlInitUnicodeString(&AliasName
, groupname
);
541 MemberList
= (PLOCALGROUP_MEMBERS_INFO_0
)buf
;
545 Status
= BuildSidListFromDomainAndName((servername
!= NULL
) ? &ServerName
: NULL
,
546 (PLOCALGROUP_MEMBERS_INFO_3
)buf
,
549 if (!NT_SUCCESS(Status
))
551 ERR("BuildSidListFromDomainAndName failed (Status %08lx)\n", Status
);
552 ApiStatus
= NetpNtStatusToApiStatus(Status
);
558 ApiStatus
= ERROR_INVALID_LEVEL
;
562 /* Connect to the SAM Server */
563 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
565 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
567 if (!NT_SUCCESS(Status
))
569 ERR("SamConnect failed (Status %08lx)\n", Status
);
570 ApiStatus
= NetpNtStatusToApiStatus(Status
);
574 /* Open the Builtin Domain */
575 Status
= OpenBuiltinDomain(ServerHandle
,
578 if (!NT_SUCCESS(Status
))
580 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
581 ApiStatus
= NetpNtStatusToApiStatus(Status
);
585 /* Open the alias account in the builtin domain */
586 ApiStatus
= OpenAliasByName(DomainHandle
,
590 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
592 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
596 if (AliasHandle
== NULL
)
598 if (DomainHandle
!= NULL
)
599 SamCloseHandle(DomainHandle
);
601 /* Open the Acount Domain */
602 Status
= OpenAccountDomain(ServerHandle
,
603 (servername
!= NULL
) ? &ServerName
: NULL
,
606 if (!NT_SUCCESS(Status
))
608 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
609 ApiStatus
= NetpNtStatusToApiStatus(Status
);
613 /* Open the alias account in the account domain */
614 ApiStatus
= OpenAliasByName(DomainHandle
,
618 if (ApiStatus
!= NERR_Success
)
620 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
621 if (ApiStatus
== ERROR_NONE_MAPPED
)
622 ApiStatus
= NERR_GroupNotFound
;
627 /* Add new members to the alias */
628 for (i
= 0; i
< totalentries
; i
++)
630 Status
= SamAddMemberToAlias(AliasHandle
,
631 MemberList
[i
].lgrmi0_sid
);
632 if (!NT_SUCCESS(Status
))
634 ERR("SamAddMemberToAlias failed (Status %lu)\n", Status
);
635 ApiStatus
= NetpNtStatusToApiStatus(Status
);
641 if (level
== 3 && MemberList
!= NULL
)
643 for (i
= 0; i
< totalentries
; i
++)
645 if (MemberList
[i
].lgrmi0_sid
!= NULL
)
646 NetApiBufferFree(MemberList
[i
].lgrmi0_sid
);
649 NetApiBufferFree(MemberList
);
652 if (AliasHandle
!= NULL
)
653 SamCloseHandle(AliasHandle
);
655 if (DomainHandle
!= NULL
)
656 SamCloseHandle(DomainHandle
);
658 if (ServerHandle
!= NULL
)
659 SamCloseHandle(ServerHandle
);
665 /************************************************************
666 * NetLocalGroupDel (NETAPI32.@)
674 UNICODE_STRING ServerName
;
675 UNICODE_STRING GroupName
;
676 SAM_HANDLE ServerHandle
= NULL
;
677 SAM_HANDLE DomainHandle
= NULL
;
678 SAM_HANDLE AliasHandle
= NULL
;
679 NET_API_STATUS ApiStatus
= NERR_Success
;
680 NTSTATUS Status
= STATUS_SUCCESS
;
682 TRACE("(%s %s)\n", debugstr_w(servername
), debugstr_w(groupname
));
684 if (servername
!= NULL
)
685 RtlInitUnicodeString(&ServerName
, servername
);
687 RtlInitUnicodeString(&GroupName
, groupname
);
689 /* Connect to the SAM Server */
690 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
692 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
694 if (!NT_SUCCESS(Status
))
696 ERR("SamConnect failed (Status %08lx)\n", Status
);
697 ApiStatus
= NetpNtStatusToApiStatus(Status
);
701 /* Open the Builtin Domain */
702 Status
= OpenBuiltinDomain(ServerHandle
,
705 if (!NT_SUCCESS(Status
))
707 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
708 ApiStatus
= NetpNtStatusToApiStatus(Status
);
712 /* Open the alias account in the builtin domain */
713 ApiStatus
= OpenAliasByName(DomainHandle
,
717 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
719 TRACE("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
723 if (AliasHandle
== NULL
)
725 if (DomainHandle
!= NULL
)
727 SamCloseHandle(DomainHandle
);
731 /* Open the Acount Domain */
732 Status
= OpenAccountDomain(ServerHandle
,
733 (servername
!= NULL
) ? &ServerName
: NULL
,
736 if (!NT_SUCCESS(Status
))
738 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
739 ApiStatus
= NetpNtStatusToApiStatus(Status
);
743 /* Open the alias account in the account domain */
744 ApiStatus
= OpenAliasByName(DomainHandle
,
748 if (ApiStatus
!= NERR_Success
)
750 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
751 if (ApiStatus
== ERROR_NONE_MAPPED
)
752 ApiStatus
= NERR_GroupNotFound
;
757 /* Delete the alias */
758 Status
= SamDeleteAlias(AliasHandle
);
759 if (!NT_SUCCESS(Status
))
761 ERR("SamDeleteAlias failed (Status %08lx)\n", Status
);
762 ApiStatus
= NetpNtStatusToApiStatus(Status
);
767 if (AliasHandle
!= NULL
)
768 SamCloseHandle(AliasHandle
);
770 if (DomainHandle
!= NULL
)
771 SamCloseHandle(DomainHandle
);
773 if (ServerHandle
!= NULL
)
774 SamCloseHandle(ServerHandle
);
780 /************************************************************
781 * NetLocalGroupDelMember (NETAPI32.@)
785 NetLocalGroupDelMember(
790 LOCALGROUP_MEMBERS_INFO_0 Member
;
792 TRACE("(%s %s %p)\n", debugstr_w(servername
),
793 debugstr_w(groupname
), membersid
);
795 Member
.lgrmi0_sid
= membersid
;
797 return NetLocalGroupDelMembers(servername
,
805 /************************************************************
806 * NetLocalGroupDelMembers (NETAPI32.@)
810 NetLocalGroupDelMembers(
817 UNICODE_STRING ServerName
;
818 UNICODE_STRING AliasName
;
819 SAM_HANDLE ServerHandle
= NULL
;
820 SAM_HANDLE DomainHandle
= NULL
;
821 SAM_HANDLE AliasHandle
= NULL
;
822 PLOCALGROUP_MEMBERS_INFO_0 MemberList
= NULL
;
824 NET_API_STATUS ApiStatus
= NERR_Success
;
825 NTSTATUS Status
= STATUS_SUCCESS
;
827 TRACE("(%s %s %d %p %d)\n", debugstr_w(servername
),
828 debugstr_w(groupname
), level
, buf
, totalentries
);
830 if (servername
!= NULL
)
831 RtlInitUnicodeString(&ServerName
, servername
);
833 RtlInitUnicodeString(&AliasName
, groupname
);
838 MemberList
= (PLOCALGROUP_MEMBERS_INFO_0
)buf
;
842 Status
= BuildSidListFromDomainAndName((servername
!= NULL
) ? &ServerName
: NULL
,
843 (PLOCALGROUP_MEMBERS_INFO_3
)buf
,
846 if (!NT_SUCCESS(Status
))
848 ERR("BuildSidListFromDomainAndName failed (Status %08lx)\n", Status
);
849 ApiStatus
= NetpNtStatusToApiStatus(Status
);
855 ApiStatus
= ERROR_INVALID_LEVEL
;
859 /* Connect to the SAM Server */
860 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
862 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
864 if (!NT_SUCCESS(Status
))
866 ERR("SamConnect failed (Status %08lx)\n", Status
);
867 ApiStatus
= NetpNtStatusToApiStatus(Status
);
871 /* Open the Builtin Domain */
872 Status
= OpenBuiltinDomain(ServerHandle
,
875 if (!NT_SUCCESS(Status
))
877 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
878 ApiStatus
= NetpNtStatusToApiStatus(Status
);
882 /* Open the alias account in the builtin domain */
883 ApiStatus
= OpenAliasByName(DomainHandle
,
887 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
889 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
893 if (AliasHandle
== NULL
)
895 if (DomainHandle
!= NULL
)
896 SamCloseHandle(DomainHandle
);
898 /* Open the Acount Domain */
899 Status
= OpenAccountDomain(ServerHandle
,
900 (servername
!= NULL
) ? &ServerName
: NULL
,
903 if (!NT_SUCCESS(Status
))
905 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
906 ApiStatus
= NetpNtStatusToApiStatus(Status
);
910 /* Open the alias account in the account domain */
911 ApiStatus
= OpenAliasByName(DomainHandle
,
915 if (ApiStatus
!= NERR_Success
)
917 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
918 if (ApiStatus
== ERROR_NONE_MAPPED
)
919 ApiStatus
= NERR_GroupNotFound
;
924 /* Remove members from the alias */
925 for (i
= 0; i
< totalentries
; i
++)
927 Status
= SamRemoveMemberFromAlias(AliasHandle
,
928 MemberList
[i
].lgrmi0_sid
);
929 if (!NT_SUCCESS(Status
))
931 ERR("SamAddMemberToAlias failed (Status %lu)\n", Status
);
932 ApiStatus
= NetpNtStatusToApiStatus(Status
);
938 if (level
== 3 && MemberList
!= NULL
)
940 for (i
= 0; i
< totalentries
; i
++)
942 if (MemberList
[i
].lgrmi0_sid
!= NULL
)
943 NetApiBufferFree(MemberList
[i
].lgrmi0_sid
);
946 NetApiBufferFree(MemberList
);
949 if (AliasHandle
!= NULL
)
950 SamCloseHandle(AliasHandle
);
952 if (DomainHandle
!= NULL
)
953 SamCloseHandle(DomainHandle
);
955 if (ServerHandle
!= NULL
)
956 SamCloseHandle(ServerHandle
);
962 /************************************************************
963 * NetLocalGroupEnum (NETAPI32.@)
973 LPDWORD totalentries
,
974 PDWORD_PTR resumehandle
)
976 UNICODE_STRING ServerName
;
977 PSAM_RID_ENUMERATION CurrentAlias
;
978 PENUM_CONTEXT EnumContext
= NULL
;
980 SAM_HANDLE AliasHandle
= NULL
;
981 PALIAS_GENERAL_INFORMATION AliasInfo
= NULL
;
982 LPVOID Buffer
= NULL
;
983 NET_API_STATUS ApiStatus
= NERR_Success
;
984 NTSTATUS Status
= STATUS_SUCCESS
;
986 TRACE("(%s %d %p %d %p %p %p) stub!\n", debugstr_w(servername
),
987 level
, bufptr
, prefmaxlen
, entriesread
, totalentries
, resumehandle
);
993 if (servername
!= NULL
)
994 RtlInitUnicodeString(&ServerName
, servername
);
996 if (resumehandle
!= NULL
&& *resumehandle
!= 0)
998 EnumContext
= (PENUM_CONTEXT
)*resumehandle
;
1002 ApiStatus
= NetApiBufferAllocate(sizeof(ENUM_CONTEXT
), (PVOID
*)&EnumContext
);
1003 if (ApiStatus
!= NERR_Success
)
1006 EnumContext
->EnumerationContext
= 0;
1007 EnumContext
->Buffer
= NULL
;
1008 EnumContext
->Returned
= 0;
1009 EnumContext
->Index
= 0;
1011 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
1012 &EnumContext
->ServerHandle
,
1013 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
1015 if (!NT_SUCCESS(Status
))
1017 ERR("SamConnect failed (Status %08lx)\n", Status
);
1018 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1022 Status
= OpenAccountDomain(EnumContext
->ServerHandle
,
1023 (servername
!= NULL
) ? &ServerName
: NULL
,
1024 DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
,
1025 &EnumContext
->AccountDomainHandle
);
1026 if (!NT_SUCCESS(Status
))
1028 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
1029 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1033 Status
= OpenBuiltinDomain(EnumContext
->ServerHandle
,
1034 DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
,
1035 &EnumContext
->BuiltinDomainHandle
);
1036 if (!NT_SUCCESS(Status
))
1038 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
1039 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1043 EnumContext
->Phase
= BuiltinPhase
;
1044 EnumContext
->DomainHandle
= EnumContext
->BuiltinDomainHandle
;
1050 TRACE("EnumContext->Index: %lu\n", EnumContext
->Index
);
1051 TRACE("EnumContext->Returned: %lu\n", EnumContext
->Returned
);
1053 if (EnumContext
->Index
>= EnumContext
->Returned
)
1055 TRACE("Calling SamEnumerateAliasesInDomain\n");
1057 Status
= SamEnumerateAliasesInDomain(EnumContext
->DomainHandle
,
1058 &EnumContext
->EnumerationContext
,
1059 (PVOID
*)&EnumContext
->Buffer
,
1061 &EnumContext
->Returned
);
1063 TRACE("SamEnumerateAliasesInDomain returned (Status %08lx)\n", Status
);
1064 if (!NT_SUCCESS(Status
))
1066 ERR("SamEnumerateAliasesInDomain failed (Status %08lx)\n", Status
);
1067 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1071 if (Status
== STATUS_MORE_ENTRIES
)
1073 ApiStatus
= NERR_BufTooSmall
;
1078 TRACE("EnumContext: %lu\n", EnumContext
);
1079 TRACE("EnumContext->Returned: %lu\n", EnumContext
->Returned
);
1080 TRACE("EnumContext->Buffer: %p\n", EnumContext
->Buffer
);
1082 /* Get a pointer to the current alias */
1083 CurrentAlias
= &EnumContext
->Buffer
[EnumContext
->Index
];
1085 TRACE("RID: %lu\n", CurrentAlias
->RelativeId
);
1087 Status
= SamOpenAlias(EnumContext
->DomainHandle
,
1088 ALIAS_READ_INFORMATION
,
1089 CurrentAlias
->RelativeId
,
1091 if (!NT_SUCCESS(Status
))
1093 ERR("SamOpenAlias failed (Status %08lx)\n", Status
);
1094 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1098 Status
= SamQueryInformationAlias(AliasHandle
,
1099 AliasGeneralInformation
,
1100 (PVOID
*)&AliasInfo
);
1101 if (!NT_SUCCESS(Status
))
1103 ERR("SamQueryInformationAlias failed (Status %08lx)\n", Status
);
1104 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1108 SamCloseHandle(AliasHandle
);
1111 TRACE("Name: %S\n", AliasInfo
->Name
.Buffer
);
1112 TRACE("Comment: %S\n", AliasInfo
->AdminComment
.Buffer
);
1114 ApiStatus
= BuildAliasInfoBuffer(AliasInfo
,
1117 if (ApiStatus
!= NERR_Success
)
1120 if (AliasInfo
!= NULL
)
1122 FreeAliasInfo(AliasInfo
);
1126 EnumContext
->Index
++;
1130 if (EnumContext
->Index
== EnumContext
->Returned
)
1132 switch (EnumContext
->Phase
)
1135 EnumContext
->Phase
= AccountPhase
;
1136 EnumContext
->DomainHandle
= EnumContext
->AccountDomainHandle
;
1137 EnumContext
->EnumerationContext
= 0;
1138 EnumContext
->Index
= 0;
1139 EnumContext
->Returned
= 0;
1141 if (EnumContext
->Buffer
!= NULL
)
1143 for (i
= 0; i
< EnumContext
->Returned
; i
++)
1145 SamFreeMemory(EnumContext
->Buffer
[i
].Name
.Buffer
);
1148 SamFreeMemory(EnumContext
->Buffer
);
1149 EnumContext
->Buffer
= NULL
;
1155 EnumContext
->Phase
= DonePhase
;
1162 if (ApiStatus
== NERR_Success
&& EnumContext
->Phase
!= DonePhase
)
1163 ApiStatus
= ERROR_MORE_DATA
;
1165 if (EnumContext
!= NULL
)
1166 *totalentries
= EnumContext
->Returned
;
1168 if (resumehandle
== NULL
|| ApiStatus
!= ERROR_MORE_DATA
)
1170 if (EnumContext
!= NULL
)
1172 if (EnumContext
->BuiltinDomainHandle
!= NULL
)
1173 SamCloseHandle(EnumContext
->BuiltinDomainHandle
);
1175 if (EnumContext
->AccountDomainHandle
!= NULL
)
1176 SamCloseHandle(EnumContext
->AccountDomainHandle
);
1178 if (EnumContext
->ServerHandle
!= NULL
)
1179 SamCloseHandle(EnumContext
->ServerHandle
);
1181 if (EnumContext
->Buffer
!= NULL
)
1183 for (i
= 0; i
< EnumContext
->Returned
; i
++)
1185 SamFreeMemory(EnumContext
->Buffer
[i
].Name
.Buffer
);
1188 SamFreeMemory(EnumContext
->Buffer
);
1191 NetApiBufferFree(EnumContext
);
1196 if (AliasHandle
!= NULL
)
1197 SamCloseHandle(AliasHandle
);
1199 if (AliasInfo
!= NULL
)
1200 FreeAliasInfo(AliasInfo
);
1202 if (resumehandle
!= NULL
)
1203 *resumehandle
= (DWORD_PTR
)EnumContext
;
1205 *bufptr
= (LPBYTE
)Buffer
;
1207 TRACE ("return %lu\n", ApiStatus
);
1213 /************************************************************
1214 * NetLocalGroupGetInfo (NETAPI32.@)
1218 NetLocalGroupGetInfo(
1224 UNICODE_STRING ServerName
;
1225 UNICODE_STRING GroupName
;
1226 SAM_HANDLE ServerHandle
= NULL
;
1227 SAM_HANDLE DomainHandle
= NULL
;
1228 SAM_HANDLE AliasHandle
= NULL
;
1229 PALIAS_GENERAL_INFORMATION AliasInfo
= NULL
;
1230 LPVOID Buffer
= NULL
;
1231 NET_API_STATUS ApiStatus
= NERR_Success
;
1232 NTSTATUS Status
= STATUS_SUCCESS
;
1234 TRACE("(%s %s %d %p) stub!\n", debugstr_w(servername
),
1235 debugstr_w(groupname
), level
, bufptr
);
1237 if (servername
!= NULL
)
1238 RtlInitUnicodeString(&ServerName
, servername
);
1240 RtlInitUnicodeString(&GroupName
, groupname
);
1242 /* Connect to the SAM Server */
1243 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
1245 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
1247 if (!NT_SUCCESS(Status
))
1249 ERR("SamConnect failed (Status %08lx)\n", Status
);
1250 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1254 /* Open the Builtin Domain */
1255 Status
= OpenBuiltinDomain(ServerHandle
,
1258 if (!NT_SUCCESS(Status
))
1260 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
1261 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1265 /* Open the alias account in the builtin domain */
1266 ApiStatus
= OpenAliasByName(DomainHandle
,
1268 ALIAS_READ_INFORMATION
,
1270 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
1272 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
1276 if (AliasHandle
== NULL
)
1278 if (DomainHandle
!= NULL
)
1279 SamCloseHandle(DomainHandle
);
1281 /* Open the Acount Domain */
1282 Status
= OpenAccountDomain(ServerHandle
,
1283 (servername
!= NULL
) ? &ServerName
: NULL
,
1286 if (!NT_SUCCESS(Status
))
1288 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
1289 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1293 /* Open the alias account in the account domain */
1294 ApiStatus
= OpenAliasByName(DomainHandle
,
1296 ALIAS_READ_INFORMATION
,
1298 if (ApiStatus
!= NERR_Success
)
1300 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
1301 if (ApiStatus
== ERROR_NONE_MAPPED
)
1302 ApiStatus
= NERR_GroupNotFound
;
1307 Status
= SamQueryInformationAlias(AliasHandle
,
1308 AliasGeneralInformation
,
1309 (PVOID
*)&AliasInfo
);
1310 if (!NT_SUCCESS(Status
))
1312 ERR("SamQueryInformationAlias failed (Status %08lx)\n", Status
);
1313 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1317 ApiStatus
= BuildAliasInfoBuffer(AliasInfo
,
1320 if (ApiStatus
!= NERR_Success
)
1324 if (AliasInfo
!= NULL
)
1325 FreeAliasInfo(AliasInfo
);
1327 if (AliasHandle
!= NULL
)
1328 SamCloseHandle(AliasHandle
);
1330 if (DomainHandle
!= NULL
)
1331 SamCloseHandle(DomainHandle
);
1333 if (ServerHandle
!= NULL
)
1334 SamCloseHandle(ServerHandle
);
1336 *bufptr
= (LPBYTE
)Buffer
;
1342 /************************************************************
1343 * NetLocalGroupGetMembers (NETAPI32.@)
1347 NetLocalGroupGetMembers(
1349 LPCWSTR localgroupname
,
1353 LPDWORD entriesread
,
1354 LPDWORD totalentries
,
1355 PDWORD_PTR resumehandle
)
1357 OBJECT_ATTRIBUTES ObjectAttributes
;
1358 UNICODE_STRING ServerName
;
1359 UNICODE_STRING AliasName
;
1360 PMEMBER_ENUM_CONTEXT EnumContext
= NULL
;
1361 LPVOID Buffer
= NULL
;
1362 PLOCALGROUP_MEMBERS_INFO_0 MembersInfo0
;
1363 PLOCALGROUP_MEMBERS_INFO_1 MembersInfo1
;
1364 PLOCALGROUP_MEMBERS_INFO_2 MembersInfo2
;
1365 PLOCALGROUP_MEMBERS_INFO_3 MembersInfo3
;
1370 NET_API_STATUS ApiStatus
= NERR_Success
;
1371 NTSTATUS Status
= STATUS_SUCCESS
;
1373 TRACE("(%s %s %d %p %d, %p %p %p)\n", debugstr_w(servername
),
1374 debugstr_w(localgroupname
), level
, bufptr
, prefmaxlen
, entriesread
,
1375 totalentries
, resumehandle
);
1381 if (servername
!= NULL
)
1382 RtlInitUnicodeString(&ServerName
, servername
);
1384 RtlInitUnicodeString(&AliasName
, localgroupname
);
1386 if (resumehandle
!= NULL
&& *resumehandle
!= 0)
1388 EnumContext
= (PMEMBER_ENUM_CONTEXT
)*resumehandle
;
1392 /* Allocate the enumeration context */
1393 ApiStatus
= NetApiBufferAllocate(sizeof(MEMBER_ENUM_CONTEXT
), (PVOID
*)&EnumContext
);
1394 if (ApiStatus
!= NERR_Success
)
1397 /* Connect to the SAM Server */
1398 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
1399 &EnumContext
->ServerHandle
,
1400 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
1402 if (!NT_SUCCESS(Status
))
1404 ERR("SamConnect failed (Status %08lx)\n", Status
);
1405 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1409 /* Open the Builtin Domain */
1410 Status
= OpenBuiltinDomain(EnumContext
->ServerHandle
,
1412 &EnumContext
->DomainHandle
);
1413 if (!NT_SUCCESS(Status
))
1415 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
1416 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1420 /* Open the alias account in the builtin domain */
1421 ApiStatus
= OpenAliasByName(EnumContext
->DomainHandle
,
1424 &EnumContext
->AliasHandle
);
1425 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
1427 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
1431 if (EnumContext
->AliasHandle
== NULL
)
1433 if (EnumContext
->DomainHandle
!= NULL
)
1434 SamCloseHandle(EnumContext
->DomainHandle
);
1436 /* Open the Acount Domain */
1437 Status
= OpenAccountDomain(EnumContext
->ServerHandle
,
1438 (servername
!= NULL
) ? &ServerName
: NULL
,
1440 &EnumContext
->DomainHandle
);
1441 if (!NT_SUCCESS(Status
))
1443 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
1444 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1448 /* Open the alias account in the account domain */
1449 ApiStatus
= OpenAliasByName(EnumContext
->DomainHandle
,
1452 &EnumContext
->AliasHandle
);
1453 if (ApiStatus
!= NERR_Success
)
1455 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
1456 if (ApiStatus
== ERROR_NONE_MAPPED
)
1457 ApiStatus
= NERR_GroupNotFound
;
1462 /* Get the member list */
1463 Status
= SamGetMembersInAlias(EnumContext
->AliasHandle
,
1465 &EnumContext
->Count
);
1466 if (!NT_SUCCESS(Status
))
1468 ERR("SamGetMemberInAlias failed (Status %08lx)\n", Status
);
1469 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1473 if (EnumContext
->Count
== 0)
1475 TRACE("No member found. We're done.\n");
1476 ApiStatus
= NERR_Success
;
1480 /* Get name and domain information for all members */
1483 InitializeObjectAttributes(&ObjectAttributes
,
1489 Status
= LsaOpenPolicy((servername
!= NULL
) ? &ServerName
: NULL
,
1490 (PLSA_OBJECT_ATTRIBUTES
)&ObjectAttributes
,
1492 &EnumContext
->LsaHandle
);
1493 if (!NT_SUCCESS(Status
))
1495 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1499 Status
= LsaLookupSids(EnumContext
->LsaHandle
,
1502 &EnumContext
->Domains
,
1503 &EnumContext
->Names
);
1504 if (!NT_SUCCESS(Status
))
1506 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1512 /* Calculate the required buffer size */
1513 for (i
= 0; i
< EnumContext
->Count
; i
++)
1518 Size
+= sizeof(LOCALGROUP_MEMBERS_INFO_0
) +
1519 RtlLengthSid(EnumContext
->Sids
[i
]);
1523 Size
+= sizeof(LOCALGROUP_MEMBERS_INFO_1
) +
1524 RtlLengthSid(EnumContext
->Sids
[i
]) +
1525 EnumContext
->Names
[i
].Name
.Length
+ sizeof(WCHAR
);
1529 Size
+= sizeof(LOCALGROUP_MEMBERS_INFO_2
) +
1530 RtlLengthSid(EnumContext
->Sids
[i
]) +
1531 EnumContext
->Names
[i
].Name
.Length
+ sizeof(WCHAR
);
1532 if (EnumContext
->Names
[i
].DomainIndex
>= 0)
1533 Size
+= EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Length
+ sizeof(WCHAR
);
1537 Size
+= sizeof(LOCALGROUP_MEMBERS_INFO_3
) +
1538 EnumContext
->Names
[i
].Name
.Length
+ sizeof(WCHAR
);
1539 if (EnumContext
->Names
[i
].DomainIndex
>= 0)
1540 Size
+= EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Length
+ sizeof(WCHAR
);
1544 ApiStatus
= ERROR_INVALID_LEVEL
;
1549 /* Allocate the member buffer */
1550 ApiStatus
= NetApiBufferAllocate(Size
, &Buffer
);
1551 if (ApiStatus
!= NERR_Success
)
1554 ZeroMemory(Buffer
, Size
);
1556 /* Fill the member buffer */
1560 MembersInfo0
= (PLOCALGROUP_MEMBERS_INFO_0
)Buffer
;
1561 Ptr
= (PVOID
)((ULONG_PTR
)Buffer
+ sizeof(LOCALGROUP_MEMBERS_INFO_0
) * EnumContext
->Count
);
1565 MembersInfo1
= (PLOCALGROUP_MEMBERS_INFO_1
)Buffer
;
1566 Ptr
= (PVOID
)((ULONG_PTR
)Buffer
+ sizeof(LOCALGROUP_MEMBERS_INFO_1
) * EnumContext
->Count
);
1570 MembersInfo2
= (PLOCALGROUP_MEMBERS_INFO_2
)Buffer
;
1571 Ptr
= (PVOID
)((ULONG_PTR
)Buffer
+ sizeof(LOCALGROUP_MEMBERS_INFO_2
) * EnumContext
->Count
);
1575 MembersInfo3
= (PLOCALGROUP_MEMBERS_INFO_3
)Buffer
;
1576 Ptr
= (PVOID
)((ULONG_PTR
)Buffer
+ sizeof(LOCALGROUP_MEMBERS_INFO_3
) * EnumContext
->Count
);
1580 for (i
= 0; i
< EnumContext
->Count
; i
++)
1585 MembersInfo0
->lgrmi0_sid
= (PSID
)Ptr
;
1587 SidLength
= RtlLengthSid(EnumContext
->Sids
[i
]);
1588 memcpy(MembersInfo0
->lgrmi0_sid
,
1589 EnumContext
->Sids
[i
],
1591 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ SidLength
);
1596 MembersInfo1
->lgrmi1_sid
= (PSID
)Ptr
;
1598 SidLength
= RtlLengthSid(EnumContext
->Sids
[i
]);
1599 memcpy(MembersInfo1
->lgrmi1_sid
,
1600 EnumContext
->Sids
[i
],
1603 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ SidLength
);
1605 MembersInfo1
->lgrmi1_sidusage
= EnumContext
->Names
[i
].Use
;
1607 TRACE("Name: %S\n", EnumContext
->Names
[i
].Name
.Buffer
);
1609 MembersInfo1
->lgrmi1_name
= (LPWSTR
)Ptr
;
1611 memcpy(MembersInfo1
->lgrmi1_name
,
1612 EnumContext
->Names
[i
].Name
.Buffer
,
1613 EnumContext
->Names
[i
].Name
.Length
);
1614 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ EnumContext
->Names
[i
].Name
.Length
+ sizeof(WCHAR
));
1619 MembersInfo2
->lgrmi2_sid
= (PSID
)Ptr
;
1621 SidLength
= RtlLengthSid(EnumContext
->Sids
[i
]);
1622 memcpy(MembersInfo2
->lgrmi2_sid
,
1623 EnumContext
->Sids
[i
],
1626 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ SidLength
);
1628 MembersInfo2
->lgrmi2_sidusage
= EnumContext
->Names
[i
].Use
;
1630 MembersInfo2
->lgrmi2_domainandname
= (LPWSTR
)Ptr
;
1632 if (EnumContext
->Names
[i
].DomainIndex
>= 0)
1634 memcpy(MembersInfo2
->lgrmi2_domainandname
,
1635 EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Buffer
,
1636 EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Length
);
1638 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Length
);
1640 *((LPWSTR
)Ptr
) = L
'\\';
1642 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ sizeof(WCHAR
));
1646 EnumContext
->Names
[i
].Name
.Buffer
,
1647 EnumContext
->Names
[i
].Name
.Length
);
1648 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ EnumContext
->Names
[i
].Name
.Length
+ sizeof(WCHAR
));
1653 MembersInfo3
->lgrmi3_domainandname
= (PSID
)Ptr
;
1655 if (EnumContext
->Names
[i
].DomainIndex
>= 0)
1657 memcpy(MembersInfo2
->lgrmi2_domainandname
,
1658 EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Buffer
,
1659 EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Length
);
1661 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ EnumContext
->Domains
->Domains
[EnumContext
->Names
[i
].DomainIndex
].Name
.Length
);
1663 *((LPWSTR
)Ptr
) = L
'\\';
1665 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ sizeof(WCHAR
));
1669 EnumContext
->Names
[i
].Name
.Buffer
,
1670 EnumContext
->Names
[i
].Name
.Length
);
1671 Ptr
= (PVOID
)((ULONG_PTR
)Ptr
+ EnumContext
->Names
[i
].Name
.Length
+ sizeof(WCHAR
));
1677 *entriesread
= EnumContext
->Count
;
1679 *bufptr
= (LPBYTE
)Buffer
;
1682 if (EnumContext
!= NULL
)
1683 *totalentries
= EnumContext
->Count
;
1685 if (resumehandle
== NULL
|| ApiStatus
!= ERROR_MORE_DATA
)
1687 /* Release the enumeration context */
1688 if (EnumContext
!= NULL
)
1690 if (EnumContext
->LsaHandle
!= NULL
)
1691 LsaClose(EnumContext
->LsaHandle
);
1693 if (EnumContext
->AliasHandle
!= NULL
)
1694 SamCloseHandle(EnumContext
->AliasHandle
);
1696 if (EnumContext
->DomainHandle
!= NULL
)
1697 SamCloseHandle(EnumContext
->DomainHandle
);
1699 if (EnumContext
->ServerHandle
!= NULL
)
1700 SamCloseHandle(EnumContext
->ServerHandle
);
1702 if (EnumContext
->Sids
!= NULL
)
1703 SamFreeMemory(EnumContext
->Sids
);
1705 if (EnumContext
->Domains
!= NULL
)
1706 LsaFreeMemory(EnumContext
->Domains
);
1708 if (EnumContext
->Names
!= NULL
)
1709 LsaFreeMemory(EnumContext
->Names
);
1711 NetApiBufferFree(EnumContext
);
1720 /************************************************************
1721 * NetLocalGroupSetInfo (NETAPI32.@)
1725 NetLocalGroupSetInfo(
1732 UNICODE_STRING ServerName
;
1733 UNICODE_STRING AliasName
;
1734 SAM_HANDLE ServerHandle
= NULL
;
1735 SAM_HANDLE DomainHandle
= NULL
;
1736 SAM_HANDLE AliasHandle
= NULL
;
1737 ALIAS_NAME_INFORMATION AliasNameInfo
;
1738 ALIAS_ADM_COMMENT_INFORMATION AdminCommentInfo
;
1739 NET_API_STATUS ApiStatus
= NERR_Success
;
1740 NTSTATUS Status
= STATUS_SUCCESS
;
1742 TRACE("(%s %s %d %p %p)\n", debugstr_w(servername
),
1743 debugstr_w(groupname
), level
, buf
, parm_err
);
1745 if (parm_err
!= NULL
)
1746 *parm_err
= PARM_ERROR_NONE
;
1748 if (servername
!= NULL
)
1749 RtlInitUnicodeString(&ServerName
, servername
);
1751 RtlInitUnicodeString(&AliasName
, groupname
);
1753 /* Connect to the SAM Server */
1754 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
1756 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
1758 if (!NT_SUCCESS(Status
))
1760 ERR("SamConnect failed (Status %08lx)\n", Status
);
1761 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1765 /* Open the Builtin Domain */
1766 Status
= OpenBuiltinDomain(ServerHandle
,
1769 if (!NT_SUCCESS(Status
))
1771 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
1772 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1776 /* Open the alias account in the builtin domain */
1777 ApiStatus
= OpenAliasByName(DomainHandle
,
1779 ALIAS_WRITE_ACCOUNT
,
1781 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
1783 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
1787 if (AliasHandle
== NULL
)
1789 if (DomainHandle
!= NULL
)
1790 SamCloseHandle(DomainHandle
);
1792 /* Open the Acount Domain */
1793 Status
= OpenAccountDomain(ServerHandle
,
1794 (servername
!= NULL
) ? &ServerName
: NULL
,
1797 if (!NT_SUCCESS(Status
))
1799 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
1800 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1804 /* Open the alias account in the account domain */
1805 ApiStatus
= OpenAliasByName(DomainHandle
,
1807 ALIAS_WRITE_ACCOUNT
,
1809 if (ApiStatus
!= NERR_Success
)
1811 ERR("OpenAliasByName failed (ApiStatus %lu)\n", ApiStatus
);
1812 if (ApiStatus
== ERROR_NONE_MAPPED
)
1813 ApiStatus
= NERR_GroupNotFound
;
1821 /* Set the alias name */
1822 RtlInitUnicodeString(&AliasNameInfo
.Name
,
1823 ((PLOCALGROUP_INFO_0
)buf
)->lgrpi0_name
);
1825 Status
= SamSetInformationAlias(AliasHandle
,
1826 AliasNameInformation
,
1828 if (!NT_SUCCESS(Status
))
1830 TRACE("SamSetInformationAlias failed (ApiStatus %lu)\n", ApiStatus
);
1831 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1838 /* Set the alias admin comment */
1840 RtlInitUnicodeString(&AdminCommentInfo
.AdminComment
,
1841 ((PLOCALGROUP_INFO_1
)buf
)->lgrpi1_comment
);
1843 RtlInitUnicodeString(&AdminCommentInfo
.AdminComment
,
1844 ((PLOCALGROUP_INFO_1002
)buf
)->lgrpi1002_comment
);
1846 Status
= SamSetInformationAlias(AliasHandle
,
1847 AliasAdminCommentInformation
,
1849 if (!NT_SUCCESS(Status
))
1851 TRACE("SamSetInformationAlias failed (ApiStatus %lu)\n", ApiStatus
);
1852 ApiStatus
= NetpNtStatusToApiStatus(Status
);
1858 ApiStatus
= ERROR_INVALID_LEVEL
;
1863 if (AliasHandle
!= NULL
)
1864 SamCloseHandle(AliasHandle
);
1866 if (DomainHandle
!= NULL
)
1867 SamCloseHandle(DomainHandle
);
1869 if (ServerHandle
!= NULL
)
1870 SamCloseHandle(ServerHandle
);
1876 /************************************************************
1877 * NetLocalGroupSetMember (NETAPI32.@)
1879 NET_API_STATUS WINAPI
NetLocalGroupSetMembers(
1886 FIXME("(%s %s %d %p %d) stub!\n", debugstr_w(servername
),
1887 debugstr_w(groupname
), level
, buf
, totalentries
);
1888 return NERR_Success
;