source: branches/samba-3.3.x/source/winbindd/winbindd_passdb.c

Last change on this file was 206, checked in by Herwig Bauernfeind, 16 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

File size: 18.5 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 TALLOC_FREE( user );
271 return NT_STATUS_NO_SUCH_USER;
272 }
273
274 result = pdb_enum_group_memberships( mem_ctx, user, &groups, &gids, &ngroups );
275
276 TALLOC_FREE( user );
277
278 *num_groups = (uint32)ngroups;
279 *user_gids = groups;
280
281 return result;
282}
283
284static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
285 TALLOC_CTX *mem_ctx,
286 uint32 num_sids, const DOM_SID *sids,
287 uint32 *p_num_aliases, uint32 **rids)
288{
289 NTSTATUS result;
290 size_t num_aliases = 0;
291
292 result = pdb_enum_alias_memberships(mem_ctx, &domain->sid,
293 sids, num_sids, rids, &num_aliases);
294
295 *p_num_aliases = num_aliases;
296 return result;
297}
298
299/* find the sequence number for a domain */
300static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
301{
302 bool result;
303 time_t seq_num;
304
305 result = pdb_get_seq_num(&seq_num);
306 if (!result) {
307 *seq = 1;
308 }
309
310 *seq = (int) seq_num;
311 /* *seq = 1; */
312 return NT_STATUS_OK;
313}
314
315static NTSTATUS lockout_policy(struct winbindd_domain *domain,
316 TALLOC_CTX *mem_ctx,
317 struct samr_DomInfo12 *policy)
318{
319 /* actually we have that */
320 return NT_STATUS_NOT_IMPLEMENTED;
321}
322
323static NTSTATUS password_policy(struct winbindd_domain *domain,
324 TALLOC_CTX *mem_ctx,
325 struct samr_DomInfo1 *policy)
326{
327 uint32 min_pass_len,pass_hist,password_properties;
328 time_t u_expire, u_min_age;
329 NTTIME nt_expire, nt_min_age;
330 uint32 account_policy_temp;
331
332 if ((policy = TALLOC_ZERO_P(mem_ctx, struct samr_DomInfo1)) == NULL) {
333 return NT_STATUS_NO_MEMORY;
334 }
335
336 if (!pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp)) {
337 return NT_STATUS_ACCESS_DENIED;
338 }
339 min_pass_len = account_policy_temp;
340
341 if (!pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp)) {
342 return NT_STATUS_ACCESS_DENIED;
343 }
344 pass_hist = account_policy_temp;
345
346 if (!pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp)) {
347 return NT_STATUS_ACCESS_DENIED;
348 }
349 password_properties = account_policy_temp;
350
351 if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp)) {
352 return NT_STATUS_ACCESS_DENIED;
353 }
354 u_expire = account_policy_temp;
355
356 if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp)) {
357 return NT_STATUS_ACCESS_DENIED;
358 }
359 u_min_age = account_policy_temp;
360
361 unix_to_nt_time_abs(&nt_expire, u_expire);
362 unix_to_nt_time_abs(&nt_min_age, u_min_age);
363
364 init_samr_DomInfo1(policy,
365 (uint16)min_pass_len,
366 (uint16)pass_hist,
367 password_properties,
368 nt_expire,
369 nt_min_age);
370
371 return NT_STATUS_OK;
372}
373
374/*********************************************************************
375 BUILTIN specific functions.
376*********************************************************************/
377
378/* list all domain groups */
379static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
380 TALLOC_CTX *mem_ctx,
381 uint32 *num_entries,
382 struct acct_info **info)
383{
384 /* BUILTIN doesn't have domain groups */
385 *num_entries = 0;
386 *info = NULL;
387 return NT_STATUS_OK;
388}
389
390/* Query display info for a domain. This returns enough information plus a
391 bit extra to give an overview of domain users for the User Manager
392 application. */
393static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
394 TALLOC_CTX *mem_ctx,
395 uint32 *num_entries,
396 WINBIND_USERINFO **info)
397{
398 /* We don't have users */
399 *num_entries = 0;
400 *info = NULL;
401 return NT_STATUS_OK;
402}
403
404/* Lookup user information from a rid or username. */
405static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
406 TALLOC_CTX *mem_ctx,
407 const DOM_SID *user_sid,
408 WINBIND_USERINFO *user_info)
409{
410 return NT_STATUS_NO_SUCH_USER;
411}
412
413static NTSTATUS builtin_lookup_groupmem(struct winbindd_domain *domain,
414 TALLOC_CTX *mem_ctx,
415 const DOM_SID *group_sid, uint32 *num_names,
416 DOM_SID **sid_mem, char ***names,
417 uint32 **name_types)
418{
419 *num_names = 0;
420 *sid_mem = NULL;
421 *names = NULL;
422 *name_types = 0;
423 return NT_STATUS_NO_SUCH_GROUP;
424}
425
426/* get a list of trusted domains - builtin domain */
427static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
428 TALLOC_CTX *mem_ctx,
429 uint32 *num_domains,
430 char ***names,
431 char ***alt_names,
432 DOM_SID **dom_sids)
433{
434 *num_domains = 0;
435 *names = NULL;
436 *alt_names = NULL;
437 *dom_sids = NULL;
438 return NT_STATUS_OK;
439}
440
441/*********************************************************************
442 SAM specific functions.
443*********************************************************************/
444
445/* list all domain groups */
446static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
447 TALLOC_CTX *mem_ctx,
448 uint32 *num_entries,
449 struct acct_info **info)
450{
451 return enum_groups_internal(domain,
452 mem_ctx,
453 num_entries,
454 info,
455 SID_NAME_DOM_GRP);
456}
457
458static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
459 TALLOC_CTX *mem_ctx,
460 uint32 *num_entries,
461 WINBIND_USERINFO **info)
462{
463 struct pdb_search *ps = pdb_search_users(ACB_NORMAL);
464 struct samr_displayentry *entries = NULL;
465 uint32 i;
466
467 *num_entries = 0;
468 *info = NULL;
469
470 if (!ps) {
471 return NT_STATUS_NO_MEMORY;
472 }
473
474 *num_entries = pdb_search_entries(ps,
475 1, 0xffffffff,
476 &entries);
477
478 *info = TALLOC_ZERO_ARRAY(mem_ctx, WINBIND_USERINFO, *num_entries);
479 if (!(*info)) {
480 pdb_search_destroy(ps);
481 return NT_STATUS_NO_MEMORY;
482 }
483
484 for (i = 0; i < *num_entries; i++) {
485 struct samr_displayentry *e = &entries[i];
486
487 (*info)[i].acct_name = talloc_strdup(mem_ctx, e->account_name );
488 (*info)[i].full_name = talloc_strdup(mem_ctx, e->fullname );
489 (*info)[i].homedir = NULL;
490 (*info)[i].shell = NULL;
491 sid_compose(&(*info)[i].user_sid, &domain->sid, e->rid);
492
493 /* For the moment we set the primary group for
494 every user to be the Domain Users group.
495 There are serious problems with determining
496 the actual primary group for large domains.
497 This should really be made into a 'winbind
498 force group' smb.conf parameter or
499 something like that. */
500
501 sid_compose(&(*info)[i].group_sid, &domain->sid,
502 DOMAIN_GROUP_RID_USERS);
503 }
504
505 pdb_search_destroy(ps);
506 return NT_STATUS_OK;
507}
508
509/* Lookup user information from a rid or username. */
510static NTSTATUS sam_query_user(struct winbindd_domain *domain,
511 TALLOC_CTX *mem_ctx,
512 const DOM_SID *user_sid,
513 WINBIND_USERINFO *user_info)
514{
515 struct samu *sampass = NULL;
516
517 ZERO_STRUCTP(user_info);
518
519 if (!sid_check_is_in_our_domain(user_sid)) {
520 return NT_STATUS_NO_SUCH_USER;
521 }
522
523 DEBUG(10,("sam_query_user: getting samu info for sid %s\n",
524 sid_string_dbg(user_sid) ));
525
526 if (!(sampass = samu_new(mem_ctx))) {
527 return NT_STATUS_NO_MEMORY;
528 }
529
530 if (!pdb_getsampwsid(sampass, user_sid)) {
531 TALLOC_FREE(sampass);
532 return NT_STATUS_NO_SUCH_USER;
533 }
534
535 if (pdb_get_group_sid(sampass) == NULL) {
536 TALLOC_FREE(sampass);
537 return NT_STATUS_NO_SUCH_GROUP;
538 }
539
540 DEBUG(10,("sam_query_user: group sid %s\n",
541 sid_string_dbg(sampass->group_sid) ));
542
543 sid_copy(&user_info->user_sid, user_sid);
544 sid_copy(&user_info->group_sid, sampass->group_sid);
545
546 user_info->acct_name = talloc_strdup(mem_ctx, sampass->username ?
547 sampass->username : "");
548 user_info->full_name = talloc_strdup(mem_ctx, sampass->full_name ?
549 sampass->full_name : "");
550 user_info->homedir = talloc_strdup(mem_ctx, sampass->home_dir ?
551 sampass->home_dir : "");
552 if (sampass->unix_pw && sampass->unix_pw->pw_shell) {
553 user_info->shell = talloc_strdup(mem_ctx, sampass->unix_pw->pw_shell);
554 } else {
555 user_info->shell = talloc_strdup(mem_ctx, "");
556 }
557 user_info->primary_gid = sampass->unix_pw ? sampass->unix_pw->pw_gid : (gid_t)-1;
558
559 TALLOC_FREE(sampass);
560 return NT_STATUS_OK;
561}
562
563/* Lookup group membership given a rid. */
564static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
565 TALLOC_CTX *mem_ctx,
566 const DOM_SID *group_sid, uint32 *num_names,
567 DOM_SID **sid_mem, char ***names,
568 uint32 **name_types)
569{
570 size_t i, num_members, num_mapped;
571 uint32 *rids;
572 NTSTATUS result;
573 const DOM_SID **sids;
574 struct lsa_dom_info *lsa_domains;
575 struct lsa_name_info *lsa_names;
576 TALLOC_CTX *tmp_ctx;
577
578 if (!sid_check_is_in_our_domain(group_sid)) {
579 /* There's no groups, only aliases in BUILTIN */
580 return NT_STATUS_NO_SUCH_GROUP;
581 }
582
583 if (!(tmp_ctx = talloc_init("lookup_groupmem"))) {
584 return NT_STATUS_NO_MEMORY;
585 }
586
587 result = pdb_enum_group_members(tmp_ctx, group_sid, &rids,
588 &num_members);
589 if (!NT_STATUS_IS_OK(result)) {
590 TALLOC_FREE(tmp_ctx);
591 return result;
592 }
593
594 if (num_members == 0) {
595 *num_names = 0;
596 *sid_mem = NULL;
597 *names = NULL;
598 *name_types = NULL;
599 TALLOC_FREE(tmp_ctx);
600 return NT_STATUS_OK;
601 }
602
603 *sid_mem = TALLOC_ARRAY(mem_ctx, DOM_SID, num_members);
604 *names = TALLOC_ARRAY(mem_ctx, char *, num_members);
605 *name_types = TALLOC_ARRAY(mem_ctx, uint32, num_members);
606 sids = TALLOC_ARRAY(tmp_ctx, const DOM_SID *, num_members);
607
608 if (((*sid_mem) == NULL) || ((*names) == NULL) ||
609 ((*name_types) == NULL) || (sids == NULL)) {
610 TALLOC_FREE(tmp_ctx);
611 return NT_STATUS_NO_MEMORY;
612 }
613
614 /*
615 * Prepare an array of sid pointers for the lookup_sids calling
616 * convention.
617 */
618
619 for (i=0; i<num_members; i++) {
620 DOM_SID *sid = &((*sid_mem)[i]);
621 if (!sid_compose(sid, &domain->sid, rids[i])) {
622 TALLOC_FREE(tmp_ctx);
623 return NT_STATUS_INTERNAL_ERROR;
624 }
625 sids[i] = sid;
626 }
627
628 result = lookup_sids(tmp_ctx, num_members, sids, 1,
629 &lsa_domains, &lsa_names);
630 if (!NT_STATUS_IS_OK(result)) {
631 TALLOC_FREE(tmp_ctx);
632 return result;
633 }
634
635 num_mapped = 0;
636 for (i=0; i<num_members; i++) {
637 if (lsa_names[i].type != SID_NAME_USER) {
638 DEBUG(2, ("Got %s as group member -- ignoring\n",
639 sid_type_lookup(lsa_names[i].type)));
640 continue;
641 }
642 if (!((*names)[num_mapped] = talloc_strdup((*names),
643 lsa_names[i].name))) {
644 TALLOC_FREE(tmp_ctx);
645 return NT_STATUS_NO_MEMORY;
646 }
647
648 (*name_types)[num_mapped] = lsa_names[i].type;
649
650 num_mapped += 1;
651 }
652
653 *num_names = num_mapped;
654
655 TALLOC_FREE(tmp_ctx);
656 return NT_STATUS_OK;
657}
658
659/* get a list of trusted domains */
660static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
661 TALLOC_CTX *mem_ctx,
662 uint32 *num_domains,
663 char ***names,
664 char ***alt_names,
665 DOM_SID **dom_sids)
666{
667 NTSTATUS nt_status;
668 struct trustdom_info **domains;
669 int i;
670 TALLOC_CTX *tmp_ctx;
671
672 *num_domains = 0;
673 *names = NULL;
674 *alt_names = NULL;
675 *dom_sids = NULL;
676
677 if (!(tmp_ctx = talloc_init("trusted_domains"))) {
678 return NT_STATUS_NO_MEMORY;
679 }
680
681 nt_status = pdb_enum_trusteddoms(tmp_ctx, num_domains, &domains);
682 if (!NT_STATUS_IS_OK(nt_status)) {
683 TALLOC_FREE(tmp_ctx);
684 return nt_status;
685 }
686
687 if (*num_domains) {
688 *names = TALLOC_ARRAY(mem_ctx, char *, *num_domains);
689 *alt_names = TALLOC_ARRAY(mem_ctx, char *, *num_domains);
690 *dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_domains);
691
692 if ((*alt_names == NULL) || (*names == NULL) || (*dom_sids == NULL)) {
693 TALLOC_FREE(tmp_ctx);
694 return NT_STATUS_NO_MEMORY;
695 }
696 } else {
697 *names = NULL;
698 *alt_names = NULL;
699 *dom_sids = NULL;
700 }
701
702 for (i=0; i<*num_domains; i++) {
703 (*alt_names)[i] = NULL;
704 if (!((*names)[i] = talloc_strdup((*names),
705 domains[i]->name))) {
706 TALLOC_FREE(tmp_ctx);
707 return NT_STATUS_NO_MEMORY;
708 }
709 sid_copy(&(*dom_sids)[i], &domains[i]->sid);
710 }
711
712 TALLOC_FREE(tmp_ctx);
713 return NT_STATUS_OK;
714}
715
716/* the rpc backend methods are exposed via this structure */
717struct winbindd_methods builtin_passdb_methods = {
718 false,
719 builtin_query_user_list,
720 builtin_enum_dom_groups,
721 enum_local_groups,
722 name_to_sid,
723 sid_to_name,
724 rids_to_names,
725 builtin_query_user,
726 lookup_usergroups,
727 lookup_useraliases,
728 builtin_lookup_groupmem,
729 sequence_number,
730 lockout_policy,
731 password_policy,
732 builtin_trusted_domains,
733};
734
735/* the rpc backend methods are exposed via this structure */
736struct winbindd_methods sam_passdb_methods = {
737 false,
738 sam_query_user_list,
739 sam_enum_dom_groups,
740 enum_local_groups,
741 name_to_sid,
742 sid_to_name,
743 rids_to_names,
744 sam_query_user,
745 lookup_usergroups,
746 lookup_useraliases,
747 sam_lookup_groupmem,
748 sequence_number,
749 lockout_policy,
750 password_policy,
751 sam_trusted_domains,
752};
Note: See TracBrowser for help on using the repository browser.