r14156: Fix coverity #114: free storage alloc'ed by sstring_sub()
[Samba/nascimento.git] / source3 / nsswitch / winbindd_rpc.c
blob4aaedad4a216cbfd8d0d4a155dfe4b808ff6d34c
1 /*
2 Unix SMB/CIFS implementation.
4 Winbind rpc backend functions
6 Copyright (C) Tim Potter 2000-2001,2003
7 Copyright (C) Andrew Tridgell 2001
8 Copyright (C) Volker Lendecke 2005
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.
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.
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.
25 #include "includes.h"
26 #include "winbindd.h"
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_WINBIND
32 /* Query display info for a domain. This returns enough information plus a
33 bit extra to give an overview of domain users for the User Manager
34 application. */
35 static NTSTATUS query_user_list(struct winbindd_domain *domain,
36 TALLOC_CTX *mem_ctx,
37 uint32 *num_entries,
38 WINBIND_USERINFO **info)
40 NTSTATUS result;
41 POLICY_HND dom_pol;
42 unsigned int i, start_idx;
43 uint32 loop_count;
44 struct rpc_pipe_client *cli;
46 DEBUG(3,("rpc: query_user_list\n"));
48 *num_entries = 0;
49 *info = NULL;
51 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
52 if (!NT_STATUS_IS_OK(result))
53 return result;
55 i = start_idx = 0;
56 loop_count = 0;
58 do {
59 TALLOC_CTX *ctx2;
60 uint32 num_dom_users, j;
61 uint32 max_entries, max_size;
62 SAM_DISPINFO_CTR ctr;
63 SAM_DISPINFO_1 info1;
65 ZERO_STRUCT( ctr );
66 ZERO_STRUCT( info1 );
67 ctr.sam.info1 = &info1;
69 if (!(ctx2 = talloc_init("winbindd enum_users")))
70 return NT_STATUS_NO_MEMORY;
72 /* this next bit is copied from net_user_list_internal() */
74 get_query_dispinfo_params(loop_count, &max_entries,
75 &max_size);
77 result = rpccli_samr_query_dispinfo(cli, mem_ctx, &dom_pol,
78 &start_idx, 1,
79 &num_dom_users,
80 max_entries, max_size,
81 &ctr);
83 loop_count++;
85 *num_entries += num_dom_users;
87 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, WINBIND_USERINFO,
88 *num_entries);
90 if (!(*info)) {
91 talloc_destroy(ctx2);
92 return NT_STATUS_NO_MEMORY;
95 for (j = 0; j < num_dom_users; i++, j++) {
96 fstring username, fullname;
97 uint32 rid = ctr.sam.info1->sam[j].rid_user;
99 unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username)-1);
100 unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname)-1);
102 (*info)[i].acct_name = talloc_strdup(mem_ctx, username );
103 (*info)[i].full_name = talloc_strdup(mem_ctx, fullname );
104 (*info)[i].homedir = NULL;
105 (*info)[i].shell = NULL;
106 sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
108 /* For the moment we set the primary group for
109 every user to be the Domain Users group.
110 There are serious problems with determining
111 the actual primary group for large domains.
112 This should really be made into a 'winbind
113 force group' smb.conf parameter or
114 something like that. */
116 sid_compose(&(*info)[i].group_sid, &domain->sid,
117 DOMAIN_GROUP_RID_USERS);
120 talloc_destroy(ctx2);
122 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
124 return result;
127 /* list all domain groups */
128 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
129 TALLOC_CTX *mem_ctx,
130 uint32 *num_entries,
131 struct acct_info **info)
133 POLICY_HND dom_pol;
134 NTSTATUS status;
135 uint32 start = 0;
136 struct rpc_pipe_client *cli;
138 *num_entries = 0;
139 *info = NULL;
141 DEBUG(3,("rpc: enum_dom_groups\n"));
143 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
144 if (!NT_STATUS_IS_OK(status))
145 return status;
147 do {
148 struct acct_info *info2 = NULL;
149 uint32 count = 0;
150 TALLOC_CTX *mem_ctx2;
152 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
154 /* start is updated by this call. */
155 status = rpccli_samr_enum_dom_groups(cli, mem_ctx2, &dom_pol,
156 &start,
157 0xFFFF, /* buffer size? */
158 &info2, &count);
160 if (!NT_STATUS_IS_OK(status) &&
161 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
162 talloc_destroy(mem_ctx2);
163 break;
166 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
167 struct acct_info,
168 (*num_entries) + count);
169 if (! *info) {
170 talloc_destroy(mem_ctx2);
171 status = NT_STATUS_NO_MEMORY;
172 break;
175 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
176 (*num_entries) += count;
177 talloc_destroy(mem_ctx2);
178 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
180 return NT_STATUS_OK;
183 /* List all domain groups */
185 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
186 TALLOC_CTX *mem_ctx,
187 uint32 *num_entries,
188 struct acct_info **info)
190 POLICY_HND dom_pol;
191 NTSTATUS result;
192 struct rpc_pipe_client *cli;
194 *num_entries = 0;
195 *info = NULL;
197 DEBUG(3,("rpc: enum_local_groups\n"));
199 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
200 if (!NT_STATUS_IS_OK(result))
201 return result;
203 do {
204 struct acct_info *info2 = NULL;
205 uint32 count = 0, start = *num_entries;
206 TALLOC_CTX *mem_ctx2;
208 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
210 result = rpccli_samr_enum_als_groups( cli, mem_ctx2, &dom_pol,
211 &start, 0xFFFF, &info2,
212 &count);
214 if (!NT_STATUS_IS_OK(result) &&
215 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
217 talloc_destroy(mem_ctx2);
218 return result;
221 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
222 struct acct_info,
223 (*num_entries) + count);
224 if (! *info) {
225 talloc_destroy(mem_ctx2);
226 return NT_STATUS_NO_MEMORY;
229 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
230 (*num_entries) += count;
231 talloc_destroy(mem_ctx2);
233 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
235 return NT_STATUS_OK;
238 /* convert a single name to a sid in a domain */
239 NTSTATUS msrpc_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)
246 NTSTATUS result;
247 DOM_SID *sids = NULL;
248 uint32 *types = NULL;
249 const char *full_name;
250 struct rpc_pipe_client *cli;
251 POLICY_HND lsa_policy;
253 if(name == NULL || *name=='\0') {
254 DEBUG(3,("rpc: name_to_sid name=%s\n", domain_name));
255 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
256 } else {
257 DEBUG(3,("rpc: name_to_sid name=%s\\%s\n", domain_name, name));
258 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
260 if (!full_name) {
261 DEBUG(0, ("talloc_asprintf failed!\n"));
262 return NT_STATUS_NO_MEMORY;
265 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", name?name:"", domain_name ));
267 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
268 if (!NT_STATUS_IS_OK(result))
269 return result;
271 result = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, 1,
272 &full_name, NULL, &sids, &types);
274 if (!NT_STATUS_IS_OK(result))
275 return result;
277 /* Return rid and type if lookup successful */
279 sid_copy(sid, &sids[0]);
280 *type = (enum SID_NAME_USE)types[0];
282 return NT_STATUS_OK;
286 convert a domain SID to a user or group name
288 NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
289 TALLOC_CTX *mem_ctx,
290 const DOM_SID *sid,
291 char **domain_name,
292 char **name,
293 enum SID_NAME_USE *type)
295 char **domains;
296 char **names;
297 uint32 *types;
298 NTSTATUS result;
299 struct rpc_pipe_client *cli;
300 POLICY_HND lsa_policy;
302 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid),
303 domain->name ));
305 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
306 if (!NT_STATUS_IS_OK(result))
307 return result;
309 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
310 1, sid, &domains, &names, &types);
311 if (!NT_STATUS_IS_OK(result))
312 return result;
314 *type = (enum SID_NAME_USE)types[0];
315 *domain_name = domains[0];
316 *name = names[0];
317 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
318 return NT_STATUS_OK;
321 /* Lookup user information from a rid or username. */
322 static NTSTATUS query_user(struct winbindd_domain *domain,
323 TALLOC_CTX *mem_ctx,
324 const DOM_SID *user_sid,
325 WINBIND_USERINFO *user_info)
327 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
328 POLICY_HND dom_pol, user_pol;
329 SAM_USERINFO_CTR *ctr;
330 fstring sid_string;
331 uint32 user_rid;
332 NET_USER_INFO_3 *user;
333 struct rpc_pipe_client *cli;
335 DEBUG(3,("rpc: query_user rid=%s\n",
336 sid_to_string(sid_string, user_sid)));
338 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
339 return NT_STATUS_UNSUCCESSFUL;
341 /* try netsamlogon cache first */
343 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
346 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
347 sid_string_static(user_sid)));
349 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
350 sid_compose(&user_info->group_sid, &domain->sid,
351 user->group_rid);
353 user_info->acct_name = unistr2_tdup(mem_ctx,
354 &user->uni_user_name);
355 user_info->full_name = unistr2_tdup(mem_ctx,
356 &user->uni_full_name);
358 user_info->homedir = NULL;
359 user_info->shell = NULL;
361 SAFE_FREE(user);
363 return NT_STATUS_OK;
366 /* no cache; hit the wire */
368 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
369 if (!NT_STATUS_IS_OK(result))
370 return result;
372 /* Get user handle */
373 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
374 SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid,
375 &user_pol);
377 if (!NT_STATUS_IS_OK(result))
378 return result;
380 /* Get user info */
381 result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
382 0x15, &ctr);
384 rpccli_samr_close(cli, mem_ctx, &user_pol);
386 if (!NT_STATUS_IS_OK(result))
387 return result;
389 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
390 sid_compose(&user_info->group_sid, &domain->sid,
391 ctr->info.id21->group_rid);
392 user_info->acct_name = unistr2_tdup(mem_ctx,
393 &ctr->info.id21->uni_user_name);
394 user_info->full_name = unistr2_tdup(mem_ctx,
395 &ctr->info.id21->uni_full_name);
396 user_info->homedir = NULL;
397 user_info->shell = NULL;
399 return NT_STATUS_OK;
402 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
403 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
404 TALLOC_CTX *mem_ctx,
405 const DOM_SID *user_sid,
406 uint32 *num_groups, DOM_SID **user_grpsids)
408 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
409 POLICY_HND dom_pol, user_pol;
410 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
411 DOM_GID *user_groups;
412 unsigned int i;
413 fstring sid_string;
414 uint32 user_rid;
415 NET_USER_INFO_3 *user;
416 struct rpc_pipe_client *cli;
418 DEBUG(3,("rpc: lookup_usergroups sid=%s\n",
419 sid_to_string(sid_string, user_sid)));
421 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
422 return NT_STATUS_UNSUCCESSFUL;
424 *num_groups = 0;
425 *user_grpsids = NULL;
427 /* so lets see if we have a cached user_info_3 */
429 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
431 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
432 sid_string_static(user_sid)));
434 *num_groups = user->num_groups;
436 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
437 for (i=0;i<(*num_groups);i++) {
438 sid_copy(&((*user_grpsids)[i]), &domain->sid);
439 sid_append_rid(&((*user_grpsids)[i]),
440 user->gids[i].g_rid);
443 SAFE_FREE(user);
445 return NT_STATUS_OK;
448 /* no cache; hit the wire */
450 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
451 if (!NT_STATUS_IS_OK(result))
452 return result;
454 /* Get user handle */
455 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
456 des_access, user_rid, &user_pol);
458 if (!NT_STATUS_IS_OK(result))
459 return result;
461 /* Query user rids */
462 result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
463 num_groups, &user_groups);
465 rpccli_samr_close(cli, mem_ctx, &user_pol);
467 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
468 return result;
470 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
471 if (!(*user_grpsids))
472 return NT_STATUS_NO_MEMORY;
474 for (i=0;i<(*num_groups);i++) {
475 sid_copy(&((*user_grpsids)[i]), &domain->sid);
476 sid_append_rid(&((*user_grpsids)[i]),
477 user_groups[i].g_rid);
480 return NT_STATUS_OK;
483 NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
484 TALLOC_CTX *mem_ctx,
485 uint32 num_sids, const DOM_SID *sids,
486 uint32 *num_aliases, uint32 **alias_rids)
488 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
489 POLICY_HND dom_pol;
490 DOM_SID2 *sid2;
491 int i;
492 struct rpc_pipe_client *cli;
494 *num_aliases = 0;
495 *alias_rids = NULL;
497 DEBUG(3,("rpc: lookup_useraliases\n"));
499 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
500 if (!NT_STATUS_IS_OK(result))
501 return result;
503 sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
505 if (sid2 == NULL)
506 return NT_STATUS_NO_MEMORY;
508 for (i=0; i<num_sids; i++) {
509 sid_copy(&sid2[i].sid, &sids[i]);
510 sid2[i].num_auths = sid2[i].sid.num_auths;
513 result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,
514 num_sids, sid2,
515 num_aliases, alias_rids);
517 return result;
521 /* Lookup group membership given a rid. */
522 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
523 TALLOC_CTX *mem_ctx,
524 const DOM_SID *group_sid, uint32 *num_names,
525 DOM_SID **sid_mem, char ***names,
526 uint32 **name_types)
528 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
529 uint32 i, total_names = 0;
530 POLICY_HND dom_pol, group_pol;
531 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
532 uint32 *rid_mem = NULL;
533 uint32 group_rid;
534 unsigned int j;
535 fstring sid_string;
536 struct rpc_pipe_client *cli;
538 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
539 sid_to_string(sid_string, group_sid)));
541 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
542 return NT_STATUS_UNSUCCESSFUL;
544 *num_names = 0;
546 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
547 if (!NT_STATUS_IS_OK(result))
548 return result;
550 result = rpccli_samr_open_group(cli, mem_ctx, &dom_pol,
551 des_access, group_rid, &group_pol);
553 if (!NT_STATUS_IS_OK(result))
554 return result;
556 /* Step #1: Get a list of user rids that are the members of the
557 group. */
559 result = rpccli_samr_query_groupmem(cli, mem_ctx,
560 &group_pol, num_names, &rid_mem,
561 name_types);
563 rpccli_samr_close(cli, mem_ctx, &group_pol);
565 if (!NT_STATUS_IS_OK(result))
566 return result;
568 if (!*num_names) {
569 names = NULL;
570 name_types = NULL;
571 sid_mem = NULL;
572 return NT_STATUS_OK;
575 /* Step #2: Convert list of rids into list of usernames. Do this
576 in bunches of ~1000 to avoid crashing NT4. It looks like there
577 is a buffer overflow or something like that lurking around
578 somewhere. */
580 #define MAX_LOOKUP_RIDS 900
582 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
583 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
584 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
586 for (j=0;j<(*num_names);j++)
587 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
589 if (*num_names>0 && (!*names || !*name_types))
590 return NT_STATUS_NO_MEMORY;
592 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
593 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
594 uint32 tmp_num_names = 0;
595 char **tmp_names = NULL;
596 uint32 *tmp_types = NULL;
598 /* Lookup a chunk of rids */
600 result = rpccli_samr_lookup_rids(cli, mem_ctx,
601 &dom_pol,
602 num_lookup_rids,
603 &rid_mem[i],
604 &tmp_num_names,
605 &tmp_names, &tmp_types);
607 /* see if we have a real error (and yes the
608 STATUS_SOME_UNMAPPED is the one returned from 2k) */
610 if (!NT_STATUS_IS_OK(result) &&
611 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
612 return result;
614 /* Copy result into array. The talloc system will take
615 care of freeing the temporary arrays later on. */
617 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
618 tmp_num_names);
620 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
621 tmp_num_names);
623 total_names += tmp_num_names;
626 *num_names = total_names;
628 return NT_STATUS_OK;
631 #ifdef HAVE_LDAP
633 #include <ldap.h>
635 static int get_ldap_seq(const char *server, int port, uint32 *seq)
637 int ret = -1;
638 struct timeval to;
639 const char *attrs[] = {"highestCommittedUSN", NULL};
640 LDAPMessage *res = NULL;
641 char **values = NULL;
642 LDAP *ldp = NULL;
644 *seq = DOM_SEQUENCE_NONE;
647 * Parameterised (5) second timeout on open. This is needed as the
648 * search timeout doesn't seem to apply to doing an open as well. JRA.
651 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
652 if (ldp == NULL)
653 return -1;
655 /* Timeout if no response within 20 seconds. */
656 to.tv_sec = 10;
657 to.tv_usec = 0;
659 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
660 CONST_DISCARD(char **, attrs), 0, &to, &res))
661 goto done;
663 if (ldap_count_entries(ldp, res) != 1)
664 goto done;
666 values = ldap_get_values(ldp, res, "highestCommittedUSN");
667 if (!values || !values[0])
668 goto done;
670 *seq = atoi(values[0]);
671 ret = 0;
673 done:
675 if (values)
676 ldap_value_free(values);
677 if (res)
678 ldap_msgfree(res);
679 if (ldp)
680 ldap_unbind(ldp);
681 return ret;
684 /**********************************************************************
685 Get the sequence number for a Windows AD native mode domain using
686 LDAP queries
687 **********************************************************************/
689 static int get_ldap_sequence_number( const char* domain, uint32 *seq)
691 int ret = -1;
692 int i, port = LDAP_PORT;
693 struct ip_service *ip_list = NULL;
694 int count;
696 if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
697 DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
698 return False;
701 /* Finally return first DC that we can contact */
703 for (i = 0; i < count; i++) {
704 fstring ipstr;
706 /* since the is an LDAP lookup, default to the LDAP_PORT is
707 * not set */
708 port = (ip_list[i].port!= PORT_NONE) ?
709 ip_list[i].port : LDAP_PORT;
711 fstrcpy( ipstr, inet_ntoa(ip_list[i].ip) );
713 if (is_zero_ip(ip_list[i].ip))
714 continue;
716 if ( (ret = get_ldap_seq( ipstr, port, seq)) == 0 )
717 goto done;
719 /* add to failed connection cache */
720 add_failed_connection_entry( domain, ipstr,
721 NT_STATUS_UNSUCCESSFUL );
724 done:
725 if ( ret == 0 ) {
726 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
727 "number for Domain (%s) from DC (%s:%d)\n",
728 domain, inet_ntoa(ip_list[i].ip), port));
731 SAFE_FREE(ip_list);
733 return ret;
736 #endif /* HAVE_LDAP */
738 /* find the sequence number for a domain */
739 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
741 TALLOC_CTX *mem_ctx;
742 SAM_UNK_CTR ctr;
743 NTSTATUS result;
744 POLICY_HND dom_pol;
745 BOOL got_seq_num = False;
746 int retry;
747 struct rpc_pipe_client *cli;
749 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
751 *seq = DOM_SEQUENCE_NONE;
753 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
754 return NT_STATUS_NO_MEMORY;
756 retry = 0;
758 #ifdef HAVE_LDAP
759 if ( domain->native_mode )
761 int res;
763 DEBUG(8,("using get_ldap_seq() to retrieve the "
764 "sequence number\n"));
766 res = get_ldap_sequence_number( domain->name, seq );
767 if (res == 0)
769 result = NT_STATUS_OK;
770 DEBUG(10,("domain_sequence_number: LDAP for "
771 "domain %s is %u\n",
772 domain->name, *seq));
773 goto done;
776 DEBUG(10,("domain_sequence_number: failed to get LDAP "
777 "sequence number for domain %s\n",
778 domain->name ));
780 #endif /* HAVE_LDAP */
782 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
783 if (!NT_STATUS_IS_OK(result)) {
784 goto done;
787 /* Query domain info */
789 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 8, &ctr);
791 if (NT_STATUS_IS_OK(result)) {
792 *seq = ctr.info.inf8.seq_num.low;
793 got_seq_num = True;
794 goto seq_num;
797 /* retry with info-level 2 in case the dc does not support info-level 8
798 * (like all older samba2 and samba3 dc's - Guenther */
800 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 2, &ctr);
802 if (NT_STATUS_IS_OK(result)) {
803 *seq = ctr.info.inf2.seq_num.low;
804 got_seq_num = True;
807 seq_num:
808 if (got_seq_num) {
809 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
810 domain->name, (unsigned)*seq));
811 } else {
812 DEBUG(10,("domain_sequence_number: failed to get sequence "
813 "number (%u) for domain %s\n",
814 (unsigned)*seq, domain->name ));
817 done:
819 talloc_destroy(mem_ctx);
821 return result;
824 /* get a list of trusted domains */
825 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
826 TALLOC_CTX *mem_ctx,
827 uint32 *num_domains,
828 char ***names,
829 char ***alt_names,
830 DOM_SID **dom_sids)
832 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
833 uint32 enum_ctx = 0;
834 struct rpc_pipe_client *cli;
835 POLICY_HND lsa_policy;
837 DEBUG(3,("rpc: trusted_domains\n"));
839 *num_domains = 0;
840 *names = NULL;
841 *alt_names = NULL;
842 *dom_sids = NULL;
844 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
845 if (!NT_STATUS_IS_OK(result))
846 return result;
848 result = STATUS_MORE_ENTRIES;
850 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
851 uint32 start_idx, num;
852 char **tmp_names;
853 DOM_SID *tmp_sids;
854 int i;
856 result = rpccli_lsa_enum_trust_dom(cli, mem_ctx,
857 &lsa_policy, &enum_ctx,
858 &num, &tmp_names,
859 &tmp_sids);
861 if (!NT_STATUS_IS_OK(result) &&
862 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
863 break;
865 start_idx = *num_domains;
866 *num_domains += num;
867 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
868 char *, *num_domains);
869 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
870 DOM_SID, *num_domains);
871 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
872 char *, *num_domains);
873 if ((*names == NULL) || (*dom_sids == NULL) ||
874 (*alt_names == NULL))
875 return NT_STATUS_NO_MEMORY;
877 for (i=0; i<num; i++) {
878 (*names)[start_idx+i] = tmp_names[i];
879 (*dom_sids)[start_idx+i] = tmp_sids[i];
880 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
883 return result;
886 /* find the lockout policy for a domain */
887 NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
888 TALLOC_CTX *mem_ctx,
889 SAM_UNK_INFO_12 *lockout_policy)
891 NTSTATUS result;
892 struct rpc_pipe_client *cli;
893 POLICY_HND dom_pol;
894 SAM_UNK_CTR ctr;
896 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
898 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
899 if (!NT_STATUS_IS_OK(result)) {
900 goto done;
903 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 12, &ctr);
904 if (!NT_STATUS_IS_OK(result)) {
905 goto done;
908 *lockout_policy = ctr.info.inf12;
910 DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n",
911 ctr.info.inf12.bad_attempt_lockout));
913 done:
915 return result;
918 /* find the password policy for a domain */
919 NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
920 TALLOC_CTX *mem_ctx,
921 SAM_UNK_INFO_1 *password_policy)
923 NTSTATUS result;
924 struct rpc_pipe_client *cli;
925 POLICY_HND dom_pol;
926 SAM_UNK_CTR ctr;
928 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
930 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
931 if (!NT_STATUS_IS_OK(result)) {
932 goto done;
935 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 1, &ctr);
936 if (!NT_STATUS_IS_OK(result)) {
937 goto done;
940 *password_policy = ctr.info.inf1;
942 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
943 ctr.info.inf1.min_length_password));
945 done:
947 return result;
951 /* the rpc backend methods are exposed via this structure */
952 struct winbindd_methods msrpc_methods = {
953 False,
954 query_user_list,
955 enum_dom_groups,
956 enum_local_groups,
957 msrpc_name_to_sid,
958 msrpc_sid_to_name,
959 query_user,
960 lookup_usergroups,
961 msrpc_lookup_useraliases,
962 lookup_groupmem,
963 sequence_number,
964 msrpc_lockout_policy,
965 msrpc_password_policy,
966 trusted_domains,