• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/samba-3.5.8/source3/winbindd/idmap_adex/
1/*
2 * idmap_adex: Support for AD Forests
3 *
4 * Copyright (C) Gerald (Jerry) Carter 2006-2008
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "includes.h"
22#include "idmap_adex.h"
23
24#undef DBGC_CLASS
25#define DBGC_CLASS DBGC_IDMAP
26
27/**********************************************************************
28**********************************************************************/
29
30 char *find_attr_string(char **list, size_t num_lines, const char *substr)
31{
32	int i;
33	int cmplen = strlen(substr);
34
35	for (i = 0; i < num_lines; i++) {
36		/* make sure to avoid substring matches like uid
37		   and uidNumber */
38		if ((StrnCaseCmp(list[i], substr, cmplen) == 0) &&
39		    (list[i][cmplen] == '=')) {
40			/* Don't return an empty string */
41			if (list[i][cmplen + 1] != '\0')
42				return &(list[i][cmplen + 1]);
43
44			return NULL;
45		}
46	}
47
48	return NULL;
49}
50
51/**********************************************************************
52**********************************************************************/
53
54 bool is_object_class(char **list, size_t num_lines, const char *substr)
55{
56	int i;
57
58	for (i = 0; i < num_lines; i++) {
59		if (strequal(list[i], substr)) {
60			return true;
61		}
62	}
63
64	return false;
65}
66
67/**********************************************************************
68 Find out about the cell (e.g. use2307Attrs, etc...)
69**********************************************************************/
70
71 NTSTATUS cell_lookup_settings(struct likewise_cell * cell)
72{
73	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
74
75	/* Parameter check */
76
77	if (!cell) {
78		nt_status = NT_STATUS_INVALID_PARAMETER;
79		BAIL_ON_NTSTATUS_ERROR(nt_status);
80	}
81
82	/* Only supporting Forest-wide, schema based searches */
83
84	cell_set_flags(cell, LWCELL_FLAG_USE_RFC2307_ATTRS);
85	cell_set_flags(cell, LWCELL_FLAG_SEARCH_FOREST);
86
87	cell->provider = &ccp_unified;
88
89	nt_status = NT_STATUS_OK;
90
91done:
92	if (!NT_STATUS_IS_OK(nt_status)) {
93		DEBUG(1,("LWI: Failed to obtain cell settings (%s)\n",
94			 nt_errstr(nt_status)));
95	}
96
97	return nt_status;
98}
99
100
101static NTSTATUS cell_lookup_forest(struct likewise_cell *c)
102{
103	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
104	struct gc_info *gc = NULL;
105
106	if (!c) {
107		return NT_STATUS_INVALID_PARAMETER;
108	}
109
110	if ((gc = TALLOC_ZERO_P(NULL, struct gc_info)) == NULL) {
111		nt_status = NT_STATUS_NO_MEMORY;
112		BAIL_ON_NTSTATUS_ERROR(nt_status);
113	}
114
115	/* Query the rootDSE for the forest root naming conect first.
116           Check that the a GC server for the forest has not already
117	   been added */
118
119	nt_status = gc_find_forest_root(gc, cell_dns_domain(c));
120	BAIL_ON_NTSTATUS_ERROR(nt_status);
121
122	c->forest_name = talloc_strdup(c, gc->forest_name);
123	BAIL_ON_PTR_ERROR(c->forest_name, nt_status);
124
125done:
126	if (gc) {
127		talloc_free(gc);
128	}
129
130	return nt_status;
131}
132
133/**********************************************************************
134**********************************************************************/
135
136 NTSTATUS cell_locate_membership(ADS_STRUCT * ads)
137{
138	ADS_STATUS status;
139	char *domain_dn = ads_build_dn(lp_realm());
140	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
141	DOM_SID sid;
142	struct likewise_cell *cell = NULL;
143
144	/* In the Likewise plugin, I had to support the concept of cells
145	   based on the machine's membership in an OU.  However, now I'll
146	   just assume our membership in the forest cell */
147
148	DEBUG(2, ("locate_cell_membership: Located membership "
149		  "in cell \"%s\"\n", domain_dn));
150
151	if ((cell = cell_new()) == NULL) {
152		nt_status = NT_STATUS_NO_MEMORY;
153		BAIL_ON_NTSTATUS_ERROR(nt_status);
154	}
155
156	status = ads_domain_sid(ads, &sid);
157	if (!ADS_ERR_OK(status)) {
158		DEBUG(3,("locate_cell_membership: Failed to find "
159			 "domain SID for %s\n", domain_dn));
160	}
161
162	/* save the SID and search base for our domain */
163
164	cell_set_dns_domain(cell, lp_realm());
165	cell_set_connection(cell, ads);
166	cell_set_dn(cell, domain_dn);
167	cell_set_domain_sid(cell, &sid);
168
169	/* Now save our forest root */
170
171	cell_lookup_forest(cell);
172
173	/* Add the cell to the list */
174
175	if (!cell_list_add(cell)) {
176		nt_status = NT_STATUS_INSUFFICIENT_RESOURCES;
177		BAIL_ON_NTSTATUS_ERROR(nt_status);
178	}
179
180	/* Done! */
181	nt_status = NT_STATUS_OK;
182
183done:
184	if (!NT_STATUS_IS_OK(nt_status)) {
185		DEBUG(0,("LWI: Failed to locate cell membership (%s)\n",
186			 nt_errstr(nt_status)));
187	}
188
189	SAFE_FREE(domain_dn);
190
191	return nt_status;
192}
193
194/*********************************************************************
195 ********************************************************************/
196
197 int min_id_value(void)
198{
199	int id_val;
200
201	id_val = lp_parm_int(-1, "lwidentity", "min_id_value", MIN_ID_VALUE);
202
203	/* Still don't let it go below 50 */
204
205	return MAX(50, id_val);
206}
207
208/********************************************************************
209 *******************************************************************/
210
211 char *cell_dn_to_dns(const char *dn)
212{
213	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
214	char *domain = NULL;
215	char *dns_name = NULL;
216	const char *tmp_dn;
217	char *buffer = NULL;
218	TALLOC_CTX *frame = talloc_stackframe();
219
220	if (!dn || !*dn) {
221		goto done;
222	}
223
224	tmp_dn = talloc_strdup(frame, dn);
225	BAIL_ON_PTR_ERROR(tmp_dn, nt_status);
226
227	while (next_token_talloc(frame, &tmp_dn, &buffer, ",")) {
228
229		/* skip everything up the where DC=... begins */
230		if (StrnCaseCmp(buffer, "DC=", 3) != 0)
231			continue;
232
233		if (!domain) {
234			domain = talloc_strdup(frame, &buffer[3]);
235		} else {
236			domain = talloc_asprintf_append(domain, ".%s",
237							&buffer[3]);
238		}
239		BAIL_ON_PTR_ERROR(domain, nt_status);
240	}
241
242	dns_name = SMB_STRDUP(domain);
243	BAIL_ON_PTR_ERROR(dns_name, nt_status);
244
245	nt_status = NT_STATUS_OK;
246
247done:
248	PRINT_NTSTATUS_ERROR(nt_status, "cell_dn_to_dns", 1);
249
250	talloc_destroy(frame);
251
252	return dns_name;
253}
254
255/*********************************************************************
256 ********************************************************************/
257
258 NTSTATUS get_sid_type(ADS_STRUCT *ads,
259		       LDAPMessage *msg,
260		       enum lsa_SidType *type)
261{
262	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
263	uint32_t atype;
264
265	if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) {
266		nt_status = NT_STATUS_INVALID_USER_BUFFER;
267		BAIL_ON_NTSTATUS_ERROR(nt_status);
268	}
269
270	switch (atype &0xF0000000) {
271	case ATYPE_SECURITY_GLOBAL_GROUP:
272		*type = SID_NAME_DOM_GRP;
273		break;
274	case ATYPE_SECURITY_LOCAL_GROUP:
275		*type = SID_NAME_ALIAS;
276		break;
277	case ATYPE_NORMAL_ACCOUNT:
278	case ATYPE_WORKSTATION_TRUST:
279	case ATYPE_INTERDOMAIN_TRUST:
280		*type = SID_NAME_USER;
281		break;
282	default:
283		*type = SID_NAME_USE_NONE;
284		nt_status = NT_STATUS_INVALID_ACCOUNT_NAME;
285		BAIL_ON_NTSTATUS_ERROR(nt_status);
286	}
287
288	nt_status = NT_STATUS_OK;
289
290done:
291	return nt_status;
292}
293