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.
22 #include "idmap_adex.h"
25 #define DBGC_CLASS DBGC_IDMAP
27 #define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache"
29 NTSTATUS init_module(void);
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 *******************************************************************/
41 static NTSTATUS _idmap_adex_init(struct idmap_domain *dom,
44 ADS_STRUCT *ads = NULL;
46 static NTSTATUS init_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
49 struct sockaddr_storage ip;
50 struct likewise_cell *lwcell;
52 if (NT_STATUS_IS_OK(init_status))
55 /* Silently fail if we are not a member server in security = ads */
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);
63 /* fetch our domain SID first */
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);
70 /* reuse the same ticket cache as winbindd */
72 setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
74 /* Establish a connection to a DC */
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);
82 secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
83 ads->auth.realm = SMB_STRDUP(lp_realm());
85 /* get the DC name here to setup the server affinity cache and
88 get_dc_name(lp_workgroup(), lp_realm(), dcname, &ip);
90 status = ads_connect(ads);
91 if (!ADS_ERR_OK(status)) {
92 DEBUG(0, ("_idmap_adex_init: ads_connect() failed! (%s)\n",
95 init_status = ads_ntstatus(status);
96 BAIL_ON_NTSTATUS_ERROR(init_status);
99 /* Find out cell membership */
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)));
108 /* Fill in the cell information */
110 lwcell = cell_list_head();
112 init_status = cell_lookup_settings(lwcell);
113 BAIL_ON_NTSTATUS_ERROR(init_status);
115 /* Miscellaneous setup. E.g. set up the list of GC
116 servers and domain list for our forest (does not actually
119 init_status = gc_init_list();
120 BAIL_ON_NTSTATUS_ERROR(init_status);
122 init_status = domain_init_list();
123 BAIL_ON_NTSTATUS_ERROR(init_status);
126 if (!NT_STATUS_IS_OK(init_status)) {
127 DEBUG(1,("Likewise initialization failed (%s)\n",
128 nt_errstr(init_status)));
133 if (!NT_STATUS_IS_OK(init_status)) {
136 /* init_status stores the failure reason but we need to
137 return success or else idmap_init() will drop us from the
142 init_status = NT_STATUS_OK;
147 /**********************************************************************
148 *********************************************************************/
150 static NTSTATUS _idmap_adex_get_sid_from_id(struct
157 bool one_mapped = false;
158 bool all_mapped = true;
160 struct likewise_cell *cell;
162 /* initialize the status to avoid suprise */
163 for (i = 0; ids[i]; i++) {
164 ids[i]->status = ID_UNKNOWN;
167 nt_status = _idmap_adex_init(dom, NULL);
168 if (!NT_STATUS_IS_OK(nt_status))
171 if ((cell = cell_list_head()) == NULL) {
172 return NT_STATUS_INVALID_SERVER_STATE;
175 /* have to work through these one by one */
176 for (i = 0; ids[i]; i++) {
178 status = cell->provider->get_sid_from_id(ids[i]->sid,
181 /* Fail if we cannot find any DC */
183 (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
187 if (!NT_STATUS_IS_OK(status)) {
188 ids[i]->status = ID_UNMAPPED;
193 ids[i]->status = ID_MAPPED;
200 /**********************************************************************
201 *********************************************************************/
203 static NTSTATUS _idmap_adex_get_id_from_sid(struct
210 bool one_mapped = false;
211 bool all_mapped = true;
213 struct likewise_cell *cell;
215 /* initialize the status to avoid suprise */
216 for (i = 0; ids[i]; i++) {
217 ids[i]->status = ID_UNKNOWN;
220 nt_status = _idmap_adex_init(dom, NULL);
221 if (!NT_STATUS_IS_OK(nt_status))
224 if ((cell = cell_list_head()) == NULL) {
225 return NT_STATUS_INVALID_SERVER_STATE;
228 /* have to work through these one by one */
229 for (i = 0; ids[i]; i++) {
231 status = cell->provider->get_id_from_sid(&ids[i]->xid.id,
234 /* Fail if we cannot find any DC */
236 (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
240 if (!NT_STATUS_IS_OK(status)) {
241 ids[i]->status = ID_UNMAPPED;
246 ids[i]->status = ID_MAPPED;
253 /**********************************************************************
254 *********************************************************************/
256 static NTSTATUS _idmap_adex_set_mapping(struct
261 DEBUG(0, ("_idmap_adex_set_mapping: not implemented\n"));
262 return NT_STATUS_NOT_IMPLEMENTED;
265 /**********************************************************************
266 *********************************************************************/
268 static NTSTATUS _idmap_adex_remove_mapping(struct
275 DEBUG(0, ("_idmap_adex_remove_mapping: not implemented\n"));
276 return NT_STATUS_NOT_IMPLEMENTED;
279 /**********************************************************************
280 *********************************************************************/
282 static NTSTATUS _idmap_adex_dump(struct idmap_domain
283 *dom, struct id_map **maps, int *num_map)
285 return NT_STATUS_NOT_IMPLEMENTED;
288 /**********************************************************************
289 *********************************************************************/
291 static NTSTATUS _idmap_adex_close(struct idmap_domain
294 /* FIXME! need to do cleanup here */
303 /**********************************************************************
304 *********************************************************************/
306 static NTSTATUS _nss_adex_init(struct nss_domain_entry
309 return _idmap_adex_init(NULL, NULL);
312 /**********************************************************************
313 *********************************************************************/
315 static NTSTATUS _nss_adex_get_info(struct
322 char **shell, char **gecos, gid_t * p_gid)
325 struct likewise_cell *cell;
327 nt_status = _idmap_adex_init(NULL, NULL);
328 if (!NT_STATUS_IS_OK(nt_status))
331 if ((cell = cell_list_head()) == NULL) {
332 return NT_STATUS_INVALID_SERVER_STATE;
335 return cell->provider->get_nss_info(sid, ctx, homedir,
336 shell, gecos, p_gid);
339 /**********************************************************************
340 *********************************************************************/
342 static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx,
343 struct nss_domain_entry *e,
344 const char *name, char **alias)
346 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
347 struct likewise_cell *cell = NULL;
349 nt_status = _idmap_adex_init(NULL, NULL);
350 BAIL_ON_NTSTATUS_ERROR(nt_status);
352 if ((cell = cell_list_head()) == NULL) {
353 nt_status = NT_STATUS_INVALID_SERVER_STATE;
354 BAIL_ON_NTSTATUS_ERROR(nt_status);
357 nt_status = cell->provider->map_to_alias(mem_ctx, e->domain,
360 /* go ahead and allow the cache mgr to mark this in
363 if (!NT_STATUS_IS_OK(nt_status))
364 nt_status = NT_STATUS_NONE_MAPPED;
370 /**********************************************************************
371 *********************************************************************/
373 static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx,
374 struct nss_domain_entry *e,
375 const char *alias, char **name)
377 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
378 struct likewise_cell *cell = NULL;
380 nt_status = _idmap_adex_init(NULL, NULL);
381 BAIL_ON_NTSTATUS_ERROR(nt_status);
383 if ((cell = cell_list_head()) == NULL) {
384 nt_status = NT_STATUS_INVALID_SERVER_STATE;
385 BAIL_ON_NTSTATUS_ERROR(nt_status);
389 nt_status = cell->provider->map_from_alias(mem_ctx, e->domain,
392 /* go ahead and allow the cache mgr to mark this in
395 if (!NT_STATUS_IS_OK(nt_status))
396 nt_status = NT_STATUS_NONE_MAPPED;
402 /**********************************************************************
403 *********************************************************************/
405 static NTSTATUS _nss_adex_close(void)
407 return NT_STATUS_NOT_IMPLEMENTED;
410 /**********************************************************************
411 *********************************************************************/
413 static struct idmap_methods adex_idmap_methods = {
415 .init = _idmap_adex_init,
416 .unixids_to_sids = _idmap_adex_get_sid_from_id,
417 .sids_to_unixids = _idmap_adex_get_id_from_sid,
418 .set_mapping = _idmap_adex_set_mapping,
419 .remove_mapping = _idmap_adex_remove_mapping,
420 .dump_data = _idmap_adex_dump,
421 .close_fn = _idmap_adex_close
423 static struct nss_info_methods adex_nss_methods = {
424 .init = _nss_adex_init,
425 .get_nss_info = _nss_adex_get_info,
426 .map_to_alias = _nss_adex_map_to_alias,
427 .map_from_alias = _nss_adex_map_from_alias,
428 .close_fn = _nss_adex_close
431 /**********************************************************************
432 Register with the idmap and idmap_nss subsystems. We have to protect
433 against the idmap and nss_info interfaces being in a half-registered
435 **********************************************************************/
436 NTSTATUS idmap_adex_init(void)
438 static NTSTATUS idmap_status = NT_STATUS_UNSUCCESSFUL;
439 static NTSTATUS nss_status = NT_STATUS_UNSUCCESSFUL;
440 if (!NT_STATUS_IS_OK(idmap_status)) {
442 smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
443 "adex", &adex_idmap_methods);
444 if (!NT_STATUS_IS_OK(idmap_status)) {
446 ("idmap_centeris_init: Failed to register the adex"
452 if (!NT_STATUS_IS_OK(nss_status)) {
454 smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
455 "adex", &adex_nss_methods);
456 if (!NT_STATUS_IS_OK(nss_status)) {
458 ("idmap_adex_init: Failed to register the adex"
467 static NTSTATUS nss_info_adex_init(void)
469 return idmap_adex_init();