• 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 D 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#define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache"
28
29NTSTATUS init_module(void);
30
31/*
32 * IdMap backend
33 */
34
35/********************************************************************
36 Basic init function responsible for determining our current mode
37 (standalone or using Centeris Cells).  This must return success or
38 it will be dropped from the idmap backend list.
39 *******************************************************************/
40
41static NTSTATUS _idmap_adex_init(struct idmap_domain *dom,
42				     const char *params)
43{
44	ADS_STRUCT *ads = NULL;
45	ADS_STATUS status;
46	static NTSTATUS init_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
47	DOM_SID domain_sid;
48	fstring dcname;
49	struct sockaddr_storage ip;
50	struct likewise_cell *lwcell;
51
52	if (NT_STATUS_IS_OK(init_status))
53		return NT_STATUS_OK;
54
55	/* Silently fail if we are not a member server in security = ads */
56
57	if ((lp_server_role() != ROLE_DOMAIN_MEMBER) ||
58	    (lp_security() != SEC_ADS)) {
59		init_status = NT_STATUS_INVALID_SERVER_STATE;
60		BAIL_ON_NTSTATUS_ERROR(init_status);
61	}
62
63	/* fetch our domain SID first */
64
65	if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
66		init_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
67		BAIL_ON_NTSTATUS_ERROR(init_status);
68	}
69
70	/* reuse the same ticket cache as winbindd */
71
72	setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
73
74	/* Establish a connection to a DC */
75
76	if ((ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL) {
77		init_status = NT_STATUS_NO_MEMORY;
78		BAIL_ON_NTSTATUS_ERROR(init_status);
79	}
80
81	ads->auth.password =
82	    secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
83	ads->auth.realm = SMB_STRDUP(lp_realm());
84
85	/* get the DC name here to setup the server affinity cache and
86	   local krb5.conf */
87
88	get_dc_name(lp_workgroup(), lp_realm(), dcname, &ip);
89
90	status = ads_connect(ads);
91	if (!ADS_ERR_OK(status)) {
92		DEBUG(0, ("_idmap_adex_init: ads_connect() failed! (%s)\n",
93			  ads_errstr(status)));
94	}
95	init_status = ads_ntstatus(status);
96	BAIL_ON_NTSTATUS_ERROR(init_status);
97
98
99	/* Find out cell membership */
100
101	init_status = cell_locate_membership(ads);
102	if (!NT_STATUS_IS_OK(init_status)) {
103		DEBUG(0,("LWI: Fail to locate cell membership (%s).",
104			 nt_errstr(init_status)));
105		goto done;
106	}
107
108	/* Fill in the cell information */
109
110	lwcell = cell_list_head();
111
112	init_status = cell_lookup_settings(lwcell);
113	BAIL_ON_NTSTATUS_ERROR(init_status);
114
115	/* Miscellaneous setup.  E.g. set up the list of GC
116	   servers and domain list for our forest (does not actually
117	   connect). */
118
119	init_status = gc_init_list();
120	BAIL_ON_NTSTATUS_ERROR(init_status);
121
122	init_status = domain_init_list();
123	BAIL_ON_NTSTATUS_ERROR(init_status);
124
125done:
126	if (!NT_STATUS_IS_OK(init_status)) {
127		DEBUG(1,("Likewise initialization failed (%s)\n",
128			 nt_errstr(init_status)));
129	}
130
131	/* cleanup */
132
133	if (!NT_STATUS_IS_OK(init_status)) {
134		cell_list_destroy();
135
136		/* init_status stores the failure reason but we need to
137		   return success or else idmap_init() will drop us from the
138		   backend list */
139		return NT_STATUS_OK;
140	}
141
142	init_status = NT_STATUS_OK;
143
144	return init_status;
145}
146
147/**********************************************************************
148 *********************************************************************/
149
150static NTSTATUS _idmap_adex_get_sid_from_id(struct
151						idmap_domain
152						*dom, struct
153						id_map
154						**ids)
155{
156	int i;
157	bool one_mapped = false;
158	bool all_mapped = true;
159	NTSTATUS nt_status;
160        struct likewise_cell *cell;
161
162	/* initialize the status to avoid suprise */
163	for (i = 0; ids[i]; i++) {
164		ids[i]->status = ID_UNKNOWN;
165	}
166
167	nt_status = _idmap_adex_init(dom, NULL);
168	if (!NT_STATUS_IS_OK(nt_status))
169		return nt_status;
170
171	if ((cell = cell_list_head()) == NULL) {
172		return NT_STATUS_INVALID_SERVER_STATE;
173	}
174
175	/* have to work through these one by one */
176	for (i = 0; ids[i]; i++) {
177		NTSTATUS status;
178		status = cell->provider->get_sid_from_id(ids[i]->sid,
179							 ids[i]->xid.id,
180							 ids[i]->xid.type);
181		/* Fail if we cannot find any DC */
182		if (NT_STATUS_EQUAL
183		    (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
184			return status;
185		}
186
187		if (!NT_STATUS_IS_OK(status)) {
188			ids[i]->status = ID_UNMAPPED;
189			all_mapped = false;
190			continue;
191		}
192
193		ids[i]->status = ID_MAPPED;
194		one_mapped = true;
195	}
196
197	return NT_STATUS_OK;
198}
199
200/**********************************************************************
201 *********************************************************************/
202
203static NTSTATUS _idmap_adex_get_id_from_sid(struct
204						idmap_domain
205						*dom, struct
206						id_map
207						**ids)
208{
209	int i;
210	bool one_mapped = false;
211	bool all_mapped = true;
212	NTSTATUS nt_status;
213        struct likewise_cell *cell;
214
215	/* initialize the status to avoid suprise */
216	for (i = 0; ids[i]; i++) {
217		ids[i]->status = ID_UNKNOWN;
218	}
219
220	nt_status = _idmap_adex_init(dom, NULL);
221	if (!NT_STATUS_IS_OK(nt_status))
222		return nt_status;
223
224	if ((cell = cell_list_head()) == NULL) {
225		return NT_STATUS_INVALID_SERVER_STATE;
226	}
227
228	/* have to work through these one by one */
229	for (i = 0; ids[i]; i++) {
230		NTSTATUS status;
231		status = cell->provider->get_id_from_sid(&ids[i]->xid.id,
232							 &ids[i]->xid.
233							 type, ids[i]->sid);
234		/* Fail if we cannot find any DC */
235		if (NT_STATUS_EQUAL
236		    (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
237			return status;
238		}
239
240		if (!NT_STATUS_IS_OK(status)) {
241			ids[i]->status = ID_UNMAPPED;
242			all_mapped = false;
243			continue;
244		}
245
246		ids[i]->status = ID_MAPPED;
247		one_mapped = true;
248	}
249
250	return NT_STATUS_OK;
251}
252
253/**********************************************************************
254 *********************************************************************/
255
256static NTSTATUS _idmap_adex_set_mapping(struct
257					    idmap_domain
258					    *dom, const struct
259					    id_map *map)
260{
261	DEBUG(0, ("_idmap_adex_set_mapping: not implemented\n"));
262	return NT_STATUS_NOT_IMPLEMENTED;
263}
264
265/**********************************************************************
266 *********************************************************************/
267
268static NTSTATUS _idmap_adex_remove_mapping(struct
269					       idmap_domain
270					       *dom, const
271					       struct
272					       id_map
273					       *map)
274{
275	DEBUG(0, ("_idmap_adex_remove_mapping: not implemented\n"));
276	return NT_STATUS_NOT_IMPLEMENTED;
277}
278
279/**********************************************************************
280 *********************************************************************/
281
282static NTSTATUS _idmap_adex_dump(struct idmap_domain
283				     *dom, struct id_map **maps, int *num_map)
284{
285	return NT_STATUS_NOT_IMPLEMENTED;
286}
287
288/**********************************************************************
289 *********************************************************************/
290
291static NTSTATUS _idmap_adex_close(struct idmap_domain
292				      *dom)
293{
294	/* FIXME!  need to do cleanup here */
295
296	return NT_STATUS_OK;
297}
298
299/*
300 * IdMap NSS plugin
301 */
302
303/**********************************************************************
304 *********************************************************************/
305
306static NTSTATUS _nss_adex_init(struct nss_domain_entry
307				  *e)
308{
309	return _idmap_adex_init(NULL, NULL);
310}
311
312/**********************************************************************
313 *********************************************************************/
314
315static NTSTATUS _nss_adex_get_info(struct
316				      nss_domain_entry *e,
317				      const DOM_SID * sid,
318				      TALLOC_CTX * ctx,
319				      ADS_STRUCT * ads,
320				      LDAPMessage * msg,
321				      const char **homedir,
322				      const char **shell,
323				      const char **gecos, gid_t * p_gid)
324{
325	NTSTATUS nt_status;
326        struct likewise_cell *cell;
327
328	nt_status = _idmap_adex_init(NULL, NULL);
329	if (!NT_STATUS_IS_OK(nt_status))
330		return nt_status;
331
332	if ((cell = cell_list_head()) == NULL) {
333		return NT_STATUS_INVALID_SERVER_STATE;
334	}
335
336	return cell->provider->get_nss_info(sid, ctx, homedir,
337					    shell, gecos, p_gid);
338}
339
340/**********************************************************************
341 *********************************************************************/
342
343static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx,
344				       struct nss_domain_entry *e,
345				       const char *name, char **alias)
346{
347	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
348        struct likewise_cell *cell = NULL;
349
350	nt_status = _idmap_adex_init(NULL, NULL);
351	BAIL_ON_NTSTATUS_ERROR(nt_status);
352
353	if ((cell = cell_list_head()) == NULL) {
354		nt_status = NT_STATUS_INVALID_SERVER_STATE;
355		BAIL_ON_NTSTATUS_ERROR(nt_status);
356	}
357
358	nt_status = cell->provider->map_to_alias(mem_ctx, e->domain,
359						 name, alias);
360
361	/* go ahead and allow the cache mgr to mark this in
362	   negative cache */
363
364	if (!NT_STATUS_IS_OK(nt_status))
365		nt_status = NT_STATUS_NONE_MAPPED;
366
367done:
368	return nt_status;
369}
370
371/**********************************************************************
372 *********************************************************************/
373
374static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx,
375					 struct nss_domain_entry *e,
376					 const char *alias, char **name)
377{
378	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
379        struct likewise_cell *cell = NULL;
380
381	nt_status = _idmap_adex_init(NULL, NULL);
382	BAIL_ON_NTSTATUS_ERROR(nt_status);
383
384	if ((cell = cell_list_head()) == NULL) {
385		nt_status = NT_STATUS_INVALID_SERVER_STATE;
386		BAIL_ON_NTSTATUS_ERROR(nt_status);
387	}
388
389
390	nt_status = cell->provider->map_from_alias(mem_ctx, e->domain,
391						   alias, name);
392
393	/* go ahead and allow the cache mgr to mark this in
394	   negative cache */
395
396	if (!NT_STATUS_IS_OK(nt_status))
397		nt_status = NT_STATUS_NONE_MAPPED;
398
399done:
400	return nt_status;
401}
402
403/**********************************************************************
404 *********************************************************************/
405
406static NTSTATUS _nss_adex_close(void)
407{
408	return NT_STATUS_NOT_IMPLEMENTED;
409}
410
411/**********************************************************************
412 *********************************************************************/
413
414static struct idmap_methods adex_idmap_methods = {
415
416	.init             = _idmap_adex_init,
417	.unixids_to_sids  = _idmap_adex_get_sid_from_id,
418	.sids_to_unixids  = _idmap_adex_get_id_from_sid,
419	.set_mapping      = _idmap_adex_set_mapping,
420	.remove_mapping   = _idmap_adex_remove_mapping,
421	.dump_data        = _idmap_adex_dump,
422	.close_fn         = _idmap_adex_close
423};
424static struct nss_info_methods adex_nss_methods = {
425	.init           = _nss_adex_init,
426	.get_nss_info   = _nss_adex_get_info,
427	.map_to_alias   = _nss_adex_map_to_alias,
428	.map_from_alias = _nss_adex_map_from_alias,
429	.close_fn       = _nss_adex_close
430};
431
432/**********************************************************************
433 Register with the idmap and idmap_nss subsystems. We have to protect
434 against the idmap and nss_info interfaces being in a half-registered
435 state.
436 **********************************************************************/
437NTSTATUS idmap_adex_init(void)
438{
439	static NTSTATUS idmap_status = NT_STATUS_UNSUCCESSFUL;
440	static NTSTATUS nss_status = NT_STATUS_UNSUCCESSFUL;
441	if (!NT_STATUS_IS_OK(idmap_status)) {
442		idmap_status =
443		    smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
444				       "adex", &adex_idmap_methods);
445		if (!NT_STATUS_IS_OK(idmap_status)) {
446			DEBUG(0,
447			      ("idmap_centeris_init: Failed to register the adex"
448			       "idmap plugin.\n"));
449			return idmap_status;
450		}
451	}
452
453	if (!NT_STATUS_IS_OK(nss_status)) {
454		nss_status =
455		    smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
456					   "adex", &adex_nss_methods);
457		if (!NT_STATUS_IS_OK(nss_status)) {
458			DEBUG(0,
459			      ("idmap_adex_init: Failed to register the adex"
460			       "nss plugin.\n"));
461			return nss_status;
462		}
463	}
464
465	return NT_STATUS_OK;
466}
467
468static NTSTATUS nss_info_adex_init(void)
469{
470	return idmap_adex_init();
471}
472