/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- _idmap_adex_init
- _idmap_adex_get_sid_from_id
- _idmap_adex_get_id_from_sid
- _idmap_adex_set_mapping
- _idmap_adex_remove_mapping
- _idmap_adex_dump
- _idmap_adex_close
- _nss_adex_init
- _nss_adex_get_info
- _nss_adex_map_to_alias
- _nss_adex_map_from_alias
- _nss_adex_close
- idmap_adex_init
- nss_info_adex_init
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
29 NTSTATUS 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
41 static NTSTATUS _idmap_adex_init(struct idmap_domain *dom,
/* [<][>][^][v][top][bottom][index][help] */
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
125 done:
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
150 static NTSTATUS _idmap_adex_get_sid_from_id(struct
/* [<][>][^][v][top][bottom][index][help] */
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
203 static NTSTATUS _idmap_adex_get_id_from_sid(struct
/* [<][>][^][v][top][bottom][index][help] */
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
256 static NTSTATUS _idmap_adex_set_mapping(struct
/* [<][>][^][v][top][bottom][index][help] */
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
268 static NTSTATUS _idmap_adex_remove_mapping(struct
/* [<][>][^][v][top][bottom][index][help] */
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
282 static NTSTATUS _idmap_adex_dump(struct idmap_domain
/* [<][>][^][v][top][bottom][index][help] */
283 *dom, struct id_map **maps, int *num_map)
284 {
285 return NT_STATUS_NOT_IMPLEMENTED;
286 }
287
288 /**********************************************************************
289 *********************************************************************/
290
291 static NTSTATUS _idmap_adex_close(struct idmap_domain
/* [<][>][^][v][top][bottom][index][help] */
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
306 static NTSTATUS _nss_adex_init(struct nss_domain_entry
/* [<][>][^][v][top][bottom][index][help] */
307 *e)
308 {
309 return _idmap_adex_init(NULL, NULL);
310 }
311
312 /**********************************************************************
313 *********************************************************************/
314
315 static NTSTATUS _nss_adex_get_info(struct
/* [<][>][^][v][top][bottom][index][help] */
316 nss_domain_entry *e,
317 const DOM_SID * sid,
318 TALLOC_CTX * ctx,
319 ADS_STRUCT * ads,
320 LDAPMessage * msg,
321 char **homedir,
322 char **shell, char **gecos, gid_t * p_gid)
323 {
324 NTSTATUS nt_status;
325 struct likewise_cell *cell;
326
327 nt_status = _idmap_adex_init(NULL, NULL);
328 if (!NT_STATUS_IS_OK(nt_status))
329 return nt_status;
330
331 if ((cell = cell_list_head()) == NULL) {
332 return NT_STATUS_INVALID_SERVER_STATE;
333 }
334
335 return cell->provider->get_nss_info(sid, ctx, homedir,
336 shell, gecos, p_gid);
337 }
338
339 /**********************************************************************
340 *********************************************************************/
341
342 static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
343 struct nss_domain_entry *e,
344 const char *name, char **alias)
345 {
346 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
347 struct likewise_cell *cell = NULL;
348
349 nt_status = _idmap_adex_init(NULL, NULL);
350 BAIL_ON_NTSTATUS_ERROR(nt_status);
351
352 if ((cell = cell_list_head()) == NULL) {
353 nt_status = NT_STATUS_INVALID_SERVER_STATE;
354 BAIL_ON_NTSTATUS_ERROR(nt_status);
355 }
356
357 nt_status = cell->provider->map_to_alias(mem_ctx, e->domain,
358 name, alias);
359
360 /* go ahead and allow the cache mgr to mark this in
361 negative cache */
362
363 if (!NT_STATUS_IS_OK(nt_status))
364 nt_status = NT_STATUS_NONE_MAPPED;
365
366 done:
367 return nt_status;
368 }
369
370 /**********************************************************************
371 *********************************************************************/
372
373 static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
374 struct nss_domain_entry *e,
375 const char *alias, char **name)
376 {
377 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
378 struct likewise_cell *cell = NULL;
379
380 nt_status = _idmap_adex_init(NULL, NULL);
381 BAIL_ON_NTSTATUS_ERROR(nt_status);
382
383 if ((cell = cell_list_head()) == NULL) {
384 nt_status = NT_STATUS_INVALID_SERVER_STATE;
385 BAIL_ON_NTSTATUS_ERROR(nt_status);
386 }
387
388
389 nt_status = cell->provider->map_from_alias(mem_ctx, e->domain,
390 alias, name);
391
392 /* go ahead and allow the cache mgr to mark this in
393 negative cache */
394
395 if (!NT_STATUS_IS_OK(nt_status))
396 nt_status = NT_STATUS_NONE_MAPPED;
397
398 done:
399 return nt_status;
400 }
401
402 /**********************************************************************
403 *********************************************************************/
404
405 static NTSTATUS _nss_adex_close(void)
/* [<][>][^][v][top][bottom][index][help] */
406 {
407 return NT_STATUS_NOT_IMPLEMENTED;
408 }
409
410 /**********************************************************************
411 *********************************************************************/
412
413 static struct idmap_methods adex_idmap_methods = {
414
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
422 };
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
429 };
430
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
434 state.
435 **********************************************************************/
436 NTSTATUS idmap_adex_init(void)
/* [<][>][^][v][top][bottom][index][help] */
437 {
438 static NTSTATUS idmap_status = NT_STATUS_UNSUCCESSFUL;
439 static NTSTATUS nss_status = NT_STATUS_UNSUCCESSFUL;
440 if (!NT_STATUS_IS_OK(idmap_status)) {
441 idmap_status =
442 smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
443 "adex", &adex_idmap_methods);
444 if (!NT_STATUS_IS_OK(idmap_status)) {
445 DEBUG(0,
446 ("idmap_centeris_init: Failed to register the adex"
447 "idmap plugin.\n"));
448 return idmap_status;
449 }
450 }
451
452 if (!NT_STATUS_IS_OK(nss_status)) {
453 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)) {
457 DEBUG(0,
458 ("idmap_adex_init: Failed to register the adex"
459 "nss plugin.\n"));
460 return nss_status;
461 }
462 }
463
464 return NT_STATUS_OK;
465 }
466
467 static NTSTATUS nss_info_adex_init(void)
/* [<][>][^][v][top][bottom][index][help] */
468 {
469 return idmap_adex_init();
470 }