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