4 samr interface definition
8 Thanks to Todd Sabin for some information from his samr.idl in acltools
11 [ uuid(12345778-1234-abcd-ef00-0123456789ac),
13 pointer_default(unique)
18 NTSTATUS samr_Connect (
19 /* notice the lack of [string] */
20 [in] uint16 *system_name,
21 [in] uint32 access_mask,
22 [out,ref] policy_handle *handle
29 [in,out,ref] policy_handle *handle
36 [value(ndr_size_security_descriptor(r->sd))] uint32 sd_size;
37 [subcontext(4)] security_descriptor *sd;
40 NTSTATUS samr_SetSecurity (
41 [in,ref] policy_handle *handle,
43 [in,ref] samr_SdBuf *sdbuf
49 NTSTATUS samr_QuerySecurity (
50 [in,ref] policy_handle *handle,
52 [out] samr_SdBuf *sdbuf
59 shutdown the SAM - once you call this the SAM will be dead
61 NTSTATUS samr_Shutdown (
62 [in,ref] policy_handle *handle
68 [value(2*strlen_m(r->name))] uint16 name_len;
69 [value(r->name_len)] uint16 name_size;
73 NTSTATUS samr_LookupDomain (
74 [in,ref] policy_handle *handle,
75 [in,ref] samr_Name *domain,
90 [size_is(count)] samr_SamEntry *entries;
93 NTSTATUS samr_EnumDomains (
94 [in,ref] policy_handle *handle,
95 [in,out,ref] uint32 *resume_handle,
97 [out] samr_SamArray *sam,
98 [out] uint32 num_entries
102 /************************/
104 NTSTATUS samr_OpenDomain(
105 [in,ref] policy_handle *handle,
106 [in] uint32 access_mask,
107 [in,ref] dom_sid2 *sid,
108 [out,ref] policy_handle *domain_handle
111 /************************/
116 uint16 password_history;
117 uint32 password_properties;
118 ULONG8 max_password_age;
119 ULONG8 min_password_age;
123 ULONG8 force_logoff_time;
125 samr_Name domain; /* domain name */
126 samr_Name primary; /* PDC name if this is a BDC */
127 HYPER_T sequence_num;
137 ULONG8 force_logoff_time;
141 /* I'm not entirely sure this is a comment. win2003
142 allows it to be set, and it seems harmless (like a
143 comment) but I haven't seen it show up anywhere */
160 HYPER_T sequence_num;
161 NTTIME last_xxx_time;
165 uint32 unknown; /* w2k3 returns 1 */
169 ULONG8 force_logoff_time;
173 HYPER_T sequence_num;
174 uint32 unknown2; /* w2k3 returns 1 */
176 uint32 unknown3; /* w2k3 returns 1 */
180 HYPER_T lockout_duration;
181 HYPER_T lockout_window;
182 uint16 lockout_threshold;
186 HYPER_T lockout_duration;
187 HYPER_T lockout_window;
188 uint16 lockout_threshold;
192 HYPER_T sequence_num;
193 NTTIME last_xxx_time;
199 [case(1)] samr_DomInfo1 info1;
200 [case(2)] samr_DomInfo2 info2;
201 [case(3)] samr_DomInfo3 info3;
202 [case(4)] samr_DomInfo4 info4;
203 [case(5)] samr_DomInfo5 info5;
204 [case(6)] samr_DomInfo6 info6;
205 [case(7)] samr_DomInfo7 info7;
206 [case(8)] samr_DomInfo8 info8;
207 [case(9)] samr_DomInfo9 info9;
208 [case(11)] samr_DomInfo11 info11;
209 [case(12)] samr_DomInfo12 info12;
210 [case(13)] samr_DomInfo13 info13;
213 NTSTATUS samr_QueryDomainInfo(
214 [in,ref] policy_handle *handle,
216 [out,switch_is(level)] samr_DomainInfo *info
219 /************************/
222 only levels 1, 3, 4, 6, 7, 9, 12 are valid for this
225 NTSTATUS samr_SetDomainInfo(
226 [in,ref] policy_handle *handle,
228 [in,switch_is(level),ref] samr_DomainInfo *info
232 /************************/
234 NTSTATUS samr_CreateDomainGroup(
235 [in,ref] policy_handle *handle,
236 [in,ref] samr_Name *name,
237 [in] uint32 access_mask,
238 [out,ref] policy_handle *group_handle,
239 [out,ref] uint32 *rid
243 /************************/
245 NTSTATUS samr_EnumDomainGroups(
246 [in,ref] policy_handle *handle,
247 [in,out,ref] uint32 *resume_handle,
248 [in] uint32 max_size,
249 [out] samr_SamArray *sam,
250 [out] uint32 num_entries
253 /************************/
255 NTSTATUS samr_CreateUser(
256 [in,ref] policy_handle *handle,
257 [in,ref] samr_Name *username,
258 [in] uint32 access_mask,
259 [out,ref] policy_handle *acct_handle,
260 [out,ref] uint32 *rid
263 /************************/
265 NTSTATUS samr_EnumDomainUsers(
266 [in,ref] policy_handle *handle,
267 [in,out,ref] uint32 *resume_handle,
268 [in] uint32 acct_flags,
269 [in] uint32 max_size,
270 [out] samr_SamArray *sam,
271 [out] uint32 num_entries
274 /************************/
276 NTSTATUS samr_CreateDomAlias(
277 [in,ref] policy_handle *handle,
278 [in,ref] samr_Name *aliasname,
279 [in] uint32 access_mask,
280 [out,ref] policy_handle *acct_handle,
281 [out,ref] uint32 *rid
284 /************************/
286 NTSTATUS samr_EnumDomainAliases(
287 [in,ref] policy_handle *handle,
288 [in,out,ref] uint32 *resume_handle,
289 [in] uint32 max_size,
290 [out] samr_SamArray *sam,
291 [out] uint32 num_entries
294 /************************/
299 [size_is(count)] uint32 *ids;
302 NTSTATUS samr_GetAliasMembership(
303 [in,ref] policy_handle *handle,
304 [in,ref] lsa_SidArray *sids,
308 /************************/
311 NTSTATUS samr_LookupNames(
312 [in,ref] policy_handle *handle,
313 [in] uint32 num_names,
314 [in,ref,size_is(1000),length_is(num_names)] samr_Name *names,
320 /************************/
325 [size_is(count)] samr_Name *names;
328 NTSTATUS samr_LookupRids(
329 [in,ref] policy_handle *handle,
330 [in] uint32 num_rids,
331 [in,ref,size_is(1000),length_is(num_rids)] uint32 *rids,
332 [out] samr_Names names,
336 /************************/
338 NTSTATUS samr_OpenGroup(
339 [in,ref] policy_handle *handle,
340 [in] uint32 access_mask,
342 [out,ref] policy_handle *acct_handle
346 /************************/
353 samr_Name description;
361 samr_Name description;
362 } samr_GroupInfoDesciption;
372 [case(GroupInfoAll)] samr_GroupInfoAll all;
373 [case(GroupInfoName)] samr_Name name;
374 [case(GroupInfoX)] samr_GroupInfoX unknown;
375 [case(GroupInfoDescription)] samr_Name description;
378 NTSTATUS samr_QueryGroupInfo(
379 [in,ref] policy_handle *handle,
381 [out,switch_is(level)] samr_GroupInfo *info
384 /************************/
386 NTSTATUS samr_SetGroupInfo(
387 [in,ref] policy_handle *handle,
389 [in,switch_is(level),ref] samr_GroupInfo *info
392 /************************/
394 NTSTATUS samr_AddGroupMember(
395 [in,ref] policy_handle *handle,
400 /************************/
402 NTSTATUS samr_DeleteDomainGroup(
403 [in,out,ref] policy_handle *handle
406 /************************/
408 NTSTATUS samr_DeleteGroupMember(
409 [in,ref] policy_handle *handle,
414 /************************/
417 this isn't really valid IDL, but it does work. I suspect
418 I need to do some more pidl work to get this really right
427 samr_intArray *unknown7;
430 NTSTATUS samr_QueryGroupMember(
431 [in,ref] policy_handle *handle,
433 [out] samr_ridArray rids
437 /************************/
441 win2003 seems to accept any data at all for the two integers
442 below, and doesn't seem to do anything with them that I can
443 see. Weird. I really expected the first integer to be a rid
444 and the second to be the attributes for that rid member.
446 NTSTATUS samr_SetMemberAttributesOfGroup(
447 [in,ref] policy_handle *handle,
448 [in] uint32 unknown1,
453 /************************/
455 NTSTATUS samr_OpenAlias (
456 [in,ref] policy_handle *handle,
457 [in] uint32 access_mask,
459 [out,ref] policy_handle *acct_handle
463 /************************/
469 samr_Name description;
473 [case(1)] samr_AliasInfoAll all;
474 [case(2)] samr_Name name;
475 [case(3)] samr_Name description;
478 NTSTATUS samr_QueryAliasInfo(
479 [in,ref] policy_handle *handle,
481 [out,switch_is(level)] samr_AliasInfo *info
484 /************************/
486 NTSTATUS samr_SetAliasInfo(
487 [in,ref] policy_handle *handle,
489 [in,switch_is(level)] samr_AliasInfo info
492 /************************/
494 NTSTATUS samr_DeleteDomAlias(
495 [in,out,ref] policy_handle *handle
498 /************************/
500 NTSTATUS samr_AddAliasMember(
501 [in,ref] policy_handle *handle,
502 [in,ref] dom_sid2 *sid
505 /************************/
507 NTSTATUS samr_DeleteAliasMember(
508 [in,ref] policy_handle *handle,
509 [in,ref] dom_sid2 *sid
512 /************************/
514 NTSTATUS samr_GetMembersInAlias(
515 [in,ref] policy_handle *handle,
516 [out,ref] lsa_SidArray *sids
519 /************************/
521 NTSTATUS samr_OpenUser(
522 [in,ref] policy_handle *handle,
523 [in] uint32 access_mask,
525 [out,ref] policy_handle *acct_handle
528 /************************/
530 NTSTATUS samr_DeleteUser(
531 [in,out,ref] policy_handle *handle
534 /************************/
540 samr_Name description;
546 samr_Name unknown; /* settable, but doesn't stick. probably obsolete */
556 samr_Name home_directory;
557 samr_Name home_drive;
558 samr_Name logon_script;
560 samr_Name workstations;
563 NTTIME last_pwd_change;
564 NTTIME allow_pwd_change;
565 NTTIME force_pwd_change;
566 samr_LogonHours logon_hours;
567 uint16 bad_pwd_count;
573 samr_LogonHours logon_hours;
581 samr_Name home_directory;
582 samr_Name home_drive;
583 samr_Name logon_script;
585 samr_Name description;
586 samr_Name workstations;
589 samr_LogonHours logon_hours;
590 uint16 bad_pwd_count;
592 NTTIME last_pwd_change;
616 samr_Name home_drive;
620 samr_Name logon_script;
628 samr_Name description;
632 samr_Name workstations;
647 /* this defines the bits used for fields_present in info21 */
648 const int SAMR_FIELD_NAME = 0x00000002;
649 const int SAMR_FIELD_DESCRIPTION = 0x00000010;
650 const int SAMR_FIELD_COMMENT = 0x00000020;
651 const int SAMR_FIELD_LOGON_SCRIPT = 0x00000100;
652 const int SAMR_FIELD_PROFILE = 0x00000200;
653 const int SAMR_FIELD_WORKSTATION = 0x00000400;
654 const int SAMR_FIELD_LOGON_HOURS = 0x00002000;
655 const int SAMR_FIELD_CALLBACK = 0x00200000;
656 const int SAMR_FIELD_COUNTRY_CODE = 0x00400000;
657 const int SAMR_FIELD_CODE_PAGE = 0x00800000;
658 const int SAMR_FIELD_PASSWORD = 0x03000000; /* 2 bits!? */
663 NTTIME last_pwd_change;
665 NTTIME allow_pwd_change;
666 NTTIME force_pwd_change;
670 samr_Name home_drive;
671 samr_Name logon_script;
673 samr_Name description;
674 samr_Name workstations;
681 [size_is(buf_count)] uint8 *buffer;
685 uint32 fields_present;
686 samr_LogonHours logon_hours;
687 uint16 bad_pwd_count;
697 typedef [flag(NDR_PAHEX)] struct {
699 } samr_CryptPassword;
702 samr_UserInfo21 info;
703 samr_CryptPassword password;
707 samr_CryptPassword password;
711 typedef [flag(NDR_PAHEX)] struct {
713 } samr_CryptPasswordEx;
716 samr_UserInfo21 info;
717 samr_CryptPasswordEx password;
721 samr_CryptPasswordEx password;
726 [case(1)] samr_UserInfo1 info1;
727 [case(2)] samr_UserInfo2 info2;
728 [case(3)] samr_UserInfo3 info3;
729 [case(4)] samr_UserInfo4 info4;
730 [case(5)] samr_UserInfo5 info5;
731 [case(6)] samr_UserInfo6 info6;
732 [case(7)] samr_UserInfo7 info7;
733 [case(8)] samr_UserInfo8 info8;
734 [case(9)] samr_UserInfo9 info9;
735 [case(10)] samr_UserInfo10 info10;
736 [case(11)] samr_UserInfo11 info11;
737 [case(12)] samr_UserInfo12 info12;
738 [case(13)] samr_UserInfo13 info13;
739 [case(14)] samr_UserInfo14 info14;
740 [case(16)] samr_UserInfo16 info16;
741 [case(17)] samr_UserInfo17 info17;
742 [case(20)] samr_UserInfo20 info20;
743 [case(21)] samr_UserInfo21 info21;
744 [case(23)] samr_UserInfo23 info23;
745 [case(24)] samr_UserInfo24 info24;
746 [case(25)] samr_UserInfo25 info25;
747 [case(26)] samr_UserInfo26 info26;
750 NTSTATUS samr_QueryUserInfo(
751 [in,ref] policy_handle *handle,
753 [out,switch_is(level)] samr_UserInfo *info
757 /************************/
759 NTSTATUS samr_SetUserInfo(
760 [in,ref] policy_handle *handle,
762 [in,ref,switch_is(level)] samr_UserInfo *info
765 /************************/
768 typedef [flag(NDR_PAHEX)] struct {
773 this is a password change interface that doesn't give
774 the server the plaintext password. Depricated.
776 NTSTATUS samr_ChangePasswordUser(
777 [in,ref] policy_handle *handle,
778 [in] bool8 lm_present,
779 [in] samr_Hash *old_lm_crypted,
780 [in] samr_Hash *new_lm_crypted,
781 [in] bool8 nt_present,
782 [in] samr_Hash *old_nt_crypted,
783 [in] samr_Hash *new_nt_crypted,
784 [in] bool8 cross1_present,
785 [in] samr_Hash *nt_cross,
786 [in] bool8 cross2_present,
787 [in] samr_Hash *lm_cross
790 /************************/
800 [size_is(count)] samr_RidType *rid;
803 NTSTATUS samr_GetGroupsForUser(
804 [in,ref] policy_handle *handle,
805 [out] samr_RidArray *rids
808 /************************/
815 samr_Name account_name;
817 samr_Name description;
818 } samr_DispEntryGeneral;
822 [size_is(count)] samr_DispEntryGeneral *entries;
823 } samr_DispInfoGeneral;
829 samr_Name account_name;
830 samr_Name description;
831 } samr_DispEntryFull;
835 [size_is(count)] samr_DispEntryFull *entries;
839 [value(strlen_m(r->name))] uint16 name_len;
840 [value(strlen_m(r->name))] uint16 name_size;
846 samr_AsciiName account_name;
847 } samr_DispEntryAscii;
851 [size_is(count)] samr_DispEntryAscii *entries;
852 } samr_DispInfoAscii;
855 [case(1)] samr_DispInfoGeneral info1;/* users */
856 [case(2)] samr_DispInfoFull info2; /* trust accounts? */
857 [case(3)] samr_DispInfoFull info3; /* groups */
858 [case(4)] samr_DispInfoAscii info4; /* users */
859 [case(5)] samr_DispInfoAscii info5; /* groups */
862 NTSTATUS samr_QueryDisplayInfo(
863 [in,ref] policy_handle *handle,
865 [in] uint32 start_idx,
866 [in] uint32 max_entries,
867 [in] uint32 buf_size,
868 [out] uint32 total_size,
869 [out] uint32 returned_size,
870 [out,switch_is(level)] samr_DispInfo info
874 /************************/
878 this seems to be an alphabetic search function. The returned index
879 is the index for samr_QueryDisplayInfo needed to get names occurring
880 after the specified name. The supplied name does not need to exist
881 in the database (for example you can supply just a first letter for
882 searching starting at that letter)
884 The level corresponds to the samr_QueryDisplayInfo level
886 NTSTATUS samr_GetDisplayEnumerationIndex(
887 [in,ref] policy_handle *handle,
895 /************************/
899 w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this
901 NTSTATUS samr_TestPrivateFunctionsDomain(
902 [in,ref] policy_handle *handle
906 /************************/
910 w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this
912 NTSTATUS samr_TestPrivateFunctionsUser(
913 [in,ref] policy_handle *handle
917 /************************/
920 /* password properties flags */
921 const uint32 DOMAIN_PASSWORD_COMPLEX = 0x00000001;
922 const uint32 DOMAIN_PASSWORD_NO_ANON_CHANGE = 0x00000002;
923 const uint32 DOMAIN_PASSWORD_NO_CLEAR_CHANGE = 0x00000004;
924 const uint32 DOMAIN_PASSWORD_STORE_CLEARTEXT = 0x00000010;
925 const uint32 DOMAIN_REFUSE_PASSWORD_CHANGE = 0x00000020;
929 uint32 password_properties;
932 NTSTATUS samr_GetUserPwInfo(
933 [in,ref] policy_handle *handle,
934 [out] samr_PwInfo info
937 /************************/
939 NTSTATUS samr_RemoveMemberFromForeignDomain(
940 [in,ref] policy_handle *handle,
941 [in,ref] dom_sid2 *sid
944 /************************/
948 how is this different from QueryDomainInfo ??
950 NTSTATUS samr_QueryDomainInfo2(
951 [in,ref] policy_handle *handle,
953 [out,switch_is(level)] samr_DomainInfo *info
956 /************************/
960 how is this different from QueryUserInfo ??
962 NTSTATUS samr_QueryUserInfo2(
963 [in,ref] policy_handle *handle,
965 [out,switch_is(level)] samr_UserInfo *info
968 /************************/
972 how is this different from QueryDisplayInfo??
974 NTSTATUS samr_QueryDisplayInfo2(
975 [in,ref] policy_handle *handle,
977 [in] uint32 start_idx,
978 [in] uint32 max_entries,
979 [in] uint32 buf_size,
980 [out] uint32 total_size,
981 [out] uint32 returned_size,
982 [out,switch_is(level)] samr_DispInfo info
985 /************************/
989 how is this different from GetDisplayEnumerationIndex ??
991 NTSTATUS samr_GetDisplayEnumerationIndex2(
992 [in,ref] policy_handle *handle,
999 /************************/
1001 NTSTATUS samr_CreateUser2(
1002 [in,ref] policy_handle *handle,
1003 [in,ref] samr_Name *username,
1004 [in] uint32 acct_flags,
1005 [in] uint32 access_mask,
1006 [out,ref] policy_handle *acct_handle,
1007 [out,ref] uint32 *access_granted,
1008 [out,ref] uint32 *rid
1012 /************************/
1016 another duplicate. There must be a reason ....
1018 NTSTATUS samr_QueryDisplayInfo3(
1019 [in,ref] policy_handle *handle,
1021 [in] uint32 start_idx,
1022 [in] uint32 max_entries,
1023 [in] uint32 buf_size,
1024 [out] uint32 total_size,
1025 [out] uint32 returned_size,
1026 [out,switch_is(level)] samr_DispInfo info
1029 /************************/
1031 NTSTATUS samr_AddMultipleMembersToAlias(
1032 [in,ref] policy_handle *handle,
1033 [in,ref] lsa_SidArray *sids
1036 /************************/
1038 NTSTATUS samr_RemoveMultipleMembersFromAlias(
1039 [in,ref] policy_handle *handle,
1040 [in,ref] lsa_SidArray *sids
1043 /************************/
1046 NTSTATUS samr_OemChangePasswordUser2(
1047 [in] samr_AsciiName *server,
1048 [in,ref] samr_AsciiName *account,
1049 [in] samr_CryptPassword *password,
1050 [in] samr_Hash *hash
1053 /************************/
1055 NTSTATUS samr_ChangePasswordUser2(
1056 [in] samr_Name *server,
1057 [in,ref] samr_Name *account,
1058 [in] samr_CryptPassword *nt_password,
1059 [in] samr_Hash *nt_verifier,
1060 [in] bool8 lm_change,
1061 [in] samr_CryptPassword *lm_password,
1062 [in] samr_Hash *lm_verifier
1065 /************************/
1067 NTSTATUS samr_GetDomPwInfo(
1068 [in] samr_Name *name,
1069 [out] samr_PwInfo info
1072 /************************/
1074 NTSTATUS samr_Connect2(
1075 [in] unistr *system_name,
1076 [in] uint32 access_mask,
1077 [out,ref] policy_handle *handle
1080 /************************/
1083 seems to be an exact alias for samr_SetUserInfo()
1085 NTSTATUS samr_SetUserInfo2(
1086 [in,ref] policy_handle *handle,
1088 [in,ref,switch_is(level)] samr_UserInfo *info
1091 /************************/
1094 this one is mysterious. I have a few guesses, but nothing working yet
1096 NTSTATUS samr_SetBootKeyInformation(
1097 [in,ref] policy_handle *handle,
1098 [in] uint32 unknown1,
1099 [in] uint32 unknown2,
1100 [in] uint32 unknown3
1103 /************************/
1105 NTSTATUS samr_GetBootKeyInformation(
1106 [in,ref] policy_handle *handle,
1107 [out] uint32 unknown
1110 /************************/
1112 NTSTATUS samr_Connect3(
1113 [in] unistr *system_name,
1114 /* this unknown value seems to be completely ignored by w2k3 */
1115 [in] uint32 unknown,
1116 [in] uint32 access_mask,
1117 [out,ref] policy_handle *handle
1120 /************************/
1122 NTSTATUS samr_Connect4(
1123 [in] unistr *system_name,
1124 [in] uint32 unknown,
1125 [in] uint32 access_mask,
1126 [out,ref] policy_handle *handle
1129 /************************/
1136 } samr_ChangeReject;
1138 NTSTATUS samr_ChangePasswordUser3(
1139 [in] samr_Name *server,
1140 [in,ref] samr_Name *account,
1141 [in] samr_CryptPassword *nt_password,
1142 [in] samr_Hash *nt_verifier,
1143 [in] bool8 lm_change,
1144 [in] samr_CryptPassword *lm_password,
1145 [in] samr_Hash *lm_verifier,
1146 [in] samr_CryptPassword *password3,
1147 [out] samr_DomInfo1 *dominfo,
1148 [out] samr_ChangeReject *reject
1151 /************************/
1155 uint32 unknown1; /* w2k3 gives 3 */
1156 uint32 unknown2; /* w2k3 gives 0 */
1157 } samr_ConnectInfo1;
1160 [case(1)] samr_ConnectInfo1 info1;
1163 NTSTATUS samr_Connect5(
1164 [in] unistr *system_name,
1165 [in] uint32 access_mask,
1166 [in,out] uint32 level,
1167 [in,out,switch_is(level),ref] samr_ConnectInfo *info,
1168 [out,ref] policy_handle *handle
1171 /************************/
1173 NTSTATUS samr_RidToSid(
1174 [in,ref] policy_handle *handle,
1180 /************************/
1184 this should set the DSRM password for the server, which is used
1185 when booting into Directory Services Recovery Mode on a DC. Win2003
1186 gives me NT_STATUS_NOT_SUPPORTED
1189 NTSTATUS samr_SetDsrmPassword(
1190 [in] samr_Name *name,
1191 [in] uint32 unknown,
1192 [in] samr_Hash *hash
1196 /************************/
1199 I haven't been able to work out the format of this one yet.
1200 Seems to start with a switch level for a union?
1202 NTSTATUS samr_ValidatePassword();