2 * idmap_adex: Support for D Forests
4 * Copyright (C) Gerald (Jerry) Carter 2006-2008
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.
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.
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.
23 #include "idmap_adex.h"
28 #define DBGC_CLASS DBGC_IDMAP
30 #define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache"
32 NTSTATUS init_module(void);
38 /********************************************************************
39 Basic init function responsible for determining our current mode
40 (standalone or using Centeris Cells). This must return success or
41 it will be dropped from the idmap backend list.
42 *******************************************************************/
44 static NTSTATUS _idmap_adex_init(struct idmap_domain *dom,
47 ADS_STRUCT *ads = NULL;
49 static NTSTATUS init_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
50 struct dom_sid domain_sid;
52 struct sockaddr_storage ip;
53 struct likewise_cell *lwcell;
55 if (NT_STATUS_IS_OK(init_status))
58 /* Silently fail if we are not a member server in security = ads */
60 if ((lp_server_role() != ROLE_DOMAIN_MEMBER) ||
61 (lp_security() != SEC_ADS)) {
62 init_status = NT_STATUS_INVALID_SERVER_STATE;
63 BAIL_ON_NTSTATUS_ERROR(init_status);
66 /* fetch our domain SID first */
68 if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
69 init_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
70 BAIL_ON_NTSTATUS_ERROR(init_status);
73 /* reuse the same ticket cache as winbindd */
75 setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
77 /* Establish a connection to a DC */
79 if ((ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL) {
80 init_status = NT_STATUS_NO_MEMORY;
81 BAIL_ON_NTSTATUS_ERROR(init_status);
85 secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
86 ads->auth.realm = SMB_STRDUP(lp_realm());
88 /* get the DC name here to setup the server affinity cache and
91 get_dc_name(lp_workgroup(), lp_realm(), dcname, &ip);
93 status = ads_connect(ads);
94 if (!ADS_ERR_OK(status)) {
95 DEBUG(0, ("_idmap_adex_init: ads_connect() failed! (%s)\n",
98 init_status = ads_ntstatus(status);
99 BAIL_ON_NTSTATUS_ERROR(init_status);
102 /* Find out cell membership */
104 init_status = cell_locate_membership(ads);
105 if (!NT_STATUS_IS_OK(init_status)) {
106 DEBUG(0,("LWI: Fail to locate cell membership (%s).",
107 nt_errstr(init_status)));
111 /* Fill in the cell information */
113 lwcell = cell_list_head();
115 init_status = cell_lookup_settings(lwcell);
116 BAIL_ON_NTSTATUS_ERROR(init_status);
118 /* Miscellaneous setup. E.g. set up the list of GC
119 servers and domain list for our forest (does not actually
122 init_status = gc_init_list();
123 BAIL_ON_NTSTATUS_ERROR(init_status);
125 init_status = domain_init_list();
126 BAIL_ON_NTSTATUS_ERROR(init_status);
129 if (!NT_STATUS_IS_OK(init_status)) {
130 DEBUG(1,("Likewise initialization failed (%s)\n",
131 nt_errstr(init_status)));
136 if (!NT_STATUS_IS_OK(init_status)) {
139 /* init_status stores the failure reason but we need to
140 return success or else idmap_init() will drop us from the
145 init_status = NT_STATUS_OK;
150 /**********************************************************************
151 *********************************************************************/
153 static NTSTATUS _idmap_adex_get_sid_from_id(struct
160 bool one_mapped = false;
161 bool all_mapped = true;
163 struct likewise_cell *cell;
165 /* initialize the status to avoid suprise */
166 for (i = 0; ids[i]; i++) {
167 ids[i]->status = ID_UNKNOWN;
170 nt_status = _idmap_adex_init(dom, NULL);
171 if (!NT_STATUS_IS_OK(nt_status))
174 if ((cell = cell_list_head()) == NULL) {
175 return NT_STATUS_INVALID_SERVER_STATE;
178 /* have to work through these one by one */
179 for (i = 0; ids[i]; i++) {
181 status = cell->provider->get_sid_from_id(ids[i]->sid,
184 /* Fail if we cannot find any DC */
186 (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
190 if (!NT_STATUS_IS_OK(status)) {
191 ids[i]->status = ID_UNMAPPED;
196 ids[i]->status = ID_MAPPED;
203 /**********************************************************************
204 *********************************************************************/
206 static NTSTATUS _idmap_adex_get_id_from_sid(struct
213 bool one_mapped = false;
214 bool all_mapped = true;
216 struct likewise_cell *cell;
218 /* initialize the status to avoid suprise */
219 for (i = 0; ids[i]; i++) {
220 ids[i]->status = ID_UNKNOWN;
223 nt_status = _idmap_adex_init(dom, NULL);
224 if (!NT_STATUS_IS_OK(nt_status))
227 if ((cell = cell_list_head()) == NULL) {
228 return NT_STATUS_INVALID_SERVER_STATE;
231 /* have to work through these one by one */
232 for (i = 0; ids[i]; i++) {
234 status = cell->provider->get_id_from_sid(&ids[i]->xid.id,
237 /* Fail if we cannot find any DC */
239 (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
243 if (!NT_STATUS_IS_OK(status)) {
244 ids[i]->status = ID_UNMAPPED;
249 ids[i]->status = ID_MAPPED;
256 /**********************************************************************
257 *********************************************************************/
259 static NTSTATUS _idmap_adex_set_mapping(struct
264 DEBUG(0, ("_idmap_adex_set_mapping: not implemented\n"));
265 return NT_STATUS_NOT_IMPLEMENTED;
268 /**********************************************************************
269 *********************************************************************/
271 static NTSTATUS _idmap_adex_remove_mapping(struct
278 DEBUG(0, ("_idmap_adex_remove_mapping: not implemented\n"));
279 return NT_STATUS_NOT_IMPLEMENTED;
282 /**********************************************************************
283 *********************************************************************/
285 static NTSTATUS _idmap_adex_dump(struct idmap_domain
286 *dom, struct id_map **maps, int *num_map)
288 return NT_STATUS_NOT_IMPLEMENTED;
291 /**********************************************************************
292 *********************************************************************/
294 static NTSTATUS _idmap_adex_close(struct idmap_domain
297 /* FIXME! need to do cleanup here */
306 /**********************************************************************
307 *********************************************************************/
309 static NTSTATUS _nss_adex_init(struct nss_domain_entry
312 return _idmap_adex_init(NULL, NULL);
315 /**********************************************************************
316 *********************************************************************/
318 static NTSTATUS _nss_adex_get_info(struct
320 const struct dom_sid * sid,
324 const char **homedir,
326 const char **gecos, gid_t * p_gid)
329 struct likewise_cell *cell;
331 nt_status = _idmap_adex_init(NULL, NULL);
332 if (!NT_STATUS_IS_OK(nt_status))
335 if ((cell = cell_list_head()) == NULL) {
336 return NT_STATUS_INVALID_SERVER_STATE;
339 return cell->provider->get_nss_info(sid, ctx, homedir,
340 shell, gecos, p_gid);
343 /**********************************************************************
344 *********************************************************************/
346 static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx,
347 struct nss_domain_entry *e,
348 const char *name, char **alias)
350 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
351 struct likewise_cell *cell = NULL;
353 nt_status = _idmap_adex_init(NULL, NULL);
354 BAIL_ON_NTSTATUS_ERROR(nt_status);
356 if ((cell = cell_list_head()) == NULL) {
357 nt_status = NT_STATUS_INVALID_SERVER_STATE;
358 BAIL_ON_NTSTATUS_ERROR(nt_status);
361 nt_status = cell->provider->map_to_alias(mem_ctx, e->domain,
364 /* go ahead and allow the cache mgr to mark this in
367 if (!NT_STATUS_IS_OK(nt_status))
368 nt_status = NT_STATUS_NONE_MAPPED;
374 /**********************************************************************
375 *********************************************************************/
377 static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx,
378 struct nss_domain_entry *e,
379 const char *alias, char **name)
381 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
382 struct likewise_cell *cell = NULL;
384 nt_status = _idmap_adex_init(NULL, NULL);
385 BAIL_ON_NTSTATUS_ERROR(nt_status);
387 if ((cell = cell_list_head()) == NULL) {
388 nt_status = NT_STATUS_INVALID_SERVER_STATE;
389 BAIL_ON_NTSTATUS_ERROR(nt_status);
393 nt_status = cell->provider->map_from_alias(mem_ctx, e->domain,
396 /* go ahead and allow the cache mgr to mark this in
399 if (!NT_STATUS_IS_OK(nt_status))
400 nt_status = NT_STATUS_NONE_MAPPED;
406 /**********************************************************************
407 *********************************************************************/
409 static NTSTATUS _nss_adex_close(void)
411 return NT_STATUS_NOT_IMPLEMENTED;
414 /**********************************************************************
415 *********************************************************************/
417 static struct idmap_methods adex_idmap_methods = {
419 .init = _idmap_adex_init,
420 .unixids_to_sids = _idmap_adex_get_sid_from_id,
421 .sids_to_unixids = _idmap_adex_get_id_from_sid,
422 .set_mapping = _idmap_adex_set_mapping,
423 .remove_mapping = _idmap_adex_remove_mapping,
424 .dump_data = _idmap_adex_dump,
425 .close_fn = _idmap_adex_close
427 static struct nss_info_methods adex_nss_methods = {
428 .init = _nss_adex_init,
429 .get_nss_info = _nss_adex_get_info,
430 .map_to_alias = _nss_adex_map_to_alias,
431 .map_from_alias = _nss_adex_map_from_alias,
432 .close_fn = _nss_adex_close
435 /**********************************************************************
436 Register with the idmap and idmap_nss subsystems. We have to protect
437 against the idmap and nss_info interfaces being in a half-registered
439 **********************************************************************/
440 NTSTATUS idmap_adex_init(void)
442 static NTSTATUS idmap_status = NT_STATUS_UNSUCCESSFUL;
443 static NTSTATUS nss_status = NT_STATUS_UNSUCCESSFUL;
444 if (!NT_STATUS_IS_OK(idmap_status)) {
446 smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
447 "adex", &adex_idmap_methods);
448 if (!NT_STATUS_IS_OK(idmap_status)) {
450 ("idmap_centeris_init: Failed to register the adex"
456 if (!NT_STATUS_IS_OK(nss_status)) {
458 smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
459 "adex", &adex_nss_methods);
460 if (!NT_STATUS_IS_OK(nss_status)) {
462 ("idmap_adex_init: Failed to register the adex"
471 static NTSTATUS nss_info_adex_init(void)
473 return idmap_adex_init();