r15837: starting sync up for 3.0.23rc1 (in sync with SAMBA_3_0 r15822)
[Samba.git] / source / nsswitch / winbindd_rpc.c
blob22df8d4db967ed3636a92a0036b262441c234542
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 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 *sid2;
477 int i;
478 struct rpc_pipe_client *cli;
480 *num_aliases = 0;
481 *alias_rids = NULL;
483 DEBUG(3,("rpc: lookup_useraliases\n"));
485 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
486 if (!NT_STATUS_IS_OK(result))
487 return result;
489 sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
491 if (sid2 == NULL)
492 return NT_STATUS_NO_MEMORY;
494 for (i=0; i<num_sids; i++) {
495 sid_copy(&sid2[i].sid, &sids[i]);
496 sid2[i].num_auths = sid2[i].sid.num_auths;
499 result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,
500 num_sids, sid2,
501 num_aliases, alias_rids);
503 return result;
507 /* Lookup group membership given a rid. */
508 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
509 TALLOC_CTX *mem_ctx,
510 const DOM_SID *group_sid, uint32 *num_names,
511 DOM_SID **sid_mem, char ***names,
512 uint32 **name_types)
514 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
515 uint32 i, total_names = 0;
516 POLICY_HND dom_pol, group_pol;
517 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
518 uint32 *rid_mem = NULL;
519 uint32 group_rid;
520 unsigned int j;
521 fstring sid_string;
522 struct rpc_pipe_client *cli;
524 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
525 sid_to_string(sid_string, group_sid)));
527 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
528 return NT_STATUS_UNSUCCESSFUL;
530 *num_names = 0;
532 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
533 if (!NT_STATUS_IS_OK(result))
534 return result;
536 result = rpccli_samr_open_group(cli, mem_ctx, &dom_pol,
537 des_access, group_rid, &group_pol);
539 if (!NT_STATUS_IS_OK(result))
540 return result;
542 /* Step #1: Get a list of user rids that are the members of the
543 group. */
545 result = rpccli_samr_query_groupmem(cli, mem_ctx,
546 &group_pol, num_names, &rid_mem,
547 name_types);
549 rpccli_samr_close(cli, mem_ctx, &group_pol);
551 if (!NT_STATUS_IS_OK(result))
552 return result;
554 if (!*num_names) {
555 names = NULL;
556 name_types = NULL;
557 sid_mem = NULL;
558 return NT_STATUS_OK;
561 /* Step #2: Convert list of rids into list of usernames. Do this
562 in bunches of ~1000 to avoid crashing NT4. It looks like there
563 is a buffer overflow or something like that lurking around
564 somewhere. */
566 #define MAX_LOOKUP_RIDS 900
568 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
569 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
570 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
572 for (j=0;j<(*num_names);j++)
573 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
575 if (*num_names>0 && (!*names || !*name_types))
576 return NT_STATUS_NO_MEMORY;
578 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
579 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
580 uint32 tmp_num_names = 0;
581 char **tmp_names = NULL;
582 uint32 *tmp_types = NULL;
584 /* Lookup a chunk of rids */
586 result = rpccli_samr_lookup_rids(cli, mem_ctx,
587 &dom_pol,
588 num_lookup_rids,
589 &rid_mem[i],
590 &tmp_num_names,
591 &tmp_names, &tmp_types);
593 /* see if we have a real error (and yes the
594 STATUS_SOME_UNMAPPED is the one returned from 2k) */
596 if (!NT_STATUS_IS_OK(result) &&
597 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
598 return result;
600 /* Copy result into array. The talloc system will take
601 care of freeing the temporary arrays later on. */
603 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
604 tmp_num_names);
606 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
607 tmp_num_names);
609 total_names += tmp_num_names;
612 *num_names = total_names;
614 return NT_STATUS_OK;
617 #ifdef HAVE_LDAP
619 #include <ldap.h>
621 static int get_ldap_seq(const char *server, int port, uint32 *seq)
623 int ret = -1;
624 struct timeval to;
625 const char *attrs[] = {"highestCommittedUSN", NULL};
626 LDAPMessage *res = NULL;
627 char **values = NULL;
628 LDAP *ldp = NULL;
630 *seq = DOM_SEQUENCE_NONE;
633 * Parameterised (5) second timeout on open. This is needed as the
634 * search timeout doesn't seem to apply to doing an open as well. JRA.
637 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
638 if (ldp == NULL)
639 return -1;
641 /* Timeout if no response within 20 seconds. */
642 to.tv_sec = 10;
643 to.tv_usec = 0;
645 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
646 CONST_DISCARD(char **, attrs), 0, &to, &res))
647 goto done;
649 if (ldap_count_entries(ldp, res) != 1)
650 goto done;
652 values = ldap_get_values(ldp, res, "highestCommittedUSN");
653 if (!values || !values[0])
654 goto done;
656 *seq = atoi(values[0]);
657 ret = 0;
659 done:
661 if (values)
662 ldap_value_free(values);
663 if (res)
664 ldap_msgfree(res);
665 if (ldp)
666 ldap_unbind(ldp);
667 return ret;
670 /**********************************************************************
671 Get the sequence number for a Windows AD native mode domain using
672 LDAP queries
673 **********************************************************************/
675 static int get_ldap_sequence_number( const char* domain, uint32 *seq)
677 int ret = -1;
678 int i, port = LDAP_PORT;
679 struct ip_service *ip_list = NULL;
680 int count;
682 if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
683 DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
684 return False;
687 /* Finally return first DC that we can contact */
689 for (i = 0; i < count; i++) {
690 fstring ipstr;
692 /* since the is an LDAP lookup, default to the LDAP_PORT is
693 * not set */
694 port = (ip_list[i].port!= PORT_NONE) ?
695 ip_list[i].port : LDAP_PORT;
697 fstrcpy( ipstr, inet_ntoa(ip_list[i].ip) );
699 if (is_zero_ip(ip_list[i].ip))
700 continue;
702 if ( (ret = get_ldap_seq( ipstr, port, seq)) == 0 )
703 goto done;
705 /* add to failed connection cache */
706 add_failed_connection_entry( domain, ipstr,
707 NT_STATUS_UNSUCCESSFUL );
710 done:
711 if ( ret == 0 ) {
712 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
713 "number for Domain (%s) from DC (%s:%d)\n",
714 domain, inet_ntoa(ip_list[i].ip), port));
717 SAFE_FREE(ip_list);
719 return ret;
722 #endif /* HAVE_LDAP */
724 /* find the sequence number for a domain */
725 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
727 TALLOC_CTX *mem_ctx;
728 SAM_UNK_CTR ctr;
729 NTSTATUS result;
730 POLICY_HND dom_pol;
731 BOOL got_seq_num = False;
732 int retry;
733 struct rpc_pipe_client *cli;
735 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
737 *seq = DOM_SEQUENCE_NONE;
739 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
740 return NT_STATUS_NO_MEMORY;
742 retry = 0;
744 #ifdef HAVE_LDAP
745 if ( domain->native_mode )
747 int res;
749 DEBUG(8,("using get_ldap_seq() to retrieve the "
750 "sequence number\n"));
752 res = get_ldap_sequence_number( domain->name, seq );
753 if (res == 0)
755 result = NT_STATUS_OK;
756 DEBUG(10,("domain_sequence_number: LDAP for "
757 "domain %s is %u\n",
758 domain->name, *seq));
759 goto done;
762 DEBUG(10,("domain_sequence_number: failed to get LDAP "
763 "sequence number for domain %s\n",
764 domain->name ));
766 #endif /* HAVE_LDAP */
768 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
769 if (!NT_STATUS_IS_OK(result)) {
770 goto done;
773 /* Query domain info */
775 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 8, &ctr);
777 if (NT_STATUS_IS_OK(result)) {
778 *seq = ctr.info.inf8.seq_num.low;
779 got_seq_num = True;
780 goto seq_num;
783 /* retry with info-level 2 in case the dc does not support info-level 8
784 * (like all older samba2 and samba3 dc's - Guenther */
786 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 2, &ctr);
788 if (NT_STATUS_IS_OK(result)) {
789 *seq = ctr.info.inf2.seq_num.low;
790 got_seq_num = True;
793 seq_num:
794 if (got_seq_num) {
795 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
796 domain->name, (unsigned)*seq));
797 } else {
798 DEBUG(10,("domain_sequence_number: failed to get sequence "
799 "number (%u) for domain %s\n",
800 (unsigned)*seq, domain->name ));
803 done:
805 talloc_destroy(mem_ctx);
807 return result;
810 /* get a list of trusted domains */
811 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
812 TALLOC_CTX *mem_ctx,
813 uint32 *num_domains,
814 char ***names,
815 char ***alt_names,
816 DOM_SID **dom_sids)
818 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
819 uint32 enum_ctx = 0;
820 struct rpc_pipe_client *cli;
821 POLICY_HND lsa_policy;
823 DEBUG(3,("rpc: trusted_domains\n"));
825 *num_domains = 0;
826 *names = NULL;
827 *alt_names = NULL;
828 *dom_sids = NULL;
830 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
831 if (!NT_STATUS_IS_OK(result))
832 return result;
834 result = STATUS_MORE_ENTRIES;
836 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
837 uint32 start_idx, num;
838 char **tmp_names;
839 DOM_SID *tmp_sids;
840 int i;
842 result = rpccli_lsa_enum_trust_dom(cli, mem_ctx,
843 &lsa_policy, &enum_ctx,
844 &num, &tmp_names,
845 &tmp_sids);
847 if (!NT_STATUS_IS_OK(result) &&
848 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
849 break;
851 start_idx = *num_domains;
852 *num_domains += num;
853 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
854 char *, *num_domains);
855 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
856 DOM_SID, *num_domains);
857 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
858 char *, *num_domains);
859 if ((*names == NULL) || (*dom_sids == NULL) ||
860 (*alt_names == NULL))
861 return NT_STATUS_NO_MEMORY;
863 for (i=0; i<num; i++) {
864 (*names)[start_idx+i] = tmp_names[i];
865 (*dom_sids)[start_idx+i] = tmp_sids[i];
866 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
869 return result;
872 /* find the lockout policy for a domain */
873 NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
874 TALLOC_CTX *mem_ctx,
875 SAM_UNK_INFO_12 *lockout_policy)
877 NTSTATUS result;
878 struct rpc_pipe_client *cli;
879 POLICY_HND dom_pol;
880 SAM_UNK_CTR ctr;
882 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
884 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
885 if (!NT_STATUS_IS_OK(result)) {
886 goto done;
889 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 12, &ctr);
890 if (!NT_STATUS_IS_OK(result)) {
891 goto done;
894 *lockout_policy = ctr.info.inf12;
896 DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n",
897 ctr.info.inf12.bad_attempt_lockout));
899 done:
901 return result;
904 /* find the password policy for a domain */
905 NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
906 TALLOC_CTX *mem_ctx,
907 SAM_UNK_INFO_1 *password_policy)
909 NTSTATUS result;
910 struct rpc_pipe_client *cli;
911 POLICY_HND dom_pol;
912 SAM_UNK_CTR ctr;
914 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
916 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
917 if (!NT_STATUS_IS_OK(result)) {
918 goto done;
921 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 1, &ctr);
922 if (!NT_STATUS_IS_OK(result)) {
923 goto done;
926 *password_policy = ctr.info.inf1;
928 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
929 ctr.info.inf1.min_length_password));
931 done:
933 return result;
937 /* the rpc backend methods are exposed via this structure */
938 struct winbindd_methods msrpc_methods = {
939 False,
940 query_user_list,
941 enum_dom_groups,
942 enum_local_groups,
943 msrpc_name_to_sid,
944 msrpc_sid_to_name,
945 query_user,
946 lookup_usergroups,
947 msrpc_lookup_useraliases,
948 lookup_groupmem,
949 sequence_number,
950 msrpc_lockout_policy,
951 msrpc_password_policy,
952 trusted_domains,