source: vendor/current/source3/winbindd/idmap_rfc2307.c

Last change on this file was 989, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.7

File size: 19.5 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 *
4 * Id mapping using LDAP records as defined in RFC 2307
5 *
6 * The SID<->uid/gid mapping is performed in two steps: 1) Query the
7 * AD server for the name<->sid mapping. 2) Query an LDAP server
8 * according to RFC 2307 for the name<->uid/gid mapping.
9 *
10 * Copyright (C) Christof Schmitt 2012,2013
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "includes.h"
27#include "winbindd.h"
28#include "ads.h"
29#include "idmap.h"
30#include "smbldap.h"
31#include "nsswitch/winbind_client.h"
32#include "lib/winbind_util.h"
33
34/*
35 * Config and connection info per domain.
36 */
37struct idmap_rfc2307_context {
38 const char *bind_path_user;
39 const char *bind_path_group;
40 const char *ldap_domain;
41 bool user_cn;
42 const char *realm;
43
44 /*
45 * Pointer to ldap struct in ads or smbldap_state, has to be
46 * updated after connecting to server
47 */
48 LDAP *ldap;
49
50 /* Optional function to check connection to server */
51 NTSTATUS (*check_connection)(struct idmap_domain *dom);
52
53 /* Issue ldap query */
54 NTSTATUS (*search)(struct idmap_rfc2307_context *ctx,
55 const char *bind_path, const char *expr,
56 const char **attrs, LDAPMessage **res);
57
58 /* Access to LDAP in AD server */
59 ADS_STRUCT *ads;
60
61 /* Access to stand-alone LDAP server */
62 struct smbldap_state *smbldap_state;
63};
64
65/*
66 * backend functions for LDAP queries through ADS
67 */
68
69static NTSTATUS idmap_rfc2307_ads_check_connection(struct idmap_domain *dom)
70{
71 struct idmap_rfc2307_context *ctx;
72 const char *dom_name = dom->name;
73 ADS_STATUS status;
74
75 DEBUG(10, ("ad_idmap_cached_connection: called for domain '%s'\n",
76 dom->name));
77
78 ctx = talloc_get_type(dom->private_data, struct idmap_rfc2307_context);
79 dom_name = ctx->ldap_domain ? ctx->ldap_domain : dom->name;
80
81 status = ads_idmap_cached_connection(&ctx->ads, dom_name);
82 if (ADS_ERR_OK(status)) {
83 ctx->ldap = ctx->ads->ldap.ld;
84 } else {
85 DEBUG(1, ("Could not connect to domain %s: %s\n", dom->name,
86 ads_errstr(status)));
87 }
88
89 return ads_ntstatus(status);
90}
91
92static NTSTATUS idmap_rfc2307_ads_search(struct idmap_rfc2307_context *ctx,
93 const char *bind_path,
94 const char *expr,
95 const char **attrs,
96 LDAPMessage **result)
97{
98 ADS_STATUS status;
99
100 status = ads_do_search_retry(ctx->ads, bind_path,
101 LDAP_SCOPE_SUBTREE, expr, attrs, result);
102 ctx->ldap = ctx->ads->ldap.ld;
103 return ads_ntstatus(status);
104}
105
106static NTSTATUS idmap_rfc2307_init_ads(struct idmap_rfc2307_context *ctx,
107 const char *cfg_opt)
108{
109 const char *ldap_domain;
110
111 ctx->search = idmap_rfc2307_ads_search;
112 ctx->check_connection = idmap_rfc2307_ads_check_connection;
113
114 ldap_domain = lp_parm_const_string(-1, cfg_opt, "ldap_domain",
115 NULL);
116 if (ldap_domain) {
117 ctx->ldap_domain = talloc_strdup(ctx, ldap_domain);
118 if (ctx->ldap_domain == NULL) {
119 return NT_STATUS_NO_MEMORY;
120 }
121 }
122
123 return NT_STATUS_OK;
124}
125
126/*
127 * backend function for LDAP queries through stand-alone LDAP server
128 */
129
130static NTSTATUS idmap_rfc2307_ldap_search(struct idmap_rfc2307_context *ctx,
131 const char *bind_path,
132 const char *expr,
133 const char **attrs,
134 LDAPMessage **result)
135{
136 int ret;
137
138 ret = smbldap_search(ctx->smbldap_state, bind_path, LDAP_SCOPE_SUBTREE,
139 expr, attrs, 0, result);
140 ctx->ldap = ctx->smbldap_state->ldap_struct;
141
142 if (ret == LDAP_SUCCESS) {
143 return NT_STATUS_OK;
144 }
145
146 return NT_STATUS_LDAP(ret);
147}
148
149static bool idmap_rfc2307_get_uint32(LDAP *ldap, LDAPMessage *entry,
150 const char *field, uint32_t *value)
151{
152 bool b;
153 char str[20];
154
155 b = smbldap_get_single_attribute(ldap, entry, field, str, sizeof(str));
156
157 if (b) {
158 *value = atoi(str);
159 }
160
161 return b;
162}
163
164static NTSTATUS idmap_rfc2307_init_ldap(struct idmap_rfc2307_context *ctx,
165 struct idmap_domain *dom,
166 const char *config_option)
167{
168 NTSTATUS ret;
169 char *url;
170 char *secret = NULL;
171 const char *ldap_url, *user_dn;
172 TALLOC_CTX *mem_ctx = ctx;
173
174 ldap_url = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
175 if (!ldap_url) {
176 DEBUG(1, ("ERROR: missing idmap ldap url\n"));
177 return NT_STATUS_UNSUCCESSFUL;
178 }
179
180 url = talloc_strdup(talloc_tos(), ldap_url);
181
182 user_dn = lp_parm_const_string(-1, config_option, "ldap_user_dn", NULL);
183 if (user_dn) {
184 secret = idmap_fetch_secret("ldap", dom->name, user_dn);
185 if (!secret) {
186 ret = NT_STATUS_ACCESS_DENIED;
187 goto done;
188 }
189 }
190
191 /* assume anonymous if we don't have a specified user */
192 ret = smbldap_init(mem_ctx, winbind_event_context(), url,
193 (user_dn == NULL), user_dn, secret,
194 &ctx->smbldap_state);
195 SAFE_FREE(secret);
196 if (!NT_STATUS_IS_OK(ret)) {
197 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", url));
198 goto done;
199 }
200
201 ctx->search = idmap_rfc2307_ldap_search;
202
203done:
204 talloc_free(url);
205 return ret;
206}
207
208/*
209 * common code for stand-alone LDAP and ADS
210 */
211
212static void idmap_rfc2307_map_sid_results(struct idmap_rfc2307_context *ctx,
213 TALLOC_CTX *mem_ctx,
214 struct id_map **ids,
215 LDAPMessage *result,
216 const char *dom_name,
217 const char **attrs, int type)
218{
219 int count, i;
220 LDAPMessage *entry;
221
222 count = ldap_count_entries(ctx->ldap, result);
223
224 for (i = 0; i < count; i++) {
225 char *name;
226 enum lsa_SidType lsa_type;
227 struct id_map *map;
228 uint32_t id;
229 bool b;
230
231 if (i == 0) {
232 entry = ldap_first_entry(ctx->ldap, result);
233 } else {
234 entry = ldap_next_entry(ctx->ldap, result);
235 }
236 if (!entry) {
237 DEBUG(2, ("Unable to fetch entry.\n"));
238 break;
239 }
240
241 name = smbldap_talloc_single_attribute(ctx->ldap, entry,
242 attrs[0], mem_ctx);
243 if (!name) {
244 DEBUG(1, ("Could not get user name\n"));
245 continue;
246 }
247
248 b = idmap_rfc2307_get_uint32(ctx->ldap, entry, attrs[1], &id);
249 if (!b) {
250 DEBUG(1, ("Could not pull id for record %s\n", name));
251 continue;
252 }
253
254 map = idmap_find_map_by_id(ids, type, id);
255 if (!map) {
256 DEBUG(1, ("Could not find id %d, name %s\n", id, name));
257 continue;
258 }
259
260 if (ctx->realm != NULL) {
261 /* Strip @realm from user or group name */
262 char *delim;
263
264 delim = strchr(name, '@');
265 if (delim) {
266 *delim = '\0';
267 }
268 }
269
270 /* by default calls to winbindd are disabled
271 the following call will not recurse so this is safe */
272 (void)winbind_on();
273 /* Lookup name from PDC using lsa_lookup_names() */
274 b = winbind_lookup_name(dom_name, name, map->sid, &lsa_type);
275 (void)winbind_off();
276
277 if (!b) {
278 DEBUG(1, ("SID lookup failed for id %d, %s\n",
279 id, name));
280 continue;
281 }
282
283 if (type == ID_TYPE_UID && lsa_type != SID_NAME_USER) {
284 DEBUG(1, ("Wrong type %d for user name %s\n",
285 type, name));
286 continue;
287 }
288
289 if (type == ID_TYPE_GID && lsa_type != SID_NAME_DOM_GRP &&
290 lsa_type != SID_NAME_ALIAS &&
291 lsa_type != SID_NAME_WKN_GRP) {
292 DEBUG(1, ("Wrong type %d for group name %s\n",
293 type, name));
294 continue;
295 }
296
297 map->status = ID_MAPPED;
298 }
299}
300
301/*
302 * Map unixids to names and then to sids.
303 */
304static NTSTATUS idmap_rfc2307_unixids_to_sids(struct idmap_domain *dom,
305 struct id_map **ids)
306{
307 struct idmap_rfc2307_context *ctx;
308 char *fltr_usr = NULL, *fltr_grp = NULL;
309 TALLOC_CTX *mem_ctx;
310 int cnt_usr = 0, cnt_grp = 0, idx = 0, bidx = 0;
311 LDAPMessage *result = NULL;
312 NTSTATUS ret;
313
314 ctx = talloc_get_type(dom->private_data, struct idmap_rfc2307_context);
315 mem_ctx = talloc_new(ctx);
316 if (!mem_ctx) {
317 return NT_STATUS_NO_MEMORY;
318 }
319
320 if (ctx->check_connection) {
321 ret = ctx->check_connection(dom);
322 if (!NT_STATUS_IS_OK(ret)) {
323 goto out;
324 }
325 }
326
327again:
328 bidx = idx;
329
330 if (!fltr_usr) {
331 /* prepare new user query, see getpwuid() in RFC2307 */
332 fltr_usr = talloc_asprintf(mem_ctx,
333 "(&(objectClass=posixAccount)(|");
334 }
335
336 if (!fltr_grp) {
337 /* prepare new group query, see getgrgid() in RFC2307 */
338 fltr_grp = talloc_asprintf(mem_ctx,
339 "(&(objectClass=posixGroup)(|");
340 }
341
342 if (!fltr_usr || !fltr_grp) {
343 ret = NT_STATUS_NO_MEMORY;
344 goto out;
345 }
346
347 while (cnt_usr < IDMAP_LDAP_MAX_IDS &&
348 cnt_grp < IDMAP_LDAP_MAX_IDS && ids[idx]) {
349
350 switch (ids[idx]->xid.type) {
351 case ID_TYPE_UID:
352 fltr_usr = talloc_asprintf_append_buffer(fltr_usr,
353 "(uidNumber=%d)", ids[idx]->xid.id);
354 cnt_usr++;
355 break;
356 case ID_TYPE_GID:
357 fltr_grp = talloc_asprintf_append_buffer(fltr_grp,
358 "(gidNumber=%d)", ids[idx]->xid.id);
359 cnt_grp++;
360 break;
361 default:
362 DEBUG(3, ("Error: unknown ID type %d\n",
363 ids[idx]->xid.type));
364 ret = NT_STATUS_UNSUCCESSFUL;
365 goto out;
366 }
367
368 if (!fltr_usr || !fltr_grp) {
369 ret = NT_STATUS_NO_MEMORY;
370 goto out;
371 }
372
373 idx++;
374 }
375
376 if (cnt_usr == IDMAP_LDAP_MAX_IDS || (cnt_usr != 0 && !ids[idx])) {
377 const char *attrs[] = { NULL, /* uid or cn */
378 "uidNumber",
379 NULL };
380
381 fltr_usr = talloc_strdup_append(fltr_usr, "))");
382 if (!fltr_usr) {
383 ret = NT_STATUS_NO_MEMORY;
384 goto out;
385 }
386
387 attrs[0] = ctx->user_cn ? "cn" : "uid";
388 ret = ctx->search(ctx, ctx->bind_path_user, fltr_usr, attrs,
389 &result);
390 if (!NT_STATUS_IS_OK(ret)) {
391 goto out;
392 }
393
394 idmap_rfc2307_map_sid_results(ctx, mem_ctx, &ids[bidx], result,
395 dom->name, attrs, ID_TYPE_UID);
396 cnt_usr = 0;
397 TALLOC_FREE(fltr_usr);
398 }
399
400 if (cnt_grp == IDMAP_LDAP_MAX_IDS || (cnt_grp != 0 && !ids[idx])) {
401 const char *attrs[] = { "cn", "gidNumber", NULL };
402
403 fltr_grp = talloc_strdup_append(fltr_grp, "))");
404 if (!fltr_grp) {
405 ret = NT_STATUS_NO_MEMORY;
406 goto out;
407 }
408 ret = ctx->search(ctx, ctx->bind_path_group, fltr_grp, attrs,
409 &result);
410 if (!NT_STATUS_IS_OK(ret)) {
411 goto out;
412 }
413
414 idmap_rfc2307_map_sid_results(ctx, mem_ctx, &ids[bidx], result,
415 dom->name, attrs, ID_TYPE_GID);
416 cnt_grp = 0;
417 TALLOC_FREE(fltr_grp);
418 }
419
420 if (ids[idx]) {
421 goto again;
422 }
423
424 ret = NT_STATUS_OK;
425
426out:
427 talloc_free(mem_ctx);
428 return ret;
429}
430
431struct idmap_rfc2307_map {
432 struct id_map *map;
433 const char *name;
434 enum id_type type;
435};
436
437/*
438 * Lookup names for SIDS and store the data in the local mapping
439 * array.
440 */
441static NTSTATUS idmap_rfc_2307_sids_to_names(TALLOC_CTX *mem_ctx,
442 struct id_map **ids,
443 struct idmap_rfc2307_map *maps,
444 struct idmap_rfc2307_context *ctx)
445{
446 int i;
447
448 for (i = 0; ids[i]; i++) {
449 const char *domain, *name;
450 enum lsa_SidType lsa_type;
451 struct id_map *id = ids[i];
452 struct idmap_rfc2307_map *map = &maps[i];
453 bool b;
454
455 /* by default calls to winbindd are disabled
456 the following call will not recurse so this is safe */
457 (void)winbind_on();
458 b = winbind_lookup_sid(mem_ctx, ids[i]->sid, &domain, &name,
459 &lsa_type);
460 (void)winbind_off();
461
462 if (!b) {
463 DEBUG(1, ("Lookup sid %s failed.\n",
464 sid_string_dbg(ids[i]->sid)));
465 continue;
466 }
467
468 switch(lsa_type) {
469 case SID_NAME_USER:
470 id->xid.type = map->type = ID_TYPE_UID;
471 if (ctx->user_cn && ctx->realm != NULL) {
472 name = talloc_asprintf(mem_ctx, "%s@%s",
473 name, ctx->realm);
474 }
475 id->xid.type = map->type = ID_TYPE_UID;
476 break;
477
478 case SID_NAME_DOM_GRP:
479 case SID_NAME_ALIAS:
480 case SID_NAME_WKN_GRP:
481 if (ctx->realm != NULL) {
482 name = talloc_asprintf(mem_ctx, "%s@%s",
483 name, ctx->realm);
484 }
485 id->xid.type = map->type = ID_TYPE_GID;
486 break;
487
488 default:
489 DEBUG(1, ("Unknown lsa type %d for sid %s\n",
490 lsa_type, sid_string_dbg(id->sid)));
491 id->status = ID_UNMAPPED;
492 continue;
493 }
494
495 map->map = id;
496 id->status = ID_UNKNOWN;
497 map->name = strupper_talloc(mem_ctx, name);
498
499 if (!map->name) {
500 return NT_STATUS_NO_MEMORY;
501 }
502 }
503
504 return NT_STATUS_OK;
505}
506
507/*
508 * Find id_map entry by looking up the name in the internal
509 * mapping array.
510 */
511static struct id_map* idmap_rfc2307_find_map(struct idmap_rfc2307_map *maps,
512 enum id_type type,
513 const char *name)
514{
515 int i;
516
517 DEBUG(10, ("Looking for name %s, type %d\n", name, type));
518
519 for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {
520 if (maps[i].map == NULL) { /* end of the run */
521 return NULL;
522 }
523 DEBUG(10, ("Entry %d: name %s, type %d\n",
524 i, maps[i].name, maps[i].type));
525 if (type == maps[i].type && strcmp(name, maps[i].name) == 0) {
526 return maps[i].map;
527 }
528 }
529
530 return NULL;
531}
532
533static void idmap_rfc2307_map_xid_results(struct idmap_rfc2307_context *ctx,
534 TALLOC_CTX *mem_ctx,
535 struct idmap_rfc2307_map *maps,
536 LDAPMessage *result,
537 struct idmap_domain *dom,
538 const char **attrs, enum id_type type)
539{
540 int count, i;
541 LDAPMessage *entry;
542
543 count = ldap_count_entries(ctx->ldap, result);
544
545 for (i = 0; i < count; i++) {
546 uint32_t id;
547 char *name;
548 bool b;
549 struct id_map *id_map;
550
551 if (i == 0) {
552 entry = ldap_first_entry(ctx->ldap, result);
553 } else {
554 entry = ldap_next_entry(ctx->ldap, result);
555 }
556 if (!entry) {
557 DEBUG(2, ("Unable to fetch entry.\n"));
558 break;
559 }
560
561 name = smbldap_talloc_single_attribute(ctx->ldap, entry,
562 attrs[0], mem_ctx);
563 if (!name) {
564 DEBUG(1, ("Could not get user name\n"));
565 continue;
566 }
567
568 b = idmap_rfc2307_get_uint32(ctx->ldap, entry, attrs[1], &id);
569 if (!b) {
570 DEBUG(5, ("Could not pull id for record %s\n", name));
571 continue;
572 }
573
574 if (!idmap_unix_id_is_in_range(id, dom)) {
575 DEBUG(5, ("Requested id (%u) out of range (%u - %u).\n",
576 id, dom->low_id, dom->high_id));
577 continue;
578 }
579
580 if (!strupper_m(name)) {
581 DEBUG(5, ("Could not convert %s to uppercase\n", name));
582 continue;
583 }
584 id_map = idmap_rfc2307_find_map(maps, type, name);
585 if (!id_map) {
586 DEBUG(0, ("Could not find mapping entry for name %s\n",
587 name));
588 continue;
589 }
590
591 id_map->xid.id = id;
592 id_map->status = ID_MAPPED;
593 }
594}
595
596/*
597 * Map sids to names and then to unixids.
598 */
599static NTSTATUS idmap_rfc2307_sids_to_unixids(struct idmap_domain *dom,
600 struct id_map **ids)
601{
602 struct idmap_rfc2307_context *ctx;
603 TALLOC_CTX *mem_ctx;
604 struct idmap_rfc2307_map *int_maps;
605 int cnt_usr = 0, cnt_grp = 0, idx = 0;
606 char *fltr_usr = NULL, *fltr_grp = NULL;
607 NTSTATUS ret;
608 int i;
609
610 ctx = talloc_get_type(dom->private_data, struct idmap_rfc2307_context);
611 mem_ctx = talloc_new(talloc_tos());
612 if (!mem_ctx) {
613 return NT_STATUS_NO_MEMORY;
614 }
615
616 if (ctx->check_connection) {
617 ret = ctx->check_connection(dom);
618 if (!NT_STATUS_IS_OK(ret)) {
619 goto out;
620 }
621 }
622
623 for (i = 0; ids[i]; i++);
624 int_maps = talloc_zero_array(mem_ctx, struct idmap_rfc2307_map, i);
625 if (!int_maps) {
626 ret = NT_STATUS_NO_MEMORY;
627 goto out;
628 }
629
630 ret = idmap_rfc_2307_sids_to_names(mem_ctx, ids, int_maps, ctx);
631 if (!NT_STATUS_IS_OK(ret)) {
632 goto out;
633 }
634
635again:
636 if (!fltr_usr) {
637 /* prepare new user query, see getpwuid() in RFC2307 */
638 fltr_usr = talloc_asprintf(mem_ctx,
639 "(&(objectClass=posixAccount)(|");
640 }
641
642 if (!fltr_grp) {
643 /* prepare new group query, see getgrgid() in RFC2307 */
644 fltr_grp = talloc_asprintf(mem_ctx,
645 "(&(objectClass=posixGroup)(|");
646 }
647
648 if (!fltr_usr || !fltr_grp) {
649 ret = NT_STATUS_NO_MEMORY;
650 goto out;
651 }
652
653 while (cnt_usr < IDMAP_LDAP_MAX_IDS &&
654 cnt_grp < IDMAP_LDAP_MAX_IDS && ids[idx]) {
655 struct id_map *id = ids[idx];
656 struct idmap_rfc2307_map *map = &int_maps[idx];
657
658 switch(id->xid.type) {
659 case ID_TYPE_UID:
660 fltr_usr = talloc_asprintf_append_buffer(fltr_usr,
661 "(%s=%s)", (ctx->user_cn ? "cn" : "uid"),
662 map->name);
663 cnt_usr++;
664 break;
665
666 case ID_TYPE_GID:
667 fltr_grp = talloc_asprintf_append_buffer(fltr_grp,
668 "(cn=%s)", map->name);
669 cnt_grp++;
670 break;
671
672 default:
673 break;
674 }
675
676 if (!fltr_usr || !fltr_grp) {
677 ret = NT_STATUS_NO_MEMORY;
678 goto out;
679 }
680
681 idx++;
682 }
683
684 if (cnt_usr == IDMAP_LDAP_MAX_IDS || (cnt_usr != 0 && !ids[idx])) {
685 const char *attrs[] = { NULL, /* uid or cn */
686 "uidNumber",
687 NULL };
688 LDAPMessage *result;
689
690 fltr_usr = talloc_strdup_append(fltr_usr, "))");
691 if (!fltr_usr) {
692 ret = NT_STATUS_NO_MEMORY;
693 goto out;
694 }
695
696 attrs[0] = ctx->user_cn ? "cn" : "uid";
697 ret = ctx->search(ctx, ctx->bind_path_user, fltr_usr, attrs,
698 &result);
699 if (!NT_STATUS_IS_OK(ret)) {
700 goto out;
701 }
702
703 idmap_rfc2307_map_xid_results(ctx, mem_ctx, int_maps,
704 result, dom, attrs, ID_TYPE_UID);
705
706 cnt_usr = 0;
707 TALLOC_FREE(fltr_usr);
708 }
709
710 if (cnt_grp == IDMAP_LDAP_MAX_IDS || (cnt_grp != 0 && !ids[idx])) {
711 const char *attrs[] = {"cn", "gidNumber", NULL };
712 LDAPMessage *result;
713
714 fltr_grp = talloc_strdup_append(fltr_grp, "))");
715 if (!fltr_grp) {
716 ret = NT_STATUS_NO_MEMORY;
717 goto out;
718 }
719
720 ret = ctx->search(ctx, ctx->bind_path_group, fltr_grp, attrs,
721 &result);
722 if (!NT_STATUS_IS_OK(ret)) {
723 goto out;
724 }
725
726 idmap_rfc2307_map_xid_results(ctx, mem_ctx, int_maps, result,
727 dom, attrs, ID_TYPE_GID);
728 cnt_grp = 0;
729 TALLOC_FREE(fltr_grp);
730 }
731
732 if (ids[idx]) {
733 goto again;
734 }
735
736 ret = NT_STATUS_OK;
737
738out:
739 talloc_free(mem_ctx);
740 return ret;
741}
742
743static int idmap_rfc2307_context_destructor(struct idmap_rfc2307_context *ctx)
744{
745 if (ctx->ads != NULL) {
746 /* we own this ADS_STRUCT so make sure it goes away */
747 ctx->ads->is_mine = True;
748 ads_destroy( &ctx->ads );
749 ctx->ads = NULL;
750 }
751
752 if (ctx->smbldap_state != NULL) {
753 smbldap_free_struct(&ctx->smbldap_state);
754 }
755
756 return 0;
757}
758
759static NTSTATUS idmap_rfc2307_initialize(struct idmap_domain *domain)
760{
761 struct idmap_rfc2307_context *ctx;
762 char *cfg_opt;
763 const char *bind_path_user, *bind_path_group, *ldap_server, *realm;
764 NTSTATUS status;
765
766 ctx = talloc_zero(domain, struct idmap_rfc2307_context);
767 if (ctx == NULL) {
768 return NT_STATUS_NO_MEMORY;
769 }
770 talloc_set_destructor(ctx, idmap_rfc2307_context_destructor);
771
772 cfg_opt = talloc_asprintf(ctx, "idmap config %s", domain->name);
773 if (cfg_opt == NULL) {
774 status = NT_STATUS_NO_MEMORY;
775 goto err;
776 }
777
778 bind_path_user = lp_parm_const_string(-1, cfg_opt, "bind_path_user",
779 NULL);
780 if (bind_path_user) {
781 ctx->bind_path_user = talloc_strdup(ctx, bind_path_user);
782 if (ctx->bind_path_user == NULL) {
783 status = NT_STATUS_NO_MEMORY;
784 goto err;
785 }
786 } else {
787 status = NT_STATUS_INVALID_PARAMETER;
788 goto err;
789 }
790
791 bind_path_group = lp_parm_const_string(-1, cfg_opt, "bind_path_group",
792 NULL);
793 if (bind_path_group) {
794 ctx->bind_path_group = talloc_strdup(ctx, bind_path_group);
795 if (ctx->bind_path_group == NULL) {
796 status = NT_STATUS_NO_MEMORY;
797 goto err;
798 }
799 } else {
800 status = NT_STATUS_INVALID_PARAMETER;
801 goto err;
802 }
803
804 ldap_server = lp_parm_const_string(-1, cfg_opt, "ldap_server", NULL);
805 if (!ldap_server) {
806 status = NT_STATUS_INVALID_PARAMETER;
807 goto err;
808 }
809
810 if (strcmp(ldap_server, "stand-alone") == 0) {
811 status = idmap_rfc2307_init_ldap(ctx, domain, cfg_opt);
812
813 } else if (strcmp(ldap_server, "ad") == 0) {
814 status = idmap_rfc2307_init_ads(ctx, cfg_opt);
815
816 } else {
817 status = NT_STATUS_INVALID_PARAMETER;
818 }
819
820 if (!NT_STATUS_IS_OK(status)) {
821 goto err;
822 }
823
824 realm = lp_parm_const_string(-1, cfg_opt, "realm", NULL);
825 if (realm) {
826 ctx->realm = talloc_strdup(ctx, realm);
827 if (ctx->realm == NULL) {
828 status = NT_STATUS_NO_MEMORY;
829 goto err;
830 }
831 }
832
833 ctx->user_cn = lp_parm_bool(-1, cfg_opt, "user_cn", false);
834
835 domain->private_data = ctx;
836 talloc_free(cfg_opt);
837 return NT_STATUS_OK;
838
839err:
840 talloc_free(cfg_opt);
841 talloc_free(ctx);
842 return status;
843}
844
845static struct idmap_methods rfc2307_methods = {
846 .init = idmap_rfc2307_initialize,
847 .unixids_to_sids = idmap_rfc2307_unixids_to_sids,
848 .sids_to_unixids = idmap_rfc2307_sids_to_unixids,
849};
850
851static_decl_idmap;
852NTSTATUS idmap_rfc2307_init(void)
853{
854 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "rfc2307",
855 &rfc2307_methods);
856}
Note: See TracBrowser for help on using the repository browser.