source: branches/samba-3.2.x/source/winbindd/winbindd_passdb.c@ 201

Last change on this file since 201 was 149, checked in by Paul Smedley, 17 years ago

Update trunk to v3.2.2

File size: 19.1 KB
Line 
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 Copyright (C) Jeremy Allison 2008
10
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.
15
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.
20
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/>.
23*/
24
25#include "includes.h"
26#include "winbindd.h"
27
28#undef DBGC_CLASS
29#define DBGC_CLASS DBGC_WINBIND
30
31static 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)
36{
37 struct pdb_search *search;
38 struct samr_displayentry *entries;
39 int i;
40 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
41
42 if (sidtype == SID_NAME_ALIAS) {
43 search = pdb_search_aliases(&domain->sid);
44 } else {
45 search = pdb_search_groups();
46 }
47
48 if (search == NULL) goto done;
49
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;
55 }
56
57 *info = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_entries);
58 if (*info == NULL) {
59 result = NT_STATUS_NO_MEMORY;
60 goto done;
61 }
62
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;
67 }
68
69 result = NT_STATUS_OK;
70 done:
71 pdb_search_destroy(search);
72 return result;
73}
74
75/* List all local groups (aliases) */
76static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
77 TALLOC_CTX *mem_ctx,
78 uint32 *num_entries,
79 struct acct_info **info)
80{
81 return enum_groups_internal(domain,
82 mem_ctx,
83 num_entries,
84 info,
85 SID_NAME_ALIAS);
86}
87
88/* convert a single name to a sid in a domain */
89static NTSTATUS name_to_sid(struct winbindd_domain *domain,
90 TALLOC_CTX *mem_ctx,
91 enum winbindd_cmd original_cmd,
92 const char *domain_name,
93 const char *name,
94 DOM_SID *sid,
95 enum lsa_SidType *type)
96{
97 const char *fullname;
98 uint32 flags = LOOKUP_NAME_ALL;
99
100 switch ( original_cmd ) {
101 case WINBINDD_LOOKUPNAME:
102 /* This call is ok */
103 break;
104 default:
105 /* Avoid any NSS calls in the lookup_name by default */
106 flags |= LOOKUP_NAME_EXPLICIT;
107 DEBUG(10,("winbindd_passdb: limiting name_to_sid() to explicit mappings\n"));
108 break;
109 }
110
111 if (domain_name && domain_name[0] && strchr_m(name, '\\') == NULL) {
112 fullname = talloc_asprintf(mem_ctx, "%s\\%s",
113 domain_name, name);
114 if (fullname == NULL) {
115 return NT_STATUS_NO_MEMORY;
116 }
117 } else {
118 fullname = name;
119 }
120
121 DEBUG(10, ("Finding fullname %s\n", fullname));
122
123 if ( !lookup_name( mem_ctx, fullname, flags, NULL, NULL, sid, type ) ) {
124 return NT_STATUS_NONE_MAPPED;
125 }
126
127 DEBUG(10, ("name_to_sid for %s returned %s (%s)\n",
128 fullname,
129 sid_string_dbg(sid),
130 sid_type_lookup((uint32)*type)));
131
132 return NT_STATUS_OK;
133}
134
135/*
136 convert a domain SID to a user or group name
137*/
138static NTSTATUS sid_to_name(struct winbindd_domain *domain,
139 TALLOC_CTX *mem_ctx,
140 const DOM_SID *sid,
141 char **domain_name,
142 char **name,
143 enum lsa_SidType *type)
144{
145 const char *dom, *nam;
146
147 DEBUG(10, ("Converting SID %s\n", sid_string_dbg(sid)));
148
149 /* Paranoia check */
150 if (!sid_check_is_in_builtin(sid) &&
151 !sid_check_is_in_our_domain(sid) &&
152 !sid_check_is_in_unix_users(sid) &&
153 !sid_check_is_unix_users(sid) &&
154 !sid_check_is_in_unix_groups(sid) &&
155 !sid_check_is_unix_groups(sid) &&
156 !sid_check_is_in_wellknown_domain(sid))
157 {
158 DEBUG(0, ("Possible deadlock: Trying to lookup SID %s with "
159 "passdb backend\n", sid_string_dbg(sid)));
160 return NT_STATUS_NONE_MAPPED;
161 }
162
163 if (!lookup_sid(mem_ctx, sid, &dom, &nam, type)) {
164 return NT_STATUS_NONE_MAPPED;
165 }
166
167 *domain_name = talloc_strdup(mem_ctx, dom);
168 *name = talloc_strdup(mem_ctx, nam);
169
170 return NT_STATUS_OK;
171}
172
173static NTSTATUS rids_to_names(struct winbindd_domain *domain,
174 TALLOC_CTX *mem_ctx,
175 const DOM_SID *sid,
176 uint32 *rids,
177 size_t num_rids,
178 char **domain_name,
179 char ***names,
180 enum lsa_SidType **types)
181{
182 size_t i;
183 bool have_mapped;
184 bool have_unmapped;
185
186 *domain_name = NULL;
187 *names = NULL;
188 *types = NULL;
189
190 if (!num_rids) {
191 return NT_STATUS_OK;
192 }
193
194 /* Paranoia check */
195 if (!sid_check_is_in_builtin(sid) &&
196 !sid_check_is_in_our_domain(sid) &&
197 !sid_check_is_in_unix_users(sid) &&
198 !sid_check_is_unix_users(sid) &&
199 !sid_check_is_in_unix_groups(sid) &&
200 !sid_check_is_unix_groups(sid) &&
201 !sid_check_is_in_wellknown_domain(sid))
202 {
203 DEBUG(0, ("Possible deadlock: Trying to lookup SID %s with "
204 "passdb backend\n", sid_string_dbg(sid)));
205 return NT_STATUS_NONE_MAPPED;
206 }
207
208 *names = TALLOC_ARRAY(mem_ctx, char *, num_rids);
209 *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
210
211 if ((*names == NULL) || (*types == NULL)) {
212 return NT_STATUS_NO_MEMORY;
213 }
214
215 have_mapped = have_unmapped = false;
216
217 for (i=0; i<num_rids; i++) {
218 DOM_SID lsid;
219 const char *dom = NULL, *nam = NULL;
220 enum lsa_SidType type = SID_NAME_UNKNOWN;
221
222 if (!sid_compose(&lsid, sid, rids[i])) {
223 return NT_STATUS_INTERNAL_ERROR;
224 }
225
226 if (!lookup_sid(mem_ctx, &lsid, &dom, &nam, &type)) {
227 have_unmapped = true;
228 (*types)[i] = SID_NAME_UNKNOWN;
229 (*names)[i] = talloc_strdup(mem_ctx, "");
230 } else {
231 have_mapped = true;
232 (*types)[i] = type;
233 (*names)[i] = CONST_DISCARD(char *, nam);
234 }
235
236 if (*domain_name == NULL) {
237 *domain_name = CONST_DISCARD(char *, dom);
238 } else {
239 char *dname = CONST_DISCARD(char *, dom);
240 TALLOC_FREE(dname);
241 }
242 }
243
244 if (!have_mapped) {
245 return NT_STATUS_NONE_MAPPED;
246 }
247 if (!have_unmapped) {
248 return NT_STATUS_OK;
249 }
250 return STATUS_SOME_UNMAPPED;
251}
252
253/* Lookup groups a user is a member of. I wish Unix had a call like this! */
254static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
255 TALLOC_CTX *mem_ctx,
256 const DOM_SID *user_sid,
257 uint32 *num_groups, DOM_SID **user_gids)
258{
259 NTSTATUS result;
260 DOM_SID *groups = NULL;
261 gid_t *gids = NULL;
262 size_t ngroups = 0;
263 struct samu *user;
264
265 if ( (user = samu_new(mem_ctx)) == NULL ) {
266 return NT_STATUS_NO_MEMORY;
267 }
268
269 if ( !pdb_getsampwsid( user, user_sid ) ) {
270 return NT_STATUS_NO_SUCH_USER;
271 }
272
273 result = pdb_enum_group_memberships( mem_ctx, user, &groups, &gids, &ngroups );
274
275 TALLOC_FREE( user );
276
277 *num_groups = (uint32)ngroups;
278 *user_gids = groups;
279
280 return result;
281}
282
283static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
284 TALLOC_CTX *mem_ctx,
285 uint32 num_sids, const DOM_SID *sids,
286 uint32 *p_num_aliases, uint32 **rids)
287{
288 NTSTATUS result;
289 size_t num_aliases = 0;
290
291 result = pdb_enum_alias_memberships(mem_ctx, &domain->sid,
292 sids, num_sids, rids, &num_aliases);
293
294 *p_num_aliases = num_aliases;
295 return result;
296}
297
298/* find the sequence number for a domain */
299static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
300{
301 bool result;
302 time_t seq_num;
303
304 result = pdb_get_seq_num(&seq_num);
305 if (!result) {
306 *seq = 1;
307 }
308
309 *seq = (int) seq_num;
310 /* *seq = 1; */
311 return NT_STATUS_OK;
312}
313
314static NTSTATUS lockout_policy(struct winbindd_domain *domain,
315 TALLOC_CTX *mem_ctx,
316 struct samr_DomInfo12 *policy)
317{
318 /* actually we have that */
319 return NT_STATUS_NOT_IMPLEMENTED;
320}
321
322static NTSTATUS password_policy(struct winbindd_domain *domain,
323 TALLOC_CTX *mem_ctx,
324 struct samr_DomInfo1 *policy)
325{
326 uint32 min_pass_len,pass_hist,password_properties;
327 time_t u_expire, u_min_age;
328 NTTIME nt_expire, nt_min_age;
329 uint32 account_policy_temp;
330
331 if ((policy = TALLOC_ZERO_P(mem_ctx, struct samr_DomInfo1)) == NULL) {
332 return NT_STATUS_NO_MEMORY;
333 }
334
335 if (!pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp)) {
336 return NT_STATUS_ACCESS_DENIED;
337 }
338 min_pass_len = account_policy_temp;
339
340 if (!pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp)) {
341 return NT_STATUS_ACCESS_DENIED;
342 }
343 pass_hist = account_policy_temp;
344
345 if (!pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp)) {
346 return NT_STATUS_ACCESS_DENIED;
347 }
348 password_properties = account_policy_temp;
349
350 if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp)) {
351 return NT_STATUS_ACCESS_DENIED;
352 }
353 u_expire = account_policy_temp;
354
355 if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp)) {
356 return NT_STATUS_ACCESS_DENIED;
357 }
358 u_min_age = account_policy_temp;
359
360 unix_to_nt_time_abs(&nt_expire, u_expire);
361 unix_to_nt_time_abs(&nt_min_age, u_min_age);
362
363 init_samr_DomInfo1(policy,
364 (uint16)min_pass_len,
365 (uint16)pass_hist,
366 password_properties,
367 nt_expire,
368 nt_min_age);
369
370 return NT_STATUS_OK;
371}
372
373/*********************************************************************
374 BUILTIN specific functions.
375*********************************************************************/
376
377/* list all domain groups */
378static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
379 TALLOC_CTX *mem_ctx,
380 uint32 *num_entries,
381 struct acct_info **info)
382{
383 /* BUILTIN doesn't have domain groups */
384 *num_entries = 0;
385 *info = NULL;
386 return NT_STATUS_OK;
387}
388
389/* Query display info for a domain. This returns enough information plus a
390 bit extra to give an overview of domain users for the User Manager
391 application. */
392static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
393 TALLOC_CTX *mem_ctx,
394 uint32 *num_entries,
395 WINBIND_USERINFO **info)
396{
397 /* We don't have users */
398 *num_entries = 0;
399 *info = NULL;
400 return NT_STATUS_OK;
401}
402
403/* Lookup user information from a rid or username. */
404static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
405 TALLOC_CTX *mem_ctx,
406 const DOM_SID *user_sid,
407 WINBIND_USERINFO *user_info)
408{
409 return NT_STATUS_NO_SUCH_USER;
410}
411
412static NTSTATUS builtin_lookup_groupmem(struct winbindd_domain *domain,
413 TALLOC_CTX *mem_ctx,
414 const DOM_SID *group_sid, uint32 *num_names,
415 DOM_SID **sid_mem, char ***names,
416 uint32 **name_types)
417{
418 *num_names = 0;
419 *sid_mem = NULL;
420 *names = NULL;
421 *name_types = 0;
422 return NT_STATUS_NO_SUCH_GROUP;
423}
424
425/* get a list of trusted domains - builtin domain */
426static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
427 TALLOC_CTX *mem_ctx,
428 uint32 *num_domains,
429 char ***names,
430 char ***alt_names,
431 DOM_SID **dom_sids)
432{
433 *num_domains = 0;
434 *names = NULL;
435 *alt_names = NULL;
436 *dom_sids = NULL;
437 return NT_STATUS_OK;
438}
439
440/*********************************************************************
441 SAM specific functions.
442*********************************************************************/
443
444/* list all domain groups */
445static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
446 TALLOC_CTX *mem_ctx,
447 uint32 *num_entries,
448 struct acct_info **info)
449{
450 return enum_groups_internal(domain,
451 mem_ctx,
452 num_entries,
453 info,
454 SID_NAME_DOM_GRP);
455}
456
457static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
458 TALLOC_CTX *mem_ctx,
459 uint32 *num_entries,
460 WINBIND_USERINFO **info)
461{
462 struct pdb_search *ps = pdb_search_users(ACB_NORMAL);
463 struct samr_displayentry *entries = NULL;
464 uint32 i;
465
466 *num_entries = 0;
467 *info = NULL;
468
469 if (!ps) {
470 return NT_STATUS_NO_MEMORY;
471 }
472
473 *num_entries = pdb_search_entries(ps,
474 1, 0xffffffff,
475 &entries);
476
477 *info = TALLOC_ZERO_ARRAY(mem_ctx, WINBIND_USERINFO, *num_entries);
478 if (!(*info)) {
479 pdb_search_destroy(ps);
480 return NT_STATUS_NO_MEMORY;
481 }
482
483 for (i = 0; i < *num_entries; i++) {
484 struct samr_displayentry *e = &entries[i];
485
486 (*info)[i].acct_name = talloc_strdup(mem_ctx, e->account_name );
487 (*info)[i].full_name = talloc_strdup(mem_ctx, e->fullname );
488 (*info)[i].homedir = NULL;
489 (*info)[i].shell = NULL;
490 sid_compose(&(*info)[i].user_sid, &domain->sid, e->rid);
491
492 /* For the moment we set the primary group for
493 every user to be the Domain Users group.
494 There are serious problems with determining
495 the actual primary group for large domains.
496 This should really be made into a 'winbind
497 force group' smb.conf parameter or
498 something like that. */
499
500 sid_compose(&(*info)[i].group_sid, &domain->sid,
501 DOMAIN_GROUP_RID_USERS);
502 }
503
504 pdb_search_destroy(ps);
505 return NT_STATUS_OK;
506}
507
508/* Lookup user information from a rid or username. */
509static NTSTATUS sam_query_user(struct winbindd_domain *domain,
510 TALLOC_CTX *mem_ctx,
511 const DOM_SID *user_sid,
512 WINBIND_USERINFO *user_info)
513{
514 struct samu *sampass = NULL;
515
516 ZERO_STRUCTP(user_info);
517
518 if (!sid_check_is_in_our_domain(user_sid)) {
519 return NT_STATUS_NO_SUCH_USER;
520 }
521
522 DEBUG(10,("sam_query_user: getting samu info for sid %s\n",
523 sid_string_dbg(user_sid) ));
524
525 if (!(sampass = samu_new(mem_ctx))) {
526 return NT_STATUS_NO_MEMORY;
527 }
528
529 if (!pdb_getsampwsid(sampass, user_sid)) {
530 TALLOC_FREE(sampass);
531 return NT_STATUS_NO_SUCH_USER;
532 }
533
534 if (pdb_get_group_sid(sampass) == NULL) {
535 TALLOC_FREE(sampass);
536 return NT_STATUS_NO_SUCH_GROUP;
537 }
538
539 DEBUG(10,("sam_query_user: group sid %s\n",
540 sid_string_dbg(sampass->group_sid) ));
541
542 sid_copy(&user_info->user_sid, user_sid);
543 sid_copy(&user_info->group_sid, sampass->group_sid);
544
545 user_info->acct_name = talloc_strdup(mem_ctx, sampass->username ?
546 sampass->username : "");
547 user_info->full_name = talloc_strdup(mem_ctx, sampass->full_name ?
548 sampass->full_name : "");
549 user_info->homedir = talloc_strdup(mem_ctx, sampass->home_dir ?
550 sampass->home_dir : "");
551 if (sampass->unix_pw && sampass->unix_pw->pw_shell) {
552 user_info->shell = talloc_strdup(mem_ctx, sampass->unix_pw->pw_shell);
553 } else {
554 user_info->shell = talloc_strdup(mem_ctx, "");
555 }
556 user_info->primary_gid = sampass->unix_pw ? sampass->unix_pw->pw_gid : (gid_t)-1;
557
558 TALLOC_FREE(sampass);
559 return NT_STATUS_OK;
560}
561
562/* Lookup group membership given a rid. */
563static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
564 TALLOC_CTX *mem_ctx,
565 const DOM_SID *group_sid, uint32 *num_names,
566 DOM_SID **sid_mem, char ***names,
567 uint32 **name_types)
568{
569 size_t i, num_members, num_mapped;
570 uint32 *rids;
571 NTSTATUS result;
572 const DOM_SID **sids;
573 struct lsa_dom_info *lsa_domains;
574 struct lsa_name_info *lsa_names;
575 TALLOC_CTX *tmp_ctx;
576
577 if (!sid_check_is_in_our_domain(group_sid)) {
578 /* There's no groups, only aliases in BUILTIN */
579 return NT_STATUS_NO_SUCH_GROUP;
580 }
581
582 if (!(tmp_ctx = talloc_init("lookup_groupmem"))) {
583 return NT_STATUS_NO_MEMORY;
584 }
585
586 result = pdb_enum_group_members(tmp_ctx, group_sid, &rids,
587 &num_members);
588 if (!NT_STATUS_IS_OK(result)) {
589 TALLOC_FREE(tmp_ctx);
590 return result;
591 }
592
593 if (num_members == 0) {
594 *num_names = 0;
595 *sid_mem = NULL;
596 *names = NULL;
597 *name_types = NULL;
598 TALLOC_FREE(tmp_ctx);
599 return NT_STATUS_OK;
600 }
601
602 *sid_mem = TALLOC_ARRAY(mem_ctx, DOM_SID, num_members);
603 *names = TALLOC_ARRAY(mem_ctx, char *, num_members);
604 *name_types = TALLOC_ARRAY(mem_ctx, uint32, num_members);
605 sids = TALLOC_ARRAY(tmp_ctx, const DOM_SID *, num_members);
606
607 if (((*sid_mem) == NULL) || ((*names) == NULL) ||
608 ((*name_types) == NULL) || (sids == NULL)) {
609 TALLOC_FREE(tmp_ctx);
610 return NT_STATUS_NO_MEMORY;
611 }
612
613 /*
614 * Prepare an array of sid pointers for the lookup_sids calling
615 * convention.
616 */
617
618 for (i=0; i<num_members; i++) {
619 DOM_SID *sid = &((*sid_mem)[i]);
620 if (!sid_compose(sid, &domain->sid, rids[i])) {
621 TALLOC_FREE(tmp_ctx);
622 return NT_STATUS_INTERNAL_ERROR;
623 }
624 sids[i] = sid;
625 }
626
627 result = lookup_sids(tmp_ctx, num_members, sids, 1,
628 &lsa_domains, &lsa_names);
629 if (!NT_STATUS_IS_OK(result)) {
630 TALLOC_FREE(tmp_ctx);
631 return result;
632 }
633
634 num_mapped = 0;
635 for (i=0; i<num_members; i++) {
636 if (lsa_names[i].type != SID_NAME_USER) {
637 DEBUG(2, ("Got %s as group member -- ignoring\n",
638 sid_type_lookup(lsa_names[i].type)));
639 continue;
640 }
641 if (!((*names)[i] = talloc_strdup((*names),
642 lsa_names[i].name))) {
643 TALLOC_FREE(tmp_ctx);
644 return NT_STATUS_NO_MEMORY;
645 }
646
647 (*name_types)[i] = lsa_names[i].type;
648
649 num_mapped += 1;
650 }
651
652 *num_names = num_mapped;
653
654 TALLOC_FREE(tmp_ctx);
655 return NT_STATUS_OK;
656}
657
658/* get a list of trusted domains */
659static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
660 TALLOC_CTX *mem_ctx,
661 uint32 *num_domains,
662 char ***names,
663 char ***alt_names,
664 DOM_SID **dom_sids)
665{
666 NTSTATUS nt_status;
667 struct trustdom_info **domains;
668 int i;
669 TALLOC_CTX *tmp_ctx;
670
671 *num_domains = 0;
672 *names = NULL;
673 *alt_names = NULL;
674 *dom_sids = NULL;
675
676 if (!(tmp_ctx = talloc_init("trusted_domains"))) {
677 return NT_STATUS_NO_MEMORY;
678 }
679
680 nt_status = pdb_enum_trusteddoms(tmp_ctx, num_domains, &domains);
681 if (!NT_STATUS_IS_OK(nt_status)) {
682 TALLOC_FREE(tmp_ctx);
683 return nt_status;
684 }
685
686 if (*num_domains) {
687 *names = TALLOC_ARRAY(mem_ctx, char *, *num_domains);
688 *alt_names = TALLOC_ARRAY(mem_ctx, char *, *num_domains);
689 *dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_domains);
690
691 if ((*alt_names == NULL) || (*names == NULL) || (*dom_sids == NULL)) {
692 TALLOC_FREE(tmp_ctx);
693 return NT_STATUS_NO_MEMORY;
694 }
695 } else {
696 *names = NULL;
697 *alt_names = NULL;
698 *dom_sids = NULL;
699 }
700
701 for (i=0; i<*num_domains; i++) {
702 (*alt_names)[i] = NULL;
703 if (!((*names)[i] = talloc_strdup((*names),
704 domains[i]->name))) {
705 TALLOC_FREE(tmp_ctx);
706 return NT_STATUS_NO_MEMORY;
707 }
708 sid_copy(&(*dom_sids)[i], &domains[i]->sid);
709 }
710
711 TALLOC_FREE(tmp_ctx);
712 return NT_STATUS_OK;
713}
714
715/* the rpc backend methods are exposed via this structure */
716struct winbindd_methods builtin_passdb_methods = {
717 false,
718 builtin_query_user_list,
719 builtin_enum_dom_groups,
720 enum_local_groups,
721 name_to_sid,
722 sid_to_name,
723 rids_to_names,
724 builtin_query_user,
725 lookup_usergroups,
726 lookup_useraliases,
727 builtin_lookup_groupmem,
728 sequence_number,
729 lockout_policy,
730 password_policy,
731 builtin_trusted_domains,
732};
733
734/* the rpc backend methods are exposed via this structure */
735struct winbindd_methods sam_passdb_methods = {
736 false,
737 sam_query_user_list,
738 sam_enum_dom_groups,
739 enum_local_groups,
740 name_to_sid,
741 sid_to_name,
742 rids_to_names,
743 sam_query_user,
744 lookup_usergroups,
745 lookup_useraliases,
746 sam_lookup_groupmem,
747 sequence_number,
748 lockout_policy,
749 password_policy,
750 sam_trusted_domains,
751};
Note: See TracBrowser for help on using the repository browser.