• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source3/winbindd/
1/*
2   Unix SMB/CIFS implementation.
3
4   Winbind rpc backend functions
5
6   Copyright (C) Tim Potter 2000-2001,2003
7   Copyright (C) Andrew Tridgell 2001
8   Copyright (C) Volker Lendecke 2005
9   Copyright (C) Guenther Deschner 2008 (pidl conversion)
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#include "../librpc/gen_ndr/cli_samr.h"
28#include "../librpc/gen_ndr/cli_lsa.h"
29
30#undef DBGC_CLASS
31#define DBGC_CLASS DBGC_WINBIND
32
33
34/* Query display info for a domain.  This returns enough information plus a
35   bit extra to give an overview of domain users for the User Manager
36   application. */
37static NTSTATUS query_user_list(struct winbindd_domain *domain,
38			       TALLOC_CTX *mem_ctx,
39			       uint32 *num_entries,
40			       struct wbint_userinfo **info)
41{
42	NTSTATUS result;
43	struct policy_handle dom_pol;
44	unsigned int i, start_idx;
45	uint32 loop_count;
46	struct rpc_pipe_client *cli;
47
48	DEBUG(3,("rpc: query_user_list\n"));
49
50	*num_entries = 0;
51	*info = NULL;
52
53	if ( !winbindd_can_contact_domain( domain ) ) {
54		DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
55			  domain->name));
56		return NT_STATUS_OK;
57	}
58
59	result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
60	if (!NT_STATUS_IS_OK(result))
61		return result;
62
63	i = start_idx = 0;
64	loop_count = 0;
65
66	do {
67		uint32 num_dom_users, j;
68		uint32 max_entries, max_size;
69		uint32_t total_size, returned_size;
70
71		union samr_DispInfo disp_info;
72
73		/* this next bit is copied from net_user_list_internal() */
74
75		get_query_dispinfo_params(loop_count, &max_entries,
76					  &max_size);
77
78		result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
79						      &dom_pol,
80						      1,
81						      start_idx,
82						      max_entries,
83						      max_size,
84						      &total_size,
85						      &returned_size,
86						      &disp_info);
87
88		if (!NT_STATUS_IS_OK(result)) {
89		        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
90		                return result;
91		        }
92		}
93
94		num_dom_users = disp_info.info1.count;
95		start_idx += disp_info.info1.count;
96		loop_count++;
97
98		*num_entries += num_dom_users;
99
100		*info = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
101					     struct wbint_userinfo,
102					     *num_entries);
103
104		if (!(*info)) {
105			return NT_STATUS_NO_MEMORY;
106		}
107
108		for (j = 0; j < num_dom_users; i++, j++) {
109
110			uint32_t rid = disp_info.info1.entries[j].rid;
111
112			(*info)[i].acct_name = talloc_strdup(mem_ctx,
113				disp_info.info1.entries[j].account_name.string);
114			(*info)[i].full_name = talloc_strdup(mem_ctx,
115				disp_info.info1.entries[j].full_name.string);
116			(*info)[i].homedir = NULL;
117			(*info)[i].shell = NULL;
118			sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
119
120			/* For the moment we set the primary group for
121			   every user to be the Domain Users group.
122			   There are serious problems with determining
123			   the actual primary group for large domains.
124			   This should really be made into a 'winbind
125			   force group' smb.conf parameter or
126			   something like that. */
127
128			sid_compose(&(*info)[i].group_sid, &domain->sid,
129				    DOMAIN_GROUP_RID_USERS);
130		}
131
132	} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
133
134	return result;
135}
136
137/* list all domain groups */
138static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
139				TALLOC_CTX *mem_ctx,
140				uint32 *num_entries,
141				struct acct_info **info)
142{
143	struct policy_handle dom_pol;
144	NTSTATUS status;
145	uint32 start = 0;
146	struct rpc_pipe_client *cli;
147
148	*num_entries = 0;
149	*info = NULL;
150
151	DEBUG(3,("rpc: enum_dom_groups\n"));
152
153	if ( !winbindd_can_contact_domain( domain ) ) {
154		DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
155			  domain->name));
156		return NT_STATUS_OK;
157	}
158
159	status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
160	if (!NT_STATUS_IS_OK(status))
161		return status;
162
163	do {
164		struct samr_SamArray *sam_array = NULL;
165		uint32 count = 0;
166		TALLOC_CTX *mem_ctx2;
167		int g;
168
169		mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
170
171		/* start is updated by this call. */
172		status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
173						      &dom_pol,
174						      &start,
175						      &sam_array,
176						      0xFFFF, /* buffer size? */
177						      &count);
178
179		if (!NT_STATUS_IS_OK(status) &&
180		    !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
181			talloc_destroy(mem_ctx2);
182			break;
183		}
184
185		(*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
186					       struct acct_info,
187					       (*num_entries) + count);
188		if (! *info) {
189			talloc_destroy(mem_ctx2);
190			return NT_STATUS_NO_MEMORY;
191		}
192
193		for (g=0; g < count; g++) {
194
195			fstrcpy((*info)[*num_entries + g].acct_name,
196				sam_array->entries[g].name.string);
197			(*info)[*num_entries + g].rid = sam_array->entries[g].idx;
198		}
199
200		(*num_entries) += count;
201		talloc_destroy(mem_ctx2);
202	} while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
203
204	return status;
205}
206
207/* List all domain groups */
208
209static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
210				TALLOC_CTX *mem_ctx,
211				uint32 *num_entries,
212				struct acct_info **info)
213{
214	struct policy_handle dom_pol;
215	NTSTATUS result;
216	struct rpc_pipe_client *cli;
217
218	*num_entries = 0;
219	*info = NULL;
220
221	DEBUG(3,("rpc: enum_local_groups\n"));
222
223	if ( !winbindd_can_contact_domain( domain ) ) {
224		DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
225			  domain->name));
226		return NT_STATUS_OK;
227	}
228
229	result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
230	if (!NT_STATUS_IS_OK(result))
231		return result;
232
233	do {
234		struct samr_SamArray *sam_array = NULL;
235		uint32 count = 0, start = *num_entries;
236		TALLOC_CTX *mem_ctx2;
237		int g;
238
239		mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
240
241		result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
242						       &dom_pol,
243						       &start,
244						       &sam_array,
245						       0xFFFF, /* buffer size? */
246						       &count);
247		if (!NT_STATUS_IS_OK(result) &&
248		    !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
249		{
250			talloc_destroy(mem_ctx2);
251			return result;
252		}
253
254		(*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
255					       struct acct_info,
256					       (*num_entries) + count);
257		if (! *info) {
258			talloc_destroy(mem_ctx2);
259			return NT_STATUS_NO_MEMORY;
260		}
261
262		for (g=0; g < count; g++) {
263
264			fstrcpy((*info)[*num_entries + g].acct_name,
265				sam_array->entries[g].name.string);
266			(*info)[*num_entries + g].rid = sam_array->entries[g].idx;
267		}
268
269		(*num_entries) += count;
270		talloc_destroy(mem_ctx2);
271
272	} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
273
274	return result;
275}
276
277/* convert a single name to a sid in a domain */
278static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
279				  TALLOC_CTX *mem_ctx,
280				  const char *domain_name,
281				  const char *name,
282				  uint32_t flags,
283				  DOM_SID *sid,
284				  enum lsa_SidType *type)
285{
286	NTSTATUS result;
287	DOM_SID *sids = NULL;
288	enum lsa_SidType *types = NULL;
289	char *full_name = NULL;
290	NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
291	char *mapped_name = NULL;
292
293	if (name == NULL || *name=='\0') {
294		full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
295	} else if (domain_name == NULL || *domain_name == '\0') {
296		full_name = talloc_asprintf(mem_ctx, "%s", name);
297	} else {
298		full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
299	}
300	if (!full_name) {
301		DEBUG(0, ("talloc_asprintf failed!\n"));
302		return NT_STATUS_NO_MEMORY;
303	}
304
305	DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
306
307	name_map_status = normalize_name_unmap(mem_ctx, full_name,
308					       &mapped_name);
309
310	/* Reset the full_name pointer if we mapped anytthing */
311
312	if (NT_STATUS_IS_OK(name_map_status) ||
313	    NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
314	{
315		full_name = mapped_name;
316	}
317
318	DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
319		 full_name?full_name:"", domain_name ));
320
321	result = winbindd_lookup_names(mem_ctx, domain, 1,
322				       (const char **)&full_name, NULL,
323				       &sids, &types);
324	if (!NT_STATUS_IS_OK(result))
325		return result;
326
327	/* Return rid and type if lookup successful */
328
329	sid_copy(sid, &sids[0]);
330	*type = types[0];
331
332	return NT_STATUS_OK;
333}
334
335/*
336  convert a domain SID to a user or group name
337*/
338static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
339				  TALLOC_CTX *mem_ctx,
340				  const DOM_SID *sid,
341				  char **domain_name,
342				  char **name,
343				  enum lsa_SidType *type)
344{
345	char **domains;
346	char **names;
347	enum lsa_SidType *types = NULL;
348	NTSTATUS result;
349	NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
350	char *mapped_name = NULL;
351
352	DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
353		 domain->name ));
354
355	result = winbindd_lookup_sids(mem_ctx,
356				      domain,
357				      1,
358				      sid,
359				      &domains,
360				      &names,
361				      &types);
362	if (!NT_STATUS_IS_OK(result)) {
363		DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
364			nt_errstr(result)));
365		return result;
366	}
367
368
369	*type = (enum lsa_SidType)types[0];
370	*domain_name = domains[0];
371	*name = names[0];
372
373	DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
374
375	name_map_status = normalize_name_map(mem_ctx, domain, *name,
376					     &mapped_name);
377	if (NT_STATUS_IS_OK(name_map_status) ||
378	    NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
379	{
380		*name = mapped_name;
381		DEBUG(5,("returning mapped name -- %s\n", *name));
382	}
383
384	return NT_STATUS_OK;
385}
386
387static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
388				    TALLOC_CTX *mem_ctx,
389				    const DOM_SID *sid,
390				    uint32 *rids,
391				    size_t num_rids,
392				    char **domain_name,
393				    char ***names,
394				    enum lsa_SidType **types)
395{
396	char **domains;
397	NTSTATUS result;
398	DOM_SID *sids;
399	size_t i;
400	char **ret_names;
401
402	DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
403
404	if (num_rids) {
405		sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
406		if (sids == NULL) {
407			return NT_STATUS_NO_MEMORY;
408		}
409	} else {
410		sids = NULL;
411	}
412
413	for (i=0; i<num_rids; i++) {
414		if (!sid_compose(&sids[i], sid, rids[i])) {
415			return NT_STATUS_INTERNAL_ERROR;
416		}
417	}
418
419	result = winbindd_lookup_sids(mem_ctx,
420				      domain,
421				      num_rids,
422				      sids,
423				      &domains,
424				      names,
425				      types);
426
427	if (!NT_STATUS_IS_OK(result) &&
428	    !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
429		return result;
430	}
431
432	ret_names = *names;
433	for (i=0; i<num_rids; i++) {
434		NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
435		char *mapped_name = NULL;
436
437		if ((*types)[i] != SID_NAME_UNKNOWN) {
438			name_map_status = normalize_name_map(mem_ctx,
439							     domain,
440							     ret_names[i],
441							     &mapped_name);
442			if (NT_STATUS_IS_OK(name_map_status) ||
443			    NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
444			{
445				ret_names[i] = mapped_name;
446			}
447
448			*domain_name = domains[i];
449		}
450	}
451
452	return result;
453}
454
455/* Lookup user information from a rid or username. */
456static NTSTATUS query_user(struct winbindd_domain *domain,
457			   TALLOC_CTX *mem_ctx,
458			   const DOM_SID *user_sid,
459			   struct wbint_userinfo *user_info)
460{
461	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
462	struct policy_handle dom_pol, user_pol;
463	union samr_UserInfo *info = NULL;
464	uint32 user_rid;
465	struct netr_SamInfo3 *user;
466	struct rpc_pipe_client *cli;
467
468	DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
469
470	if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
471		return NT_STATUS_UNSUCCESSFUL;
472
473	user_info->homedir = NULL;
474	user_info->shell = NULL;
475	user_info->primary_gid = (gid_t)-1;
476
477	/* try netsamlogon cache first */
478
479	if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
480	{
481
482		DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
483			sid_string_dbg(user_sid)));
484
485		sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
486		sid_compose(&user_info->group_sid, &domain->sid,
487			    user->base.primary_gid);
488
489		user_info->acct_name = talloc_strdup(mem_ctx,
490						     user->base.account_name.string);
491		user_info->full_name = talloc_strdup(mem_ctx,
492						     user->base.full_name.string);
493
494		TALLOC_FREE(user);
495
496		return NT_STATUS_OK;
497	}
498
499	if ( !winbindd_can_contact_domain( domain ) ) {
500		DEBUG(10,("query_user: No incoming trust for domain %s\n",
501			  domain->name));
502		return NT_STATUS_OK;
503	}
504
505	/* no cache; hit the wire */
506
507	result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
508	if (!NT_STATUS_IS_OK(result))
509		return result;
510
511	/* Get user handle */
512	result = rpccli_samr_OpenUser(cli, mem_ctx,
513				      &dom_pol,
514				      SEC_FLAG_MAXIMUM_ALLOWED,
515				      user_rid,
516				      &user_pol);
517
518	if (!NT_STATUS_IS_OK(result))
519		return result;
520
521	/* Get user info */
522	result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
523					   &user_pol,
524					   0x15,
525					   &info);
526
527	rpccli_samr_Close(cli, mem_ctx, &user_pol);
528
529	if (!NT_STATUS_IS_OK(result))
530		return result;
531
532	sid_compose(&user_info->user_sid, &domain->sid, user_rid);
533	sid_compose(&user_info->group_sid, &domain->sid,
534		    info->info21.primary_gid);
535	user_info->acct_name = talloc_strdup(mem_ctx,
536					     info->info21.account_name.string);
537	user_info->full_name = talloc_strdup(mem_ctx,
538					     info->info21.full_name.string);
539	user_info->homedir = NULL;
540	user_info->shell = NULL;
541	user_info->primary_gid = (gid_t)-1;
542
543	return NT_STATUS_OK;
544}
545
546/* Lookup groups a user is a member of.  I wish Unix had a call like this! */
547static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
548				  TALLOC_CTX *mem_ctx,
549				  const DOM_SID *user_sid,
550				  uint32 *num_groups, DOM_SID **user_grpsids)
551{
552	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
553	struct policy_handle dom_pol, user_pol;
554	uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
555	struct samr_RidWithAttributeArray *rid_array = NULL;
556	unsigned int i;
557	uint32 user_rid;
558	struct rpc_pipe_client *cli;
559
560	DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
561
562	if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
563		return NT_STATUS_UNSUCCESSFUL;
564
565	*num_groups = 0;
566	*user_grpsids = NULL;
567
568	/* so lets see if we have a cached user_info_3 */
569	result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
570					  num_groups, user_grpsids);
571
572	if (NT_STATUS_IS_OK(result)) {
573		return NT_STATUS_OK;
574	}
575
576	if ( !winbindd_can_contact_domain( domain ) ) {
577		DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
578			  domain->name));
579
580		/* Tell the cache manager not to remember this one */
581
582		return NT_STATUS_SYNCHRONIZATION_REQUIRED;
583	}
584
585	/* no cache; hit the wire */
586
587	result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
588	if (!NT_STATUS_IS_OK(result))
589		return result;
590
591	/* Get user handle */
592	result = rpccli_samr_OpenUser(cli, mem_ctx,
593				      &dom_pol,
594				      des_access,
595				      user_rid,
596				      &user_pol);
597
598	if (!NT_STATUS_IS_OK(result))
599		return result;
600
601	/* Query user rids */
602	result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
603					      &user_pol,
604					      &rid_array);
605	*num_groups = rid_array->count;
606
607	rpccli_samr_Close(cli, mem_ctx, &user_pol);
608
609	if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
610		return result;
611
612	(*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
613	if (!(*user_grpsids))
614		return NT_STATUS_NO_MEMORY;
615
616	for (i=0;i<(*num_groups);i++) {
617		sid_copy(&((*user_grpsids)[i]), &domain->sid);
618		sid_append_rid(&((*user_grpsids)[i]),
619				rid_array->rids[i].rid);
620	}
621
622	return NT_STATUS_OK;
623}
624
625#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
626
627static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
628					 TALLOC_CTX *mem_ctx,
629					 uint32 num_sids, const DOM_SID *sids,
630					 uint32 *num_aliases,
631					 uint32 **alias_rids)
632{
633	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
634	struct policy_handle dom_pol;
635	uint32 num_query_sids = 0;
636	int i;
637	struct rpc_pipe_client *cli;
638	struct samr_Ids alias_rids_query;
639	int rangesize = MAX_SAM_ENTRIES_W2K;
640	uint32 total_sids = 0;
641	int num_queries = 1;
642
643	*num_aliases = 0;
644	*alias_rids = NULL;
645
646	DEBUG(3,("rpc: lookup_useraliases\n"));
647
648	if ( !winbindd_can_contact_domain( domain ) ) {
649		DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
650			  domain->name));
651		return NT_STATUS_OK;
652	}
653
654	result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
655	if (!NT_STATUS_IS_OK(result))
656		return result;
657
658	do {
659		/* prepare query */
660		struct lsa_SidArray sid_array;
661
662		ZERO_STRUCT(sid_array);
663
664		num_query_sids = MIN(num_sids - total_sids, rangesize);
665
666		DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
667			num_queries, num_query_sids));
668
669		if (num_query_sids) {
670			sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
671			if (sid_array.sids == NULL) {
672				return NT_STATUS_NO_MEMORY;
673			}
674		} else {
675			sid_array.sids = NULL;
676		}
677
678		for (i=0; i<num_query_sids; i++) {
679			sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
680			if (!sid_array.sids[i].sid) {
681				TALLOC_FREE(sid_array.sids);
682				return NT_STATUS_NO_MEMORY;
683			}
684		}
685		sid_array.num_sids = num_query_sids;
686
687		/* do request */
688		result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
689							&dom_pol,
690							&sid_array,
691							&alias_rids_query);
692
693		if (!NT_STATUS_IS_OK(result)) {
694			*num_aliases = 0;
695			*alias_rids = NULL;
696			TALLOC_FREE(sid_array.sids);
697			goto done;
698		}
699
700		/* process output */
701
702		for (i=0; i<alias_rids_query.count; i++) {
703			size_t na = *num_aliases;
704			if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
705						alias_rids, &na)) {
706				return NT_STATUS_NO_MEMORY;
707			}
708			*num_aliases = na;
709		}
710
711		TALLOC_FREE(sid_array.sids);
712
713		num_queries++;
714
715	} while (total_sids < num_sids);
716
717 done:
718	DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
719		"(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
720
721	return result;
722}
723
724
725/* Lookup group membership given a rid.   */
726static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
727				TALLOC_CTX *mem_ctx,
728				const DOM_SID *group_sid,
729				enum lsa_SidType type,
730				uint32 *num_names,
731				DOM_SID **sid_mem, char ***names,
732				uint32 **name_types)
733{
734        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
735        uint32 i, total_names = 0;
736        struct policy_handle dom_pol, group_pol;
737        uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
738	uint32 *rid_mem = NULL;
739	uint32 group_rid;
740	unsigned int j, r;
741	struct rpc_pipe_client *cli;
742	unsigned int orig_timeout;
743	struct samr_RidTypeArray *rids = NULL;
744
745	DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
746		  sid_string_dbg(group_sid)));
747
748	if ( !winbindd_can_contact_domain( domain ) ) {
749		DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
750			  domain->name));
751		return NT_STATUS_OK;
752	}
753
754	if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
755		return NT_STATUS_UNSUCCESSFUL;
756
757	*num_names = 0;
758
759	result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
760	if (!NT_STATUS_IS_OK(result))
761		return result;
762
763        result = rpccli_samr_OpenGroup(cli, mem_ctx,
764				       &dom_pol,
765				       des_access,
766				       group_rid,
767				       &group_pol);
768
769        if (!NT_STATUS_IS_OK(result))
770		return result;
771
772        /* Step #1: Get a list of user rids that are the members of the
773           group. */
774
775	/* This call can take a long time - allow the server to time out.
776	   35 seconds should do it. */
777
778	orig_timeout = rpccli_set_timeout(cli, 35000);
779
780        result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
781					      &group_pol,
782					      &rids);
783
784	/* And restore our original timeout. */
785	rpccli_set_timeout(cli, orig_timeout);
786
787	rpccli_samr_Close(cli, mem_ctx, &group_pol);
788
789        if (!NT_STATUS_IS_OK(result))
790		return result;
791
792	if (!rids || !rids->count) {
793		names = NULL;
794		name_types = NULL;
795		sid_mem = NULL;
796		return NT_STATUS_OK;
797	}
798
799	*num_names = rids->count;
800	rid_mem = rids->rids;
801
802        /* Step #2: Convert list of rids into list of usernames.  Do this
803           in bunches of ~1000 to avoid crashing NT4.  It looks like there
804           is a buffer overflow or something like that lurking around
805           somewhere. */
806
807#define MAX_LOOKUP_RIDS 900
808
809        *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
810        *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
811        *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
812
813	for (j=0;j<(*num_names);j++)
814		sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
815
816	if (*num_names>0 && (!*names || !*name_types))
817		return NT_STATUS_NO_MEMORY;
818
819	for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
820		int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
821		struct lsa_Strings tmp_names;
822		struct samr_Ids tmp_types;
823
824		/* Lookup a chunk of rids */
825
826		result = rpccli_samr_LookupRids(cli, mem_ctx,
827						&dom_pol,
828						num_lookup_rids,
829						&rid_mem[i],
830						&tmp_names,
831						&tmp_types);
832
833		/* see if we have a real error (and yes the
834		   STATUS_SOME_UNMAPPED is the one returned from 2k) */
835
836                if (!NT_STATUS_IS_OK(result) &&
837		    !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
838			return result;
839
840		/* Copy result into array.  The talloc system will take
841		   care of freeing the temporary arrays later on. */
842
843		if (tmp_names.count != tmp_types.count) {
844			return NT_STATUS_UNSUCCESSFUL;
845		}
846
847		for (r=0; r<tmp_names.count; r++) {
848			if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
849				continue;
850			}
851			(*names)[total_names] = fill_domain_username_talloc(
852				mem_ctx, domain->name,
853				tmp_names.names[r].string, true);
854			(*name_types)[total_names] = tmp_types.ids[r];
855			total_names += 1;
856		}
857        }
858
859        *num_names = total_names;
860
861	return NT_STATUS_OK;
862}
863
864#ifdef HAVE_LDAP
865
866#include <ldap.h>
867
868static int get_ldap_seq(const char *server, int port, uint32 *seq)
869{
870	int ret = -1;
871	struct timeval to;
872	const char *attrs[] = {"highestCommittedUSN", NULL};
873	LDAPMessage *res = NULL;
874	char **values = NULL;
875	LDAP *ldp = NULL;
876
877	*seq = DOM_SEQUENCE_NONE;
878
879	/*
880	 * Parameterised (5) second timeout on open. This is needed as the
881	 * search timeout doesn't seem to apply to doing an open as well. JRA.
882	 */
883
884	ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
885	if (ldp == NULL)
886		return -1;
887
888	/* Timeout if no response within 20 seconds. */
889	to.tv_sec = 10;
890	to.tv_usec = 0;
891
892	if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
893			   CONST_DISCARD(char **, attrs), 0, &to, &res))
894		goto done;
895
896	if (ldap_count_entries(ldp, res) != 1)
897		goto done;
898
899	values = ldap_get_values(ldp, res, "highestCommittedUSN");
900	if (!values || !values[0])
901		goto done;
902
903	*seq = atoi(values[0]);
904	ret = 0;
905
906  done:
907
908	if (values)
909		ldap_value_free(values);
910	if (res)
911		ldap_msgfree(res);
912	if (ldp)
913		ldap_unbind(ldp);
914	return ret;
915}
916
917/**********************************************************************
918 Get the sequence number for a Windows AD native mode domain using
919 LDAP queries.
920**********************************************************************/
921
922static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
923{
924	int ret = -1;
925	char addr[INET6_ADDRSTRLEN];
926
927	print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
928	if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
929		DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
930			  "number for Domain (%s) from DC (%s)\n",
931			domain->name, addr));
932	}
933	return ret;
934}
935
936#endif /* HAVE_LDAP */
937
938/* find the sequence number for a domain */
939static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
940{
941	TALLOC_CTX *mem_ctx;
942	union samr_DomainInfo *info = NULL;
943	NTSTATUS result;
944	struct policy_handle dom_pol;
945	bool got_seq_num = False;
946	struct rpc_pipe_client *cli;
947
948	DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
949
950	if ( !winbindd_can_contact_domain( domain ) ) {
951		DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
952			  domain->name));
953		*seq = time(NULL);
954		return NT_STATUS_OK;
955	}
956
957	*seq = DOM_SEQUENCE_NONE;
958
959	if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
960		return NT_STATUS_NO_MEMORY;
961
962#ifdef HAVE_LDAP
963	if ( domain->active_directory )
964	{
965		int res;
966
967		DEBUG(8,("using get_ldap_seq() to retrieve the "
968			 "sequence number\n"));
969
970		res =  get_ldap_sequence_number( domain, seq );
971		if (res == 0)
972		{
973			result = NT_STATUS_OK;
974			DEBUG(10,("domain_sequence_number: LDAP for "
975				  "domain %s is %u\n",
976				  domain->name, *seq));
977			goto done;
978		}
979
980		DEBUG(10,("domain_sequence_number: failed to get LDAP "
981			  "sequence number for domain %s\n",
982			  domain->name ));
983	}
984#endif /* HAVE_LDAP */
985
986	result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
987	if (!NT_STATUS_IS_OK(result)) {
988		goto done;
989	}
990
991	/* Query domain info */
992
993	result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
994					     &dom_pol,
995					     8,
996					     &info);
997
998	if (NT_STATUS_IS_OK(result)) {
999		*seq = info->info8.sequence_num;
1000		got_seq_num = True;
1001		goto seq_num;
1002	}
1003
1004	/* retry with info-level 2 in case the dc does not support info-level 8
1005	 * (like all older samba2 and samba3 dc's) - Guenther */
1006
1007	result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1008					     &dom_pol,
1009					     2,
1010					     &info);
1011
1012	if (NT_STATUS_IS_OK(result)) {
1013		*seq = info->general.sequence_num;
1014		got_seq_num = True;
1015	}
1016
1017 seq_num:
1018	if (got_seq_num) {
1019		DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1020			  domain->name, (unsigned)*seq));
1021	} else {
1022		DEBUG(10,("domain_sequence_number: failed to get sequence "
1023			  "number (%u) for domain %s\n",
1024			  (unsigned)*seq, domain->name ));
1025	}
1026
1027  done:
1028
1029	talloc_destroy(mem_ctx);
1030
1031	return result;
1032}
1033
1034/* get a list of trusted domains */
1035static NTSTATUS trusted_domains(struct winbindd_domain *domain,
1036				TALLOC_CTX *mem_ctx,
1037				struct netr_DomainTrustList *trusts)
1038{
1039	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1040	uint32 enum_ctx = 0;
1041	struct rpc_pipe_client *cli;
1042	struct policy_handle lsa_policy;
1043
1044	DEBUG(3,("rpc: trusted_domains\n"));
1045
1046	ZERO_STRUCTP(trusts);
1047
1048	result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1049	if (!NT_STATUS_IS_OK(result))
1050		return result;
1051
1052	result = STATUS_MORE_ENTRIES;
1053
1054	while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1055		uint32 start_idx;
1056		int i;
1057		struct lsa_DomainList dom_list;
1058
1059		result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1060						 &lsa_policy,
1061						 &enum_ctx,
1062						 &dom_list,
1063						 (uint32_t)-1);
1064
1065		if (!NT_STATUS_IS_OK(result) &&
1066		    !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1067			break;
1068
1069		start_idx = trusts->count;
1070		trusts->count += dom_list.count;
1071
1072		trusts->array = talloc_realloc(
1073			mem_ctx, trusts->array, struct netr_DomainTrust,
1074			trusts->count);
1075		if (trusts->array == NULL) {
1076			return NT_STATUS_NO_MEMORY;
1077		}
1078
1079		for (i=0; i<dom_list.count; i++) {
1080			struct netr_DomainTrust *trust = &trusts->array[i];
1081			struct dom_sid *sid;
1082
1083			ZERO_STRUCTP(trust);
1084
1085			trust->netbios_name = talloc_move(
1086				trusts->array,
1087				&dom_list.domains[i].name.string);
1088			trust->dns_name = NULL;
1089
1090			sid = talloc(trusts->array, struct dom_sid);
1091			if (sid == NULL) {
1092				return NT_STATUS_NO_MEMORY;
1093			}
1094			sid_copy(sid, dom_list.domains[i].sid);
1095			trust->sid = sid;
1096		}
1097	}
1098	return result;
1099}
1100
1101/* find the lockout policy for a domain */
1102static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1103				     TALLOC_CTX *mem_ctx,
1104				     struct samr_DomInfo12 *lockout_policy)
1105{
1106	NTSTATUS result;
1107	struct rpc_pipe_client *cli;
1108	struct policy_handle dom_pol;
1109	union samr_DomainInfo *info = NULL;
1110
1111	DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1112
1113	if ( !winbindd_can_contact_domain( domain ) ) {
1114		DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1115			  domain->name));
1116		return NT_STATUS_NOT_SUPPORTED;
1117	}
1118
1119	result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1120	if (!NT_STATUS_IS_OK(result)) {
1121		goto done;
1122	}
1123
1124	result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1125					     &dom_pol,
1126					     12,
1127					     &info);
1128	if (!NT_STATUS_IS_OK(result)) {
1129		goto done;
1130	}
1131
1132	*lockout_policy = info->info12;
1133
1134	DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1135		info->info12.lockout_threshold));
1136
1137  done:
1138
1139	return result;
1140}
1141
1142/* find the password policy for a domain */
1143static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1144				      TALLOC_CTX *mem_ctx,
1145				      struct samr_DomInfo1 *password_policy)
1146{
1147	NTSTATUS result;
1148	struct rpc_pipe_client *cli;
1149	struct policy_handle dom_pol;
1150	union samr_DomainInfo *info = NULL;
1151
1152	DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1153
1154	if ( !winbindd_can_contact_domain( domain ) ) {
1155		DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1156			  domain->name));
1157		return NT_STATUS_NOT_SUPPORTED;
1158	}
1159
1160	result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1161	if (!NT_STATUS_IS_OK(result)) {
1162		goto done;
1163	}
1164
1165	result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1166					     &dom_pol,
1167					     1,
1168					     &info);
1169	if (!NT_STATUS_IS_OK(result)) {
1170		goto done;
1171	}
1172
1173	*password_policy = info->info1;
1174
1175	DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1176		info->info1.min_password_length));
1177
1178  done:
1179
1180	return result;
1181}
1182
1183typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1184				     TALLOC_CTX *mem_ctx,
1185				     struct policy_handle *pol,
1186				     int num_sids,
1187				     const DOM_SID *sids,
1188				     char ***pdomains,
1189				     char ***pnames,
1190				     enum lsa_SidType **ptypes);
1191
1192NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1193			      struct winbindd_domain *domain,
1194			      uint32_t num_sids,
1195			      const struct dom_sid *sids,
1196			      char ***domains,
1197			      char ***names,
1198			      enum lsa_SidType **types)
1199{
1200	NTSTATUS status;
1201	struct rpc_pipe_client *cli = NULL;
1202	struct policy_handle lsa_policy;
1203	unsigned int orig_timeout;
1204	lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1205
1206	if (domain->can_do_ncacn_ip_tcp) {
1207		status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1208		if (NT_STATUS_IS_OK(status)) {
1209			lookup_sids_fn = rpccli_lsa_lookup_sids3;
1210			goto lookup;
1211		}
1212		domain->can_do_ncacn_ip_tcp = false;
1213	}
1214	status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1215
1216	if (!NT_STATUS_IS_OK(status)) {
1217		return status;
1218	}
1219
1220 lookup:
1221	/*
1222	 * This call can take a long time
1223	 * allow the server to time out.
1224	 * 35 seconds should do it.
1225	 */
1226	orig_timeout = rpccli_set_timeout(cli, 35000);
1227
1228	status = lookup_sids_fn(cli,
1229				mem_ctx,
1230				&lsa_policy,
1231				num_sids,
1232				sids,
1233				domains,
1234				names,
1235				types);
1236
1237	/* And restore our original timeout. */
1238	rpccli_set_timeout(cli, orig_timeout);
1239
1240	if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
1241	    NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
1242		/*
1243		 * This can happen if the schannel key is not
1244		 * valid anymore, we need to invalidate the
1245		 * all connections to the dc and reestablish
1246		 * a netlogon connection first.
1247		 */
1248		invalidate_cm_connection(&domain->conn);
1249		status = NT_STATUS_ACCESS_DENIED;
1250	}
1251
1252	if (!NT_STATUS_IS_OK(status)) {
1253		return status;
1254	}
1255
1256	return status;
1257}
1258
1259typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1260				      TALLOC_CTX *mem_ctx,
1261				      struct policy_handle *pol,
1262				      int num_names,
1263				      const char **names,
1264				      const char ***dom_names,
1265				      int level,
1266				      struct dom_sid **sids,
1267				      enum lsa_SidType **types);
1268
1269NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1270			       struct winbindd_domain *domain,
1271			       uint32_t num_names,
1272			       const char **names,
1273			       const char ***domains,
1274			       struct dom_sid **sids,
1275			       enum lsa_SidType **types)
1276{
1277	NTSTATUS status;
1278	struct rpc_pipe_client *cli = NULL;
1279	struct policy_handle lsa_policy;
1280	unsigned int orig_timeout = 0;
1281	lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1282
1283	if (domain->can_do_ncacn_ip_tcp) {
1284		status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1285		if (NT_STATUS_IS_OK(status)) {
1286			lookup_names_fn = rpccli_lsa_lookup_names4;
1287			goto lookup;
1288		}
1289		domain->can_do_ncacn_ip_tcp = false;
1290	}
1291	status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1292
1293	if (!NT_STATUS_IS_OK(status)) {
1294		return status;
1295	}
1296
1297 lookup:
1298
1299	/*
1300	 * This call can take a long time
1301	 * allow the server to time out.
1302	 * 35 seconds should do it.
1303	 */
1304	orig_timeout = rpccli_set_timeout(cli, 35000);
1305
1306	status = lookup_names_fn(cli,
1307				 mem_ctx,
1308				 &lsa_policy,
1309				 num_names,
1310				 (const char **) names,
1311				 domains,
1312				 1,
1313				 sids,
1314				 types);
1315
1316	/* And restore our original timeout. */
1317	rpccli_set_timeout(cli, orig_timeout);
1318
1319	if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
1320	    NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
1321		/*
1322		 * This can happen if the schannel key is not
1323		 * valid anymore, we need to invalidate the
1324		 * all connections to the dc and reestablish
1325		 * a netlogon connection first.
1326		 */
1327		invalidate_cm_connection(&domain->conn);
1328		status = NT_STATUS_ACCESS_DENIED;
1329	}
1330
1331	if (!NT_STATUS_IS_OK(status)) {
1332		return status;
1333	}
1334
1335	return status;
1336}
1337
1338/* the rpc backend methods are exposed via this structure */
1339struct winbindd_methods msrpc_methods = {
1340	False,
1341	query_user_list,
1342	enum_dom_groups,
1343	enum_local_groups,
1344	msrpc_name_to_sid,
1345	msrpc_sid_to_name,
1346	msrpc_rids_to_names,
1347	query_user,
1348	lookup_usergroups,
1349	msrpc_lookup_useraliases,
1350	lookup_groupmem,
1351	sequence_number,
1352	msrpc_lockout_policy,
1353	msrpc_password_policy,
1354	trusted_domains,
1355};
1356