s3:winbind: Do not drop the first user in sam_query_user_list
[Samba/aatanasov.git] / source3 / winbindd / winbindd_passdb.c
blob5a2c31fe2f91f17a8d37642c768639dc3c207a6f
1 /*
2 Unix SMB/CIFS implementation.
4 Winbind rpc backend functions
6 Copyright (C) Tim Potter 2000-2001,2003
7 Copyright (C) Simo Sorce 2003
8 Copyright (C) Volker Lendecke 2004
9 Copyright (C) Jeremy Allison 2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "includes.h"
26 #include "winbindd.h"
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_WINBIND
31 static NTSTATUS enum_groups_internal(struct winbindd_domain *domain,
32 TALLOC_CTX *mem_ctx,
33 uint32 *num_entries,
34 struct acct_info **info,
35 enum lsa_SidType sidtype)
37 struct pdb_search *search;
38 struct samr_displayentry *entries;
39 int i;
40 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
42 if (sidtype == SID_NAME_ALIAS) {
43 search = pdb_search_aliases(talloc_tos(), &domain->sid);
44 } else {
45 search = pdb_search_groups(talloc_tos());
48 if (search == NULL) goto done;
50 *num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
51 if (*num_entries == 0) {
52 /* Zero entries isn't an error */
53 result = NT_STATUS_OK;
54 goto done;
57 *info = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_entries);
58 if (*info == NULL) {
59 result = NT_STATUS_NO_MEMORY;
60 goto done;
63 for (i=0; i<*num_entries; i++) {
64 fstrcpy((*info)[i].acct_name, entries[i].account_name);
65 fstrcpy((*info)[i].acct_desc, entries[i].description);
66 (*info)[i].rid = entries[i].rid;
69 result = NT_STATUS_OK;
70 done:
71 TALLOC_FREE(search);
72 return result;
75 /* List all local groups (aliases) */
76 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
77 TALLOC_CTX *mem_ctx,
78 uint32 *num_entries,
79 struct acct_info **info)
81 return enum_groups_internal(domain,
82 mem_ctx,
83 num_entries,
84 info,
85 SID_NAME_ALIAS);
88 /* convert a single name to a sid in a domain */
89 static NTSTATUS name_to_sid(struct winbindd_domain *domain,
90 TALLOC_CTX *mem_ctx,
91 const char *domain_name,
92 const char *name,
93 uint32_t flags,
94 DOM_SID *sid,
95 enum lsa_SidType *type)
97 const char *fullname;
99 flags |= LOOKUP_NAME_ALL;
101 if (domain_name && domain_name[0] && strchr_m(name, '\\') == NULL) {
102 fullname = talloc_asprintf(mem_ctx, "%s\\%s",
103 domain_name, name);
104 if (fullname == NULL) {
105 return NT_STATUS_NO_MEMORY;
107 } else {
108 fullname = name;
111 DEBUG(10, ("Finding fullname %s\n", fullname));
113 if ( !lookup_name( mem_ctx, fullname, flags, NULL, NULL, sid, type ) ) {
114 return NT_STATUS_NONE_MAPPED;
117 DEBUG(10, ("name_to_sid for %s returned %s (%s)\n",
118 fullname,
119 sid_string_dbg(sid),
120 sid_type_lookup((uint32)*type)));
122 return NT_STATUS_OK;
126 convert a domain SID to a user or group name
128 static NTSTATUS sid_to_name(struct winbindd_domain *domain,
129 TALLOC_CTX *mem_ctx,
130 const DOM_SID *sid,
131 char **domain_name,
132 char **name,
133 enum lsa_SidType *type)
135 const char *dom, *nam;
137 DEBUG(10, ("Converting SID %s\n", sid_string_dbg(sid)));
139 /* Paranoia check */
140 if (!sid_check_is_in_builtin(sid) &&
141 !sid_check_is_in_our_domain(sid) &&
142 !sid_check_is_in_unix_users(sid) &&
143 !sid_check_is_unix_users(sid) &&
144 !sid_check_is_in_unix_groups(sid) &&
145 !sid_check_is_unix_groups(sid) &&
146 !sid_check_is_in_wellknown_domain(sid))
148 DEBUG(0, ("Possible deadlock: Trying to lookup SID %s with "
149 "passdb backend\n", sid_string_dbg(sid)));
150 return NT_STATUS_NONE_MAPPED;
153 if (!lookup_sid(mem_ctx, sid, &dom, &nam, type)) {
154 return NT_STATUS_NONE_MAPPED;
157 *domain_name = talloc_strdup(mem_ctx, dom);
158 *name = talloc_strdup(mem_ctx, nam);
160 return NT_STATUS_OK;
163 static NTSTATUS rids_to_names(struct winbindd_domain *domain,
164 TALLOC_CTX *mem_ctx,
165 const DOM_SID *sid,
166 uint32 *rids,
167 size_t num_rids,
168 char **domain_name,
169 char ***names,
170 enum lsa_SidType **types)
172 size_t i;
173 bool have_mapped;
174 bool have_unmapped;
176 *domain_name = NULL;
177 *names = NULL;
178 *types = NULL;
180 if (!num_rids) {
181 return NT_STATUS_OK;
184 /* Paranoia check */
185 if (!sid_check_is_in_builtin(sid) &&
186 !sid_check_is_in_our_domain(sid) &&
187 !sid_check_is_in_unix_users(sid) &&
188 !sid_check_is_unix_users(sid) &&
189 !sid_check_is_in_unix_groups(sid) &&
190 !sid_check_is_unix_groups(sid) &&
191 !sid_check_is_in_wellknown_domain(sid))
193 DEBUG(0, ("Possible deadlock: Trying to lookup SID %s with "
194 "passdb backend\n", sid_string_dbg(sid)));
195 return NT_STATUS_NONE_MAPPED;
198 *names = TALLOC_ARRAY(mem_ctx, char *, num_rids);
199 *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
201 if ((*names == NULL) || (*types == NULL)) {
202 return NT_STATUS_NO_MEMORY;
205 have_mapped = have_unmapped = false;
207 for (i=0; i<num_rids; i++) {
208 DOM_SID lsid;
209 const char *dom = NULL, *nam = NULL;
210 enum lsa_SidType type = SID_NAME_UNKNOWN;
212 if (!sid_compose(&lsid, sid, rids[i])) {
213 return NT_STATUS_INTERNAL_ERROR;
216 if (!lookup_sid(mem_ctx, &lsid, &dom, &nam, &type)) {
217 have_unmapped = true;
218 (*types)[i] = SID_NAME_UNKNOWN;
219 (*names)[i] = talloc_strdup(mem_ctx, "");
220 } else {
221 have_mapped = true;
222 (*types)[i] = type;
223 (*names)[i] = CONST_DISCARD(char *, nam);
226 if (*domain_name == NULL) {
227 *domain_name = CONST_DISCARD(char *, dom);
228 } else {
229 char *dname = CONST_DISCARD(char *, dom);
230 TALLOC_FREE(dname);
234 if (!have_mapped) {
235 return NT_STATUS_NONE_MAPPED;
237 if (!have_unmapped) {
238 return NT_STATUS_OK;
240 return STATUS_SOME_UNMAPPED;
243 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
244 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
245 TALLOC_CTX *mem_ctx,
246 const DOM_SID *user_sid,
247 uint32 *num_groups, DOM_SID **user_gids)
249 NTSTATUS result;
250 DOM_SID *groups = NULL;
251 gid_t *gids = NULL;
252 size_t ngroups = 0;
253 struct samu *user;
255 if ( (user = samu_new(mem_ctx)) == NULL ) {
256 return NT_STATUS_NO_MEMORY;
259 if ( !pdb_getsampwsid( user, user_sid ) ) {
260 TALLOC_FREE( user );
261 return NT_STATUS_NO_SUCH_USER;
264 result = pdb_enum_group_memberships( mem_ctx, user, &groups, &gids, &ngroups );
266 TALLOC_FREE( user );
268 *num_groups = (uint32)ngroups;
269 *user_gids = groups;
271 return result;
274 static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
275 TALLOC_CTX *mem_ctx,
276 uint32 num_sids, const DOM_SID *sids,
277 uint32 *p_num_aliases, uint32 **rids)
279 NTSTATUS result;
280 size_t num_aliases = 0;
282 result = pdb_enum_alias_memberships(mem_ctx, &domain->sid,
283 sids, num_sids, rids, &num_aliases);
285 *p_num_aliases = num_aliases;
286 return result;
289 /* find the sequence number for a domain */
290 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
292 bool result;
293 time_t seq_num;
295 result = pdb_get_seq_num(&seq_num);
296 if (!result) {
297 *seq = 1;
300 *seq = (int) seq_num;
301 /* *seq = 1; */
302 return NT_STATUS_OK;
305 static NTSTATUS lockout_policy(struct winbindd_domain *domain,
306 TALLOC_CTX *mem_ctx,
307 struct samr_DomInfo12 *policy)
309 /* actually we have that */
310 return NT_STATUS_NOT_IMPLEMENTED;
313 static NTSTATUS password_policy(struct winbindd_domain *domain,
314 TALLOC_CTX *mem_ctx,
315 struct samr_DomInfo1 *policy)
317 struct samr_DomInfo1 *p;
318 time_t u_expire, u_min_age;
319 uint32 account_policy_temp;
321 if ((p = TALLOC_ZERO_P(mem_ctx, struct samr_DomInfo1)) == NULL) {
322 return NT_STATUS_NO_MEMORY;
325 if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
326 &account_policy_temp)) {
327 return NT_STATUS_ACCESS_DENIED;
329 p->min_password_length = account_policy_temp;
331 if (!pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY,
332 &account_policy_temp)) {
333 return NT_STATUS_ACCESS_DENIED;
335 p->password_history_length = account_policy_temp;
337 if (!pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
338 &p->password_properties)) {
339 return NT_STATUS_ACCESS_DENIED;
342 if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp)) {
343 return NT_STATUS_ACCESS_DENIED;
345 u_expire = account_policy_temp;
347 if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp)) {
348 return NT_STATUS_ACCESS_DENIED;
350 u_min_age = account_policy_temp;
352 unix_to_nt_time_abs((NTTIME *)&p->max_password_age, u_expire);
353 unix_to_nt_time_abs((NTTIME *)&p->min_password_age, u_min_age);
355 policy = p;
357 return NT_STATUS_OK;
360 /*********************************************************************
361 BUILTIN specific functions.
362 *********************************************************************/
364 /* list all domain groups */
365 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
366 TALLOC_CTX *mem_ctx,
367 uint32 *num_entries,
368 struct acct_info **info)
370 /* BUILTIN doesn't have domain groups */
371 *num_entries = 0;
372 *info = NULL;
373 return NT_STATUS_OK;
376 /* Query display info for a domain. This returns enough information plus a
377 bit extra to give an overview of domain users for the User Manager
378 application. */
379 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
380 TALLOC_CTX *mem_ctx,
381 uint32 *num_entries,
382 struct wbint_userinfo **info)
384 /* We don't have users */
385 *num_entries = 0;
386 *info = NULL;
387 return NT_STATUS_OK;
390 /* Lookup user information from a rid or username. */
391 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
392 TALLOC_CTX *mem_ctx,
393 const DOM_SID *user_sid,
394 struct wbint_userinfo *user_info)
396 return NT_STATUS_NO_SUCH_USER;
399 static NTSTATUS builtin_lookup_groupmem(struct winbindd_domain *domain,
400 TALLOC_CTX *mem_ctx,
401 const DOM_SID *group_sid, uint32 *num_names,
402 DOM_SID **sid_mem, char ***names,
403 uint32 **name_types)
405 DEBUG(10,("passdb: lookup_groupmem (builtin) %s sid=%s\n", domain->name,
406 sid_string_dbg(group_sid)));
408 *num_names = 0;
409 *sid_mem = NULL;
410 *names = NULL;
411 *name_types = 0;
412 return NT_STATUS_NO_SUCH_GROUP;
415 /* get a list of trusted domains - builtin domain */
416 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
417 TALLOC_CTX *mem_ctx,
418 uint32 *num_domains,
419 char ***names,
420 char ***alt_names,
421 DOM_SID **dom_sids)
423 *num_domains = 0;
424 *names = NULL;
425 *alt_names = NULL;
426 *dom_sids = NULL;
427 return NT_STATUS_OK;
430 /*********************************************************************
431 SAM specific functions.
432 *********************************************************************/
434 /* list all domain groups */
435 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
436 TALLOC_CTX *mem_ctx,
437 uint32 *num_entries,
438 struct acct_info **info)
440 return enum_groups_internal(domain,
441 mem_ctx,
442 num_entries,
443 info,
444 SID_NAME_DOM_GRP);
447 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
448 TALLOC_CTX *mem_ctx,
449 uint32 *num_entries,
450 struct wbint_userinfo **info)
452 struct pdb_search *ps = pdb_search_users(talloc_tos(), ACB_NORMAL);
453 struct samr_displayentry *entries = NULL;
454 uint32 i;
456 *num_entries = 0;
457 *info = NULL;
459 if (!ps) {
460 return NT_STATUS_NO_MEMORY;
463 *num_entries = pdb_search_entries(ps, 0, 0xffffffff, &entries);
465 DEBUG(10, ("sam_query_user_list: found %d users\n",
466 (int)*num_entries));
468 *info = TALLOC_ZERO_ARRAY(mem_ctx, struct wbint_userinfo, *num_entries);
469 if (!(*info)) {
470 TALLOC_FREE(ps);
471 return NT_STATUS_NO_MEMORY;
474 for (i = 0; i < *num_entries; i++) {
475 struct samr_displayentry *e = &entries[i];
477 (*info)[i].acct_name = talloc_strdup(mem_ctx, e->account_name );
478 (*info)[i].full_name = talloc_strdup(mem_ctx, e->fullname );
479 (*info)[i].homedir = NULL;
480 (*info)[i].shell = NULL;
481 sid_compose(&(*info)[i].user_sid, &domain->sid, e->rid);
483 /* For the moment we set the primary group for
484 every user to be the Domain Users group.
485 There are serious problems with determining
486 the actual primary group for large domains.
487 This should really be made into a 'winbind
488 force group' smb.conf parameter or
489 something like that. */
491 sid_compose(&(*info)[i].group_sid, &domain->sid,
492 DOMAIN_GROUP_RID_USERS);
495 TALLOC_FREE(ps);
496 return NT_STATUS_OK;
499 /* Lookup user information from a rid or username. */
500 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
501 TALLOC_CTX *mem_ctx,
502 const DOM_SID *user_sid,
503 struct wbint_userinfo *user_info)
505 struct samu *sampass = NULL;
507 ZERO_STRUCTP(user_info);
509 if (!sid_check_is_in_our_domain(user_sid)) {
510 return NT_STATUS_NO_SUCH_USER;
513 DEBUG(10,("sam_query_user: getting samu info for sid %s\n",
514 sid_string_dbg(user_sid) ));
516 if (!(sampass = samu_new(mem_ctx))) {
517 return NT_STATUS_NO_MEMORY;
520 if (!pdb_getsampwsid(sampass, user_sid)) {
521 TALLOC_FREE(sampass);
522 return NT_STATUS_NO_SUCH_USER;
525 if (pdb_get_group_sid(sampass) == NULL) {
526 TALLOC_FREE(sampass);
527 return NT_STATUS_NO_SUCH_GROUP;
530 DEBUG(10,("sam_query_user: group sid %s\n",
531 sid_string_dbg(sampass->group_sid) ));
533 sid_copy(&user_info->user_sid, user_sid);
534 sid_copy(&user_info->group_sid, sampass->group_sid);
536 user_info->acct_name = talloc_strdup(mem_ctx, sampass->username ?
537 sampass->username : "");
538 user_info->full_name = talloc_strdup(mem_ctx, sampass->full_name ?
539 sampass->full_name : "");
540 user_info->homedir = talloc_strdup(mem_ctx, sampass->home_dir ?
541 sampass->home_dir : "");
542 if (sampass->unix_pw && sampass->unix_pw->pw_shell) {
543 user_info->shell = talloc_strdup(mem_ctx, sampass->unix_pw->pw_shell);
544 } else {
545 user_info->shell = talloc_strdup(mem_ctx, "");
547 user_info->primary_gid = sampass->unix_pw ? sampass->unix_pw->pw_gid : (gid_t)-1;
549 TALLOC_FREE(sampass);
550 return NT_STATUS_OK;
553 /* Lookup group membership given a rid. */
554 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
555 TALLOC_CTX *mem_ctx,
556 const DOM_SID *group_sid, uint32 *num_names,
557 DOM_SID **sid_mem, char ***names,
558 uint32 **name_types)
560 size_t i, num_members, num_mapped;
561 uint32 *rids;
562 NTSTATUS result;
563 const DOM_SID **sids;
564 struct lsa_dom_info *lsa_domains;
565 struct lsa_name_info *lsa_names;
566 TALLOC_CTX *tmp_ctx;
568 DEBUG(10,("passdb: lookup_groupmem (sam) %s sid=%s\n", domain->name,
569 sid_string_dbg(group_sid)));
571 if (!sid_check_is_in_our_domain(group_sid)) {
572 /* There's no groups, only aliases in BUILTIN */
573 return NT_STATUS_NO_SUCH_GROUP;
576 if (!(tmp_ctx = talloc_init("lookup_groupmem"))) {
577 return NT_STATUS_NO_MEMORY;
580 result = pdb_enum_group_members(tmp_ctx, group_sid, &rids,
581 &num_members);
582 if (!NT_STATUS_IS_OK(result)) {
583 TALLOC_FREE(tmp_ctx);
584 return result;
587 if (num_members == 0) {
588 *num_names = 0;
589 *sid_mem = NULL;
590 *names = NULL;
591 *name_types = NULL;
592 TALLOC_FREE(tmp_ctx);
593 return NT_STATUS_OK;
596 *sid_mem = TALLOC_ARRAY(mem_ctx, DOM_SID, num_members);
597 *names = TALLOC_ARRAY(mem_ctx, char *, num_members);
598 *name_types = TALLOC_ARRAY(mem_ctx, uint32, num_members);
599 sids = TALLOC_ARRAY(tmp_ctx, const DOM_SID *, num_members);
601 if (((*sid_mem) == NULL) || ((*names) == NULL) ||
602 ((*name_types) == NULL) || (sids == NULL)) {
603 TALLOC_FREE(tmp_ctx);
604 return NT_STATUS_NO_MEMORY;
608 * Prepare an array of sid pointers for the lookup_sids calling
609 * convention.
612 for (i=0; i<num_members; i++) {
613 DOM_SID *sid = &((*sid_mem)[i]);
614 if (!sid_compose(sid, &domain->sid, rids[i])) {
615 TALLOC_FREE(tmp_ctx);
616 return NT_STATUS_INTERNAL_ERROR;
618 sids[i] = sid;
621 result = lookup_sids(tmp_ctx, num_members, sids, 1,
622 &lsa_domains, &lsa_names);
623 if (!NT_STATUS_IS_OK(result)) {
624 TALLOC_FREE(tmp_ctx);
625 return result;
628 num_mapped = 0;
629 for (i=0; i<num_members; i++) {
630 if (lsa_names[i].type != SID_NAME_USER) {
631 DEBUG(2, ("Got %s as group member -- ignoring\n",
632 sid_type_lookup(lsa_names[i].type)));
633 continue;
635 if (!((*names)[num_mapped] = talloc_strdup((*names),
636 lsa_names[i].name))) {
637 TALLOC_FREE(tmp_ctx);
638 return NT_STATUS_NO_MEMORY;
641 (*name_types)[num_mapped] = lsa_names[i].type;
643 num_mapped += 1;
646 *num_names = num_mapped;
648 TALLOC_FREE(tmp_ctx);
649 return NT_STATUS_OK;
652 /* get a list of trusted domains */
653 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
654 TALLOC_CTX *mem_ctx,
655 uint32 *num_domains,
656 char ***names,
657 char ***alt_names,
658 DOM_SID **dom_sids)
660 NTSTATUS nt_status;
661 struct trustdom_info **domains;
662 int i;
663 TALLOC_CTX *tmp_ctx;
665 *num_domains = 0;
666 *names = NULL;
667 *alt_names = NULL;
668 *dom_sids = NULL;
670 if (!(tmp_ctx = talloc_init("trusted_domains"))) {
671 return NT_STATUS_NO_MEMORY;
674 nt_status = pdb_enum_trusteddoms(tmp_ctx, num_domains, &domains);
675 if (!NT_STATUS_IS_OK(nt_status)) {
676 TALLOC_FREE(tmp_ctx);
677 return nt_status;
680 if (*num_domains) {
681 *names = TALLOC_ARRAY(mem_ctx, char *, *num_domains);
682 *alt_names = TALLOC_ARRAY(mem_ctx, char *, *num_domains);
683 *dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_domains);
685 if ((*alt_names == NULL) || (*names == NULL) || (*dom_sids == NULL)) {
686 TALLOC_FREE(tmp_ctx);
687 return NT_STATUS_NO_MEMORY;
689 } else {
690 *names = NULL;
691 *alt_names = NULL;
692 *dom_sids = NULL;
695 for (i=0; i<*num_domains; i++) {
696 (*alt_names)[i] = NULL;
697 if (!((*names)[i] = talloc_strdup((*names),
698 domains[i]->name))) {
699 TALLOC_FREE(tmp_ctx);
700 return NT_STATUS_NO_MEMORY;
702 sid_copy(&(*dom_sids)[i], &domains[i]->sid);
705 TALLOC_FREE(tmp_ctx);
706 return NT_STATUS_OK;
709 /* the rpc backend methods are exposed via this structure */
710 struct winbindd_methods builtin_passdb_methods = {
711 false,
712 builtin_query_user_list,
713 builtin_enum_dom_groups,
714 enum_local_groups,
715 name_to_sid,
716 sid_to_name,
717 rids_to_names,
718 builtin_query_user,
719 lookup_usergroups,
720 lookup_useraliases,
721 builtin_lookup_groupmem,
722 sequence_number,
723 lockout_policy,
724 password_policy,
725 builtin_trusted_domains,
728 /* the rpc backend methods are exposed via this structure */
729 struct winbindd_methods sam_passdb_methods = {
730 false,
731 sam_query_user_list,
732 sam_enum_dom_groups,
733 enum_local_groups,
734 name_to_sid,
735 sid_to_name,
736 rids_to_names,
737 sam_query_user,
738 lookup_usergroups,
739 lookup_useraliases,
740 sam_lookup_groupmem,
741 sequence_number,
742 lockout_policy,
743 password_policy,
744 sam_trusted_domains,