~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/nsswitch/winbindd_passdb.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
   Unix SMB/CIFS implementation.
3
 
 
4
 
   Winbind rpc backend functions
5
 
 
6
 
   Copyright (C) Tim Potter 2000-2001,2003
7
 
   Copyright (C) Simo Sorce 2003
8
 
   Copyright (C) Volker Lendecke 2004
9
 
   
10
 
   This program is free software; you can redistribute it and/or modify
11
 
   it under the terms of the GNU General Public License as published by
12
 
   the Free Software Foundation; either version 2 of the License, or
13
 
   (at your option) any later version.
14
 
   
15
 
   This program is distributed in the hope that it will be useful,
16
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
   GNU General Public License for more details.
19
 
   
20
 
   You should have received a copy of the GNU General Public License
21
 
   along with this program; if not, write to the Free Software
22
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
 
*/
24
 
 
25
 
#include "includes.h"
26
 
#include "winbindd.h"
27
 
 
28
 
#undef DBGC_CLASS
29
 
#define DBGC_CLASS DBGC_WINBIND
30
 
 
31
 
static void add_member(const char *domain, const char *user,
32
 
           char **pp_members, size_t *p_num_members)
33
 
{
34
 
        fstring name;
35
 
 
36
 
        fill_domain_username(name, domain, user, True);
37
 
        safe_strcat(name, ",", sizeof(name)-1);
38
 
        string_append(pp_members, name);
39
 
        *p_num_members += 1;
40
 
}
41
 
 
42
 
/**********************************************************************
43
 
 Add member users resulting from sid. Expand if it is a domain group.
44
 
**********************************************************************/
45
 
 
46
 
static void add_expanded_sid(const DOM_SID *sid, char **pp_members, size_t *p_num_members)
47
 
{
48
 
        DOM_SID dom_sid;
49
 
        uint32 rid;
50
 
        struct winbindd_domain *domain;
51
 
        size_t i;
52
 
 
53
 
        char *domain_name = NULL;
54
 
        char *name = NULL;
55
 
        enum SID_NAME_USE type;
56
 
 
57
 
        uint32 num_names;
58
 
        DOM_SID *sid_mem;
59
 
        char **names;
60
 
        uint32 *types;
61
 
 
62
 
        NTSTATUS result;
63
 
 
64
 
        TALLOC_CTX *mem_ctx = talloc_init("add_expanded_sid");
65
 
 
66
 
        if (mem_ctx == NULL) {
67
 
                DEBUG(1, ("talloc_init failed\n"));
68
 
                return;
69
 
        }
70
 
 
71
 
        sid_copy(&dom_sid, sid);
72
 
        sid_split_rid(&dom_sid, &rid);
73
 
 
74
 
        domain = find_lookup_domain_from_sid(sid);
75
 
 
76
 
        if (domain == NULL) {
77
 
                DEBUG(3, ("Could not find domain for sid %s\n",
78
 
                          sid_string_static(sid)));
79
 
                goto done;
80
 
        }
81
 
 
82
 
        result = domain->methods->sid_to_name(domain, mem_ctx, sid,
83
 
                                              &domain_name, &name, &type);
84
 
 
85
 
        if (!NT_STATUS_IS_OK(result)) {
86
 
                DEBUG(3, ("sid_to_name failed for sid %s\n",
87
 
                          sid_string_static(sid)));
88
 
                goto done;
89
 
        }
90
 
 
91
 
        DEBUG(10, ("Found name %s, type %d\n", name, type));
92
 
 
93
 
        if (type == SID_NAME_USER) {
94
 
                add_member(domain_name, name, pp_members, p_num_members);
95
 
                goto done;
96
 
        }
97
 
 
98
 
        if (type != SID_NAME_DOM_GRP) {
99
 
                DEBUG(10, ("Alias member %s neither user nor group, ignore\n",
100
 
                           name));
101
 
                goto done;
102
 
        }
103
 
 
104
 
        /* Expand the domain group, this must be done via the target domain */
105
 
 
106
 
        domain = find_domain_from_sid(sid);
107
 
 
108
 
        if (domain == NULL) {
109
 
                DEBUG(3, ("Could not find domain from SID %s\n",
110
 
                          sid_string_static(sid)));
111
 
                goto done;
112
 
        }
113
 
 
114
 
        result = domain->methods->lookup_groupmem(domain, mem_ctx,
115
 
                                                  sid, &num_names,
116
 
                                                  &sid_mem, &names,
117
 
                                                  &types);
118
 
 
119
 
        if (!NT_STATUS_IS_OK(result)) {
120
 
                DEBUG(10, ("Could not lookup group members for %s: %s\n",
121
 
                           name, nt_errstr(result)));
122
 
                goto done;
123
 
        }
124
 
 
125
 
        for (i=0; i<num_names; i++) {
126
 
                DEBUG(10, ("Adding group member SID %s\n",
127
 
                           sid_string_static(&sid_mem[i])));
128
 
 
129
 
                if (types[i] != SID_NAME_USER) {
130
 
                        DEBUG(1, ("Hmmm. Member %s of group %s is no user. "
131
 
                                  "Ignoring.\n", names[i], name));
132
 
                        continue;
133
 
                }
134
 
 
135
 
                add_member(domain->name, names[i], pp_members, p_num_members);
136
 
        }
137
 
 
138
 
 done:
139
 
        talloc_destroy(mem_ctx);
140
 
        return;
141
 
}
142
 
 
143
 
BOOL fill_passdb_alias_grmem(struct winbindd_domain *domain,
144
 
                             DOM_SID *group_sid, 
145
 
                             size_t *num_gr_mem, char **gr_mem, size_t *gr_mem_len)
146
 
{
147
 
        DOM_SID *members;
148
 
        size_t i, num_members;
149
 
 
150
 
        *num_gr_mem = 0;
151
 
        *gr_mem = NULL;
152
 
        *gr_mem_len = 0;
153
 
 
154
 
        if (!NT_STATUS_IS_OK(pdb_enum_aliasmem(group_sid, &members,
155
 
                                               &num_members)))
156
 
                return True;
157
 
 
158
 
        for (i=0; i<num_members; i++) {
159
 
                add_expanded_sid(&members[i], gr_mem, num_gr_mem);
160
 
        }
161
 
 
162
 
        SAFE_FREE(members);
163
 
 
164
 
        if (*gr_mem != NULL) {
165
 
                size_t len;
166
 
 
167
 
                /* We have at least one member, strip off the last "," */
168
 
                len = strlen(*gr_mem);
169
 
                (*gr_mem)[len-1] = '\0';
170
 
                *gr_mem_len = len;
171
 
        }
172
 
 
173
 
        return True;
174
 
}
175
 
 
176
 
/* Query display info for a domain.  This returns enough information plus a
177
 
   bit extra to give an overview of domain users for the User Manager
178
 
   application. */
179
 
static NTSTATUS query_user_list(struct winbindd_domain *domain,
180
 
                               TALLOC_CTX *mem_ctx,
181
 
                               uint32 *num_entries, 
182
 
                               WINBIND_USERINFO **info)
183
 
{
184
 
        /* We don't have users */
185
 
        *num_entries = 0;
186
 
        *info = NULL;
187
 
        return NT_STATUS_OK;
188
 
}
189
 
 
190
 
/* list all domain groups */
191
 
static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
192
 
                                TALLOC_CTX *mem_ctx,
193
 
                                uint32 *num_entries, 
194
 
                                struct acct_info **info)
195
 
{
196
 
        /* We don't have domain groups */
197
 
        *num_entries = 0;
198
 
        *info = NULL;
199
 
        return NT_STATUS_OK;
200
 
}
201
 
 
202
 
/* List all domain groups */
203
 
 
204
 
static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
205
 
                                TALLOC_CTX *mem_ctx,
206
 
                                uint32 *num_entries, 
207
 
                                struct acct_info **info)
208
 
{
209
 
        struct pdb_search *search;
210
 
        struct samr_displayentry *aliases;
211
 
        int i;
212
 
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
213
 
 
214
 
        search = pdb_search_aliases(&domain->sid);
215
 
        if (search == NULL) goto done;
216
 
 
217
 
        *num_entries = pdb_search_entries(search, 0, 0xffffffff, &aliases);
218
 
        if (*num_entries == 0) goto done;
219
 
 
220
 
        *info = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_entries);
221
 
        if (*info == NULL) {
222
 
                result = NT_STATUS_NO_MEMORY;
223
 
                goto done;
224
 
        }
225
 
 
226
 
        for (i=0; i<*num_entries; i++) {
227
 
                fstrcpy((*info)[i].acct_name, aliases[i].account_name);
228
 
                fstrcpy((*info)[i].acct_desc, aliases[i].description);
229
 
                (*info)[i].rid = aliases[i].rid;
230
 
        }
231
 
 
232
 
        result = NT_STATUS_OK;
233
 
 done:
234
 
        pdb_search_destroy(search);
235
 
        return result;
236
 
}
237
 
 
238
 
/* convert a single name to a sid in a domain */
239
 
static NTSTATUS name_to_sid(struct winbindd_domain *domain,
240
 
                            TALLOC_CTX *mem_ctx,
241
 
                            const char *domain_name,
242
 
                            const char *name,
243
 
                            DOM_SID *sid,
244
 
                            enum SID_NAME_USE *type)
245
 
{
246
 
        DEBUG(10, ("Finding name %s\n", name));
247
 
 
248
 
        if ( !lookup_name( mem_ctx, name, LOOKUP_NAME_ALL, 
249
 
                NULL, NULL, sid, type ) )
250
 
        {
251
 
                return NT_STATUS_NONE_MAPPED;
252
 
        }
253
 
 
254
 
        return NT_STATUS_OK;
255
 
}
256
 
 
257
 
/*
258
 
  convert a domain SID to a user or group name
259
 
*/
260
 
static NTSTATUS sid_to_name(struct winbindd_domain *domain,
261
 
                            TALLOC_CTX *mem_ctx,
262
 
                            const DOM_SID *sid,
263
 
                            char **domain_name,
264
 
                            char **name,
265
 
                            enum SID_NAME_USE *type)
266
 
{
267
 
        const char *dom, *nam;
268
 
 
269
 
        DEBUG(10, ("Converting SID %s\n", sid_string_static(sid)));
270
 
 
271
 
        /* Paranoia check */
272
 
        if (!sid_check_is_in_builtin(sid) &&
273
 
            !sid_check_is_in_our_domain(sid)) {
274
 
                DEBUG(0, ("Possible deadlock: Trying to lookup SID %s with "
275
 
                          "passdb backend\n", sid_string_static(sid)));
276
 
                return NT_STATUS_NONE_MAPPED;
277
 
        }
278
 
 
279
 
        if (!lookup_sid(mem_ctx, sid, &dom, &nam, type)) {
280
 
                return NT_STATUS_NONE_MAPPED;
281
 
        }
282
 
 
283
 
        *domain_name = talloc_strdup(mem_ctx, dom);
284
 
        *name = talloc_strdup(mem_ctx, nam);
285
 
 
286
 
        return NT_STATUS_OK;
287
 
}
288
 
 
289
 
static NTSTATUS rids_to_names(struct winbindd_domain *domain,
290
 
                              TALLOC_CTX *mem_ctx,
291
 
                              const DOM_SID *sid,
292
 
                              uint32 *rids,
293
 
                              size_t num_rids,
294
 
                              char **domain_name,
295
 
                              char ***names,
296
 
                              enum SID_NAME_USE **types)
297
 
{
298
 
        return NT_STATUS_UNSUCCESSFUL;
299
 
}
300
 
 
301
 
/* Lookup user information from a rid or username. */
302
 
static NTSTATUS query_user(struct winbindd_domain *domain, 
303
 
                           TALLOC_CTX *mem_ctx, 
304
 
                           const DOM_SID *user_sid,
305
 
                           WINBIND_USERINFO *user_info)
306
 
{
307
 
        return NT_STATUS_NO_SUCH_USER;
308
 
}
309
 
 
310
 
/* Lookup groups a user is a member of.  I wish Unix had a call like this! */
311
 
static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
312
 
                                  TALLOC_CTX *mem_ctx,
313
 
                                  const DOM_SID *user_sid,
314
 
                                  uint32 *num_groups, DOM_SID **user_gids)
315
 
{
316
 
        NTSTATUS result;
317
 
        DOM_SID *groups = NULL;
318
 
        gid_t *gids = NULL;
319
 
        size_t ngroups = 0;
320
 
        struct samu *user;
321
 
 
322
 
        if ( (user = samu_new(mem_ctx)) == NULL ) {
323
 
                return NT_STATUS_NO_MEMORY;
324
 
        }
325
 
 
326
 
        if ( !pdb_getsampwsid( user, user_sid ) ) {
327
 
                return NT_STATUS_NO_SUCH_USER;
328
 
        }
329
 
 
330
 
        result = pdb_enum_group_memberships( mem_ctx, user, &groups, &gids, &ngroups );
331
 
 
332
 
        TALLOC_FREE( user );
333
 
 
334
 
        *num_groups = (uint32)ngroups;
335
 
        *user_gids = groups;
336
 
 
337
 
        return result;
338
 
}
339
 
 
340
 
static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
341
 
                                   TALLOC_CTX *mem_ctx,
342
 
                                   uint32 num_sids, const DOM_SID *sids,
343
 
                                   uint32 *p_num_aliases, uint32 **rids)
344
 
{
345
 
        NTSTATUS result;
346
 
        size_t num_aliases = 0;
347
 
 
348
 
        result = pdb_enum_alias_memberships(mem_ctx, &domain->sid,
349
 
                                            sids, num_sids, rids, &num_aliases);
350
 
 
351
 
        *p_num_aliases = num_aliases;
352
 
        return result;
353
 
}
354
 
 
355
 
/* Lookup group membership given a rid.   */
356
 
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
357
 
                                TALLOC_CTX *mem_ctx,
358
 
                                const DOM_SID *group_sid, uint32 *num_names, 
359
 
                                DOM_SID **sid_mem, char ***names, 
360
 
                                uint32 **name_types)
361
 
{
362
 
        size_t i, num_members, num_mapped;
363
 
        uint32 *rids;
364
 
        NTSTATUS result;
365
 
        const DOM_SID **sids;
366
 
        struct lsa_dom_info *lsa_domains;
367
 
        struct lsa_name_info *lsa_names;
368
 
        TALLOC_CTX *tmp_ctx;
369
 
 
370
 
        if (!sid_check_is_in_our_domain(group_sid)) {
371
 
                /* There's no groups, only aliases in BUILTIN */
372
 
                return NT_STATUS_NO_SUCH_GROUP;
373
 
        }
374
 
 
375
 
        if (!(tmp_ctx = talloc_init("lookup_groupmem"))) {
376
 
                return NT_STATUS_NO_MEMORY;
377
 
        }
378
 
 
379
 
        result = pdb_enum_group_members(tmp_ctx, group_sid, &rids,
380
 
                                        &num_members);
381
 
        if (!NT_STATUS_IS_OK(result)) {
382
 
                TALLOC_FREE(tmp_ctx);
383
 
                return result;
384
 
        }
385
 
 
386
 
        if (num_members == 0) {
387
 
                *num_names = 0;
388
 
                *sid_mem = NULL;
389
 
                *names = NULL;
390
 
                *name_types = NULL;
391
 
                TALLOC_FREE(tmp_ctx);
392
 
                return NT_STATUS_OK;
393
 
        }
394
 
 
395
 
        *sid_mem = TALLOC_ARRAY(mem_ctx, DOM_SID, num_members);
396
 
        *names = TALLOC_ARRAY(mem_ctx, char *, num_members);
397
 
        *name_types = TALLOC_ARRAY(mem_ctx, uint32, num_members);
398
 
        sids = TALLOC_ARRAY(tmp_ctx, const DOM_SID *, num_members);
399
 
 
400
 
        if (((*sid_mem) == NULL) || ((*names) == NULL) ||
401
 
            ((*name_types) == NULL) || (sids == NULL)) {
402
 
                TALLOC_FREE(tmp_ctx);
403
 
                return NT_STATUS_NO_MEMORY;
404
 
        }
405
 
 
406
 
        /*
407
 
         * Prepare an array of sid pointers for the lookup_sids calling
408
 
         * convention.
409
 
         */
410
 
 
411
 
        for (i=0; i<num_members; i++) {
412
 
                DOM_SID *sid = &((*sid_mem)[i]);
413
 
                if (!sid_compose(sid, &domain->sid, rids[i])) {
414
 
                        TALLOC_FREE(tmp_ctx);
415
 
                        return NT_STATUS_INTERNAL_ERROR;
416
 
                }
417
 
                sids[i] = sid;
418
 
        }
419
 
 
420
 
        result = lookup_sids(tmp_ctx, num_members, sids, 1,
421
 
                             &lsa_domains, &lsa_names);
422
 
        if (!NT_STATUS_IS_OK(result)) {
423
 
                TALLOC_FREE(tmp_ctx);
424
 
                return result;
425
 
        }
426
 
 
427
 
        num_mapped = 0;
428
 
        for (i=0; i<num_members; i++) {
429
 
                if (lsa_names[i].type != SID_NAME_USER) {
430
 
                        DEBUG(2, ("Got %s as group member -- ignoring\n",
431
 
                                  sid_type_lookup(lsa_names[i].type)));
432
 
                        continue;
433
 
                }
434
 
                if (!((*names)[i] = talloc_strdup((*names),
435
 
                                                  lsa_names[i].name))) {
436
 
                        TALLOC_FREE(tmp_ctx);
437
 
                        return NT_STATUS_NO_MEMORY;
438
 
                }
439
 
 
440
 
                (*name_types)[i] = lsa_names[i].type;
441
 
 
442
 
                num_mapped += 1;
443
 
        }
444
 
 
445
 
        *num_names = num_mapped;
446
 
 
447
 
        TALLOC_FREE(tmp_ctx);
448
 
        return NT_STATUS_OK;
449
 
}
450
 
 
451
 
/* find the sequence number for a domain */
452
 
static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
453
 
{
454
 
        BOOL result;
455
 
        time_t seq_num;
456
 
 
457
 
        result = pdb_get_seq_num(&seq_num);
458
 
        if (!result) {
459
 
                *seq = 1;
460
 
        }
461
 
 
462
 
        *seq = (int) seq_num;
463
 
        /* *seq = 1; */
464
 
        return NT_STATUS_OK;
465
 
}
466
 
 
467
 
static NTSTATUS lockout_policy(struct winbindd_domain *domain,
468
 
                               TALLOC_CTX *mem_ctx,
469
 
                               SAM_UNK_INFO_12 *policy)
470
 
{
471
 
        /* actually we have that */
472
 
        return NT_STATUS_NOT_IMPLEMENTED;
473
 
}
474
 
 
475
 
static NTSTATUS password_policy(struct winbindd_domain *domain,
476
 
                                TALLOC_CTX *mem_ctx,
477
 
                                SAM_UNK_INFO_1 *policy)
478
 
{
479
 
        uint32 min_pass_len,pass_hist,password_properties;
480
 
        time_t u_expire, u_min_age;
481
 
        NTTIME nt_expire, nt_min_age;
482
 
        uint32 account_policy_temp;
483
 
 
484
 
        if ((policy = TALLOC_ZERO_P(mem_ctx, SAM_UNK_INFO_1)) == NULL) {
485
 
                return NT_STATUS_NO_MEMORY;
486
 
        }
487
 
 
488
 
        if (!pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp)) {
489
 
                return NT_STATUS_ACCESS_DENIED;
490
 
        }
491
 
        min_pass_len = account_policy_temp;
492
 
 
493
 
        if (!pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp)) {
494
 
                return NT_STATUS_ACCESS_DENIED;
495
 
        }
496
 
        pass_hist = account_policy_temp;
497
 
 
498
 
        if (!pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp)) {
499
 
                return NT_STATUS_ACCESS_DENIED;
500
 
        }
501
 
        password_properties = account_policy_temp;
502
 
        
503
 
        if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp)) {
504
 
                return NT_STATUS_ACCESS_DENIED;
505
 
        }
506
 
        u_expire = account_policy_temp;
507
 
 
508
 
        if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp)) {
509
 
                return NT_STATUS_ACCESS_DENIED;
510
 
        }
511
 
        u_min_age = account_policy_temp;
512
 
 
513
 
        unix_to_nt_time_abs(&nt_expire, u_expire);
514
 
        unix_to_nt_time_abs(&nt_min_age, u_min_age);
515
 
 
516
 
        init_unk_info1(policy, (uint16)min_pass_len, (uint16)pass_hist, 
517
 
                       password_properties, nt_expire, nt_min_age);
518
 
 
519
 
        return NT_STATUS_OK;
520
 
}
521
 
 
522
 
/* get a list of trusted domains */
523
 
static NTSTATUS trusted_domains(struct winbindd_domain *domain,
524
 
                                TALLOC_CTX *mem_ctx,
525
 
                                uint32 *num_domains,
526
 
                                char ***names,
527
 
                                char ***alt_names,
528
 
                                DOM_SID **dom_sids)
529
 
{
530
 
        NTSTATUS nt_status;
531
 
        struct trustdom_info **domains;
532
 
        int i;
533
 
        TALLOC_CTX *tmp_ctx;
534
 
 
535
 
        *num_domains = 0;
536
 
        *names = NULL;
537
 
        *alt_names = NULL;
538
 
        *dom_sids = NULL;
539
 
 
540
 
        if (!(tmp_ctx = talloc_init("trusted_domains"))) {
541
 
                return NT_STATUS_NO_MEMORY;
542
 
        }
543
 
 
544
 
        nt_status = secrets_trusted_domains(tmp_ctx, num_domains,
545
 
                                            &domains);
546
 
        if (!NT_STATUS_IS_OK(nt_status)) {
547
 
                TALLOC_FREE(tmp_ctx);
548
 
                return nt_status;
549
 
        }
550
 
 
551
 
        *names = TALLOC_ARRAY(mem_ctx, char *, *num_domains);
552
 
        *alt_names = TALLOC_ARRAY(mem_ctx, char *, *num_domains);
553
 
        *dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_domains);
554
 
 
555
 
        if ((*alt_names == NULL) || (*names == NULL) || (*dom_sids == NULL)) {
556
 
                TALLOC_FREE(tmp_ctx);
557
 
                return NT_STATUS_NO_MEMORY;
558
 
        }
559
 
 
560
 
        for (i=0; i<*num_domains; i++) {
561
 
                (*alt_names)[i] = NULL;
562
 
                if (!((*names)[i] = talloc_strdup((*names),
563
 
                                                  domains[i]->name))) {
564
 
                        TALLOC_FREE(tmp_ctx);
565
 
                        return NT_STATUS_NO_MEMORY;
566
 
                }
567
 
                sid_copy(&(*dom_sids)[i], &domains[i]->sid);
568
 
        }
569
 
 
570
 
        TALLOC_FREE(tmp_ctx);
571
 
        return NT_STATUS_OK;
572
 
}
573
 
 
574
 
/* the rpc backend methods are exposed via this structure */
575
 
struct winbindd_methods passdb_methods = {
576
 
        False,
577
 
        query_user_list,
578
 
        enum_dom_groups,
579
 
        enum_local_groups,
580
 
        name_to_sid,
581
 
        sid_to_name,
582
 
        rids_to_names,
583
 
        query_user,
584
 
        lookup_usergroups,
585
 
        lookup_useraliases,
586
 
        lookup_groupmem,
587
 
        sequence_number,
588
 
        lockout_policy,
589
 
        password_policy,
590
 
        trusted_domains,
591
 
};