r16418: Pull in more Klocwork fixes (up to r16415)
[Samba/gbeck.git] / source / nsswitch / winbindd_rpc.c
blob984c5cd8415f74835ec83b93cf297f0007107d25
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", full_name?full_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 struct rpc_pipe_client *cli;
417 DEBUG(3,("rpc: lookup_usergroups sid=%s\n",
418 sid_to_string(sid_string, user_sid)));
420 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
421 return NT_STATUS_UNSUCCESSFUL;
423 *num_groups = 0;
424 *user_grpsids = NULL;
426 /* so lets see if we have a cached user_info_3 */
427 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
428 num_groups, user_grpsids);
430 if (NT_STATUS_IS_OK(result)) {
431 return NT_STATUS_OK;
434 /* no cache; hit the wire */
436 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
437 if (!NT_STATUS_IS_OK(result))
438 return result;
440 /* Get user handle */
441 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
442 des_access, user_rid, &user_pol);
444 if (!NT_STATUS_IS_OK(result))
445 return result;
447 /* Query user rids */
448 result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
449 num_groups, &user_groups);
451 rpccli_samr_close(cli, mem_ctx, &user_pol);
453 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
454 return result;
456 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
457 if (!(*user_grpsids))
458 return NT_STATUS_NO_MEMORY;
460 for (i=0;i<(*num_groups);i++) {
461 sid_copy(&((*user_grpsids)[i]), &domain->sid);
462 sid_append_rid(&((*user_grpsids)[i]),
463 user_groups[i].g_rid);
466 return NT_STATUS_OK;
469 NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
470 TALLOC_CTX *mem_ctx,
471 uint32 num_sids, const DOM_SID *sids,
472 uint32 *num_aliases, uint32 **alias_rids)
474 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
475 POLICY_HND dom_pol;
476 DOM_SID2 *query_sids;
477 uint32 num_query_sids = 0;
478 int i;
479 struct rpc_pipe_client *cli;
480 uint32 *alias_rids_query, num_aliases_query;
481 int rangesize = MAX_SAM_ENTRIES_W2K;
482 uint32 total_sids = 0;
483 int num_queries = 1;
485 *num_aliases = 0;
486 *alias_rids = NULL;
488 DEBUG(3,("rpc: lookup_useraliases\n"));
490 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
491 if (!NT_STATUS_IS_OK(result))
492 return result;
494 do {
495 /* prepare query */
497 num_query_sids = MIN(num_sids - total_sids, rangesize);
499 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
500 num_queries, num_query_sids));
503 query_sids = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_query_sids);
504 if (query_sids == NULL) {
505 return NT_STATUS_NO_MEMORY;
508 for (i=0; i<num_query_sids; i++) {
509 sid_copy(&query_sids[i].sid, &sids[total_sids++]);
510 query_sids[i].num_auths = query_sids[i].sid.num_auths;
513 /* do request */
515 result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,
516 num_query_sids, query_sids,
517 &num_aliases_query,
518 &alias_rids_query);
520 if (!NT_STATUS_IS_OK(result)) {
521 *num_aliases = 0;
522 *alias_rids = NULL;
523 TALLOC_FREE(query_sids);
524 goto done;
527 /* process output */
529 for (i=0; i<num_aliases_query; i++) {
530 size_t na = *num_aliases;
531 add_rid_to_array_unique(mem_ctx, alias_rids_query[i],
532 alias_rids, &na);
533 *num_aliases = na;
536 TALLOC_FREE(query_sids);
538 num_queries++;
540 } while (total_sids < num_sids);
542 done:
543 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
544 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
546 return result;
550 /* Lookup group membership given a rid. */
551 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
552 TALLOC_CTX *mem_ctx,
553 const DOM_SID *group_sid, uint32 *num_names,
554 DOM_SID **sid_mem, char ***names,
555 uint32 **name_types)
557 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
558 uint32 i, total_names = 0;
559 POLICY_HND dom_pol, group_pol;
560 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
561 uint32 *rid_mem = NULL;
562 uint32 group_rid;
563 unsigned int j;
564 fstring sid_string;
565 struct rpc_pipe_client *cli;
567 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
568 sid_to_string(sid_string, group_sid)));
570 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
571 return NT_STATUS_UNSUCCESSFUL;
573 *num_names = 0;
575 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
576 if (!NT_STATUS_IS_OK(result))
577 return result;
579 result = rpccli_samr_open_group(cli, mem_ctx, &dom_pol,
580 des_access, group_rid, &group_pol);
582 if (!NT_STATUS_IS_OK(result))
583 return result;
585 /* Step #1: Get a list of user rids that are the members of the
586 group. */
588 result = rpccli_samr_query_groupmem(cli, mem_ctx,
589 &group_pol, num_names, &rid_mem,
590 name_types);
592 rpccli_samr_close(cli, mem_ctx, &group_pol);
594 if (!NT_STATUS_IS_OK(result))
595 return result;
597 if (!*num_names) {
598 names = NULL;
599 name_types = NULL;
600 sid_mem = NULL;
601 return NT_STATUS_OK;
604 /* Step #2: Convert list of rids into list of usernames. Do this
605 in bunches of ~1000 to avoid crashing NT4. It looks like there
606 is a buffer overflow or something like that lurking around
607 somewhere. */
609 #define MAX_LOOKUP_RIDS 900
611 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
612 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
613 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
615 for (j=0;j<(*num_names);j++)
616 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
618 if (*num_names>0 && (!*names || !*name_types))
619 return NT_STATUS_NO_MEMORY;
621 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
622 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
623 uint32 tmp_num_names = 0;
624 char **tmp_names = NULL;
625 uint32 *tmp_types = NULL;
627 /* Lookup a chunk of rids */
629 result = rpccli_samr_lookup_rids(cli, mem_ctx,
630 &dom_pol,
631 num_lookup_rids,
632 &rid_mem[i],
633 &tmp_num_names,
634 &tmp_names, &tmp_types);
636 /* see if we have a real error (and yes the
637 STATUS_SOME_UNMAPPED is the one returned from 2k) */
639 if (!NT_STATUS_IS_OK(result) &&
640 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
641 return result;
643 /* Copy result into array. The talloc system will take
644 care of freeing the temporary arrays later on. */
646 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
647 tmp_num_names);
649 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
650 tmp_num_names);
652 total_names += tmp_num_names;
655 *num_names = total_names;
657 return NT_STATUS_OK;
660 #ifdef HAVE_LDAP
662 #include <ldap.h>
664 static int get_ldap_seq(const char *server, int port, uint32 *seq)
666 int ret = -1;
667 struct timeval to;
668 const char *attrs[] = {"highestCommittedUSN", NULL};
669 LDAPMessage *res = NULL;
670 char **values = NULL;
671 LDAP *ldp = NULL;
673 *seq = DOM_SEQUENCE_NONE;
676 * Parameterised (5) second timeout on open. This is needed as the
677 * search timeout doesn't seem to apply to doing an open as well. JRA.
680 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
681 if (ldp == NULL)
682 return -1;
684 /* Timeout if no response within 20 seconds. */
685 to.tv_sec = 10;
686 to.tv_usec = 0;
688 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
689 CONST_DISCARD(char **, attrs), 0, &to, &res))
690 goto done;
692 if (ldap_count_entries(ldp, res) != 1)
693 goto done;
695 values = ldap_get_values(ldp, res, "highestCommittedUSN");
696 if (!values || !values[0])
697 goto done;
699 *seq = atoi(values[0]);
700 ret = 0;
702 done:
704 if (values)
705 ldap_value_free(values);
706 if (res)
707 ldap_msgfree(res);
708 if (ldp)
709 ldap_unbind(ldp);
710 return ret;
713 /**********************************************************************
714 Get the sequence number for a Windows AD native mode domain using
715 LDAP queries
716 **********************************************************************/
718 static int get_ldap_sequence_number( const char* domain, uint32 *seq)
720 int ret = -1;
721 int i, port = LDAP_PORT;
722 struct ip_service *ip_list = NULL;
723 int count;
725 if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
726 DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
727 return False;
730 /* Finally return first DC that we can contact */
732 for (i = 0; i < count; i++) {
733 fstring ipstr;
735 /* since the is an LDAP lookup, default to the LDAP_PORT is
736 * not set */
737 port = (ip_list[i].port!= PORT_NONE) ?
738 ip_list[i].port : LDAP_PORT;
740 fstrcpy( ipstr, inet_ntoa(ip_list[i].ip) );
742 if (is_zero_ip(ip_list[i].ip))
743 continue;
745 if ( (ret = get_ldap_seq( ipstr, port, seq)) == 0 )
746 goto done;
748 /* add to failed connection cache */
749 add_failed_connection_entry( domain, ipstr,
750 NT_STATUS_UNSUCCESSFUL );
753 done:
754 if ( ret == 0 ) {
755 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
756 "number for Domain (%s) from DC (%s:%d)\n",
757 domain, inet_ntoa(ip_list[i].ip), port));
760 SAFE_FREE(ip_list);
762 return ret;
765 #endif /* HAVE_LDAP */
767 /* find the sequence number for a domain */
768 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
770 TALLOC_CTX *mem_ctx;
771 SAM_UNK_CTR ctr;
772 NTSTATUS result;
773 POLICY_HND dom_pol;
774 BOOL got_seq_num = False;
775 int retry;
776 struct rpc_pipe_client *cli;
778 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
780 *seq = DOM_SEQUENCE_NONE;
782 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
783 return NT_STATUS_NO_MEMORY;
785 retry = 0;
787 #ifdef HAVE_LDAP
788 if ( domain->native_mode )
790 int res;
792 DEBUG(8,("using get_ldap_seq() to retrieve the "
793 "sequence number\n"));
795 res = get_ldap_sequence_number( domain->name, seq );
796 if (res == 0)
798 result = NT_STATUS_OK;
799 DEBUG(10,("domain_sequence_number: LDAP for "
800 "domain %s is %u\n",
801 domain->name, *seq));
802 goto done;
805 DEBUG(10,("domain_sequence_number: failed to get LDAP "
806 "sequence number for domain %s\n",
807 domain->name ));
809 #endif /* HAVE_LDAP */
811 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
812 if (!NT_STATUS_IS_OK(result)) {
813 goto done;
816 /* Query domain info */
818 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 8, &ctr);
820 if (NT_STATUS_IS_OK(result)) {
821 *seq = ctr.info.inf8.seq_num.low;
822 got_seq_num = True;
823 goto seq_num;
826 /* retry with info-level 2 in case the dc does not support info-level 8
827 * (like all older samba2 and samba3 dc's - Guenther */
829 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 2, &ctr);
831 if (NT_STATUS_IS_OK(result)) {
832 *seq = ctr.info.inf2.seq_num.low;
833 got_seq_num = True;
836 seq_num:
837 if (got_seq_num) {
838 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
839 domain->name, (unsigned)*seq));
840 } else {
841 DEBUG(10,("domain_sequence_number: failed to get sequence "
842 "number (%u) for domain %s\n",
843 (unsigned)*seq, domain->name ));
846 done:
848 talloc_destroy(mem_ctx);
850 return result;
853 /* get a list of trusted domains */
854 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
855 TALLOC_CTX *mem_ctx,
856 uint32 *num_domains,
857 char ***names,
858 char ***alt_names,
859 DOM_SID **dom_sids)
861 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
862 uint32 enum_ctx = 0;
863 struct rpc_pipe_client *cli;
864 POLICY_HND lsa_policy;
866 DEBUG(3,("rpc: trusted_domains\n"));
868 *num_domains = 0;
869 *names = NULL;
870 *alt_names = NULL;
871 *dom_sids = NULL;
873 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
874 if (!NT_STATUS_IS_OK(result))
875 return result;
877 result = STATUS_MORE_ENTRIES;
879 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
880 uint32 start_idx, num;
881 char **tmp_names;
882 DOM_SID *tmp_sids;
883 int i;
885 result = rpccli_lsa_enum_trust_dom(cli, mem_ctx,
886 &lsa_policy, &enum_ctx,
887 &num, &tmp_names,
888 &tmp_sids);
890 if (!NT_STATUS_IS_OK(result) &&
891 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
892 break;
894 start_idx = *num_domains;
895 *num_domains += num;
896 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
897 char *, *num_domains);
898 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
899 DOM_SID, *num_domains);
900 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
901 char *, *num_domains);
902 if ((*names == NULL) || (*dom_sids == NULL) ||
903 (*alt_names == NULL))
904 return NT_STATUS_NO_MEMORY;
906 for (i=0; i<num; i++) {
907 (*names)[start_idx+i] = tmp_names[i];
908 (*dom_sids)[start_idx+i] = tmp_sids[i];
909 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
912 return result;
915 /* find the lockout policy for a domain */
916 NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
917 TALLOC_CTX *mem_ctx,
918 SAM_UNK_INFO_12 *lockout_policy)
920 NTSTATUS result;
921 struct rpc_pipe_client *cli;
922 POLICY_HND dom_pol;
923 SAM_UNK_CTR ctr;
925 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
927 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
928 if (!NT_STATUS_IS_OK(result)) {
929 goto done;
932 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 12, &ctr);
933 if (!NT_STATUS_IS_OK(result)) {
934 goto done;
937 *lockout_policy = ctr.info.inf12;
939 DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n",
940 ctr.info.inf12.bad_attempt_lockout));
942 done:
944 return result;
947 /* find the password policy for a domain */
948 NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
949 TALLOC_CTX *mem_ctx,
950 SAM_UNK_INFO_1 *password_policy)
952 NTSTATUS result;
953 struct rpc_pipe_client *cli;
954 POLICY_HND dom_pol;
955 SAM_UNK_CTR ctr;
957 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
959 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
960 if (!NT_STATUS_IS_OK(result)) {
961 goto done;
964 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 1, &ctr);
965 if (!NT_STATUS_IS_OK(result)) {
966 goto done;
969 *password_policy = ctr.info.inf1;
971 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
972 ctr.info.inf1.min_length_password));
974 done:
976 return result;
980 /* the rpc backend methods are exposed via this structure */
981 struct winbindd_methods msrpc_methods = {
982 False,
983 query_user_list,
984 enum_dom_groups,
985 enum_local_groups,
986 msrpc_name_to_sid,
987 msrpc_sid_to_name,
988 query_user,
989 lookup_usergroups,
990 msrpc_lookup_useraliases,
991 lookup_groupmem,
992 sequence_number,
993 msrpc_lockout_policy,
994 msrpc_password_policy,
995 trusted_domains,