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"
27 #define DBGC_CLASS DBGC_IDMAP
29 #define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache"
31 NTSTATUS init_module(void);
37 /********************************************************************
38 Basic init function responsible for determining our current mode
39 (standalone or using Centeris Cells). This must return success or
40 it will be dropped from the idmap backend list.
41 *******************************************************************/
43 static NTSTATUS _idmap_adex_init(struct idmap_domain *dom,
46 ADS_STRUCT *ads = NULL;
48 static NTSTATUS init_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
49 struct dom_sid domain_sid;
51 struct sockaddr_storage ip;
52 struct likewise_cell *lwcell;
54 if (NT_STATUS_IS_OK(init_status))
57 /* Silently fail if we are not a member server in security = ads */
59 if ((lp_server_role() != ROLE_DOMAIN_MEMBER) ||
60 (lp_security() != SEC_ADS)) {
61 init_status = NT_STATUS_INVALID_SERVER_STATE;
62 BAIL_ON_NTSTATUS_ERROR(init_status);
65 /* fetch our domain SID first */
67 if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
68 init_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
69 BAIL_ON_NTSTATUS_ERROR(init_status);
72 /* reuse the same ticket cache as winbindd */
74 setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
76 /* Establish a connection to a DC */
78 if ((ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL) {
79 init_status = NT_STATUS_NO_MEMORY;
80 BAIL_ON_NTSTATUS_ERROR(init_status);
84 secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
85 ads->auth.realm = SMB_STRDUP(lp_realm());
87 /* get the DC name here to setup the server affinity cache and
90 get_dc_name(lp_workgroup(), lp_realm(), dcname, &ip);
92 status = ads_connect(ads);
93 if (!ADS_ERR_OK(status)) {
94 DEBUG(0, ("_idmap_adex_init: ads_connect() failed! (%s)\n",
97 init_status = ads_ntstatus(status);
98 BAIL_ON_NTSTATUS_ERROR(init_status);
101 /* Find out cell membership */
103 init_status = cell_locate_membership(ads);
104 if (!NT_STATUS_IS_OK(init_status)) {
105 DEBUG(0,("LWI: Fail to locate cell membership (%s).",
106 nt_errstr(init_status)));
110 /* Fill in the cell information */
112 lwcell = cell_list_head();
114 init_status = cell_lookup_settings(lwcell);
115 BAIL_ON_NTSTATUS_ERROR(init_status);
117 /* Miscellaneous setup. E.g. set up the list of GC
118 servers and domain list for our forest (does not actually
121 init_status = gc_init_list();
122 BAIL_ON_NTSTATUS_ERROR(init_status);
124 init_status = domain_init_list();
125 BAIL_ON_NTSTATUS_ERROR(init_status);
128 if (!NT_STATUS_IS_OK(init_status)) {
129 DEBUG(1,("Likewise initialization failed (%s)\n",
130 nt_errstr(init_status)));
135 if (!NT_STATUS_IS_OK(init_status)) {
138 /* init_status stores the failure reason but we need to
139 return success or else idmap_init() will drop us from the
144 init_status = NT_STATUS_OK;
149 /**********************************************************************
150 *********************************************************************/
152 static NTSTATUS _idmap_adex_get_sid_from_id(struct
159 bool one_mapped = false;
160 bool all_mapped = true;
162 struct likewise_cell *cell;
164 /* initialize the status to avoid suprise */
165 for (i = 0; ids[i]; i++) {
166 ids[i]->status = ID_UNKNOWN;
169 nt_status = _idmap_adex_init(dom, NULL);
170 if (!NT_STATUS_IS_OK(nt_status))
173 if ((cell = cell_list_head()) == NULL) {
174 return NT_STATUS_INVALID_SERVER_STATE;
177 /* have to work through these one by one */
178 for (i = 0; ids[i]; i++) {
180 status = cell->provider->get_sid_from_id(ids[i]->sid,
183 /* Fail if we cannot find any DC */
185 (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
189 if (!NT_STATUS_IS_OK(status)) {
190 ids[i]->status = ID_UNMAPPED;
195 ids[i]->status = ID_MAPPED;
202 /**********************************************************************
203 *********************************************************************/
205 static NTSTATUS _idmap_adex_get_id_from_sid(struct
212 bool one_mapped = false;
213 bool all_mapped = true;
215 struct likewise_cell *cell;
217 /* initialize the status to avoid suprise */
218 for (i = 0; ids[i]; i++) {
219 ids[i]->status = ID_UNKNOWN;
222 nt_status = _idmap_adex_init(dom, NULL);
223 if (!NT_STATUS_IS_OK(nt_status))
226 if ((cell = cell_list_head()) == NULL) {
227 return NT_STATUS_INVALID_SERVER_STATE;
230 /* have to work through these one by one */
231 for (i = 0; ids[i]; i++) {
233 status = cell->provider->get_id_from_sid(&ids[i]->xid.id,
236 /* Fail if we cannot find any DC */
238 (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
242 if (!NT_STATUS_IS_OK(status)) {
243 ids[i]->status = ID_UNMAPPED;
248 ids[i]->status = ID_MAPPED;
255 /**********************************************************************
256 *********************************************************************/
258 static NTSTATUS _idmap_adex_set_mapping(struct
263 DEBUG(0, ("_idmap_adex_set_mapping: not implemented\n"));
264 return NT_STATUS_NOT_IMPLEMENTED;
267 /**********************************************************************
268 *********************************************************************/
270 static NTSTATUS _idmap_adex_remove_mapping(struct
277 DEBUG(0, ("_idmap_adex_remove_mapping: not implemented\n"));
278 return NT_STATUS_NOT_IMPLEMENTED;
281 /**********************************************************************
282 *********************************************************************/
284 static NTSTATUS _idmap_adex_dump(struct idmap_domain
285 *dom, struct id_map **maps, int *num_map)
287 return NT_STATUS_NOT_IMPLEMENTED;
290 /**********************************************************************
291 *********************************************************************/
293 static NTSTATUS _idmap_adex_close(struct idmap_domain
296 /* FIXME! need to do cleanup here */
305 /**********************************************************************
306 *********************************************************************/
308 static NTSTATUS _nss_adex_init(struct nss_domain_entry
311 return _idmap_adex_init(NULL, NULL);
314 /**********************************************************************
315 *********************************************************************/
317 static NTSTATUS _nss_adex_get_info(struct
319 const struct dom_sid * sid,
323 const char **homedir,
325 const char **gecos, gid_t * p_gid)
328 struct likewise_cell *cell;
330 nt_status = _idmap_adex_init(NULL, NULL);
331 if (!NT_STATUS_IS_OK(nt_status))
334 if ((cell = cell_list_head()) == NULL) {
335 return NT_STATUS_INVALID_SERVER_STATE;
338 return cell->provider->get_nss_info(sid, ctx, homedir,
339 shell, gecos, p_gid);
342 /**********************************************************************
343 *********************************************************************/
345 static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx,
346 struct nss_domain_entry *e,
347 const char *name, char **alias)
349 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
350 struct likewise_cell *cell = NULL;
352 nt_status = _idmap_adex_init(NULL, NULL);
353 BAIL_ON_NTSTATUS_ERROR(nt_status);
355 if ((cell = cell_list_head()) == NULL) {
356 nt_status = NT_STATUS_INVALID_SERVER_STATE;
357 BAIL_ON_NTSTATUS_ERROR(nt_status);
360 nt_status = cell->provider->map_to_alias(mem_ctx, e->domain,
363 /* go ahead and allow the cache mgr to mark this in
366 if (!NT_STATUS_IS_OK(nt_status))
367 nt_status = NT_STATUS_NONE_MAPPED;
373 /**********************************************************************
374 *********************************************************************/
376 static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx,
377 struct nss_domain_entry *e,
378 const char *alias, char **name)
380 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
381 struct likewise_cell *cell = NULL;
383 nt_status = _idmap_adex_init(NULL, NULL);
384 BAIL_ON_NTSTATUS_ERROR(nt_status);
386 if ((cell = cell_list_head()) == NULL) {
387 nt_status = NT_STATUS_INVALID_SERVER_STATE;
388 BAIL_ON_NTSTATUS_ERROR(nt_status);
392 nt_status = cell->provider->map_from_alias(mem_ctx, e->domain,
395 /* go ahead and allow the cache mgr to mark this in
398 if (!NT_STATUS_IS_OK(nt_status))
399 nt_status = NT_STATUS_NONE_MAPPED;
405 /**********************************************************************
406 *********************************************************************/
408 static NTSTATUS _nss_adex_close(void)
410 return NT_STATUS_NOT_IMPLEMENTED;
413 /**********************************************************************
414 *********************************************************************/
416 static struct idmap_methods adex_idmap_methods = {
418 .init = _idmap_adex_init,
419 .unixids_to_sids = _idmap_adex_get_sid_from_id,
420 .sids_to_unixids = _idmap_adex_get_id_from_sid,
421 .set_mapping = _idmap_adex_set_mapping,
422 .remove_mapping = _idmap_adex_remove_mapping,
423 .dump_data = _idmap_adex_dump,
424 .close_fn = _idmap_adex_close
426 static struct nss_info_methods adex_nss_methods = {
427 .init = _nss_adex_init,
428 .get_nss_info = _nss_adex_get_info,
429 .map_to_alias = _nss_adex_map_to_alias,
430 .map_from_alias = _nss_adex_map_from_alias,
431 .close_fn = _nss_adex_close
434 /**********************************************************************
435 Register with the idmap and idmap_nss subsystems. We have to protect
436 against the idmap and nss_info interfaces being in a half-registered
438 **********************************************************************/
439 NTSTATUS idmap_adex_init(void)
441 static NTSTATUS idmap_status = NT_STATUS_UNSUCCESSFUL;
442 static NTSTATUS nss_status = NT_STATUS_UNSUCCESSFUL;
443 if (!NT_STATUS_IS_OK(idmap_status)) {
445 smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
446 "adex", &adex_idmap_methods);
447 if (!NT_STATUS_IS_OK(idmap_status)) {
449 ("idmap_centeris_init: Failed to register the adex"
455 if (!NT_STATUS_IS_OK(nss_status)) {
457 smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
458 "adex", &adex_nss_methods);
459 if (!NT_STATUS_IS_OK(nss_status)) {
461 ("idmap_adex_init: Failed to register the adex"
470 static NTSTATUS nss_info_adex_init(void)
472 return idmap_adex_init();