source: trunk-3.0/source/nsswitch/idmap_ldap.c@ 101

Last change on this file since 101 was 71, checked in by Paul Smedley, 18 years ago

Update source to 3.0.26a

File size: 37.2 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 idmap LDAP backend
5
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) Gerald Carter 2003
9 Copyright (C) Simo Sorce 2003-2007
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24*/
25
26#include "includes.h"
27
28#undef DBGC_CLASS
29#define DBGC_CLASS DBGC_IDMAP
30
31#include <lber.h>
32#include <ldap.h>
33
34#include "smbldap.h"
35
36struct idmap_ldap_context {
37 struct smbldap_state *smbldap_state;
38 char *url;
39 char *suffix;
40 char *user_dn;
41 uint32_t filter_low_id, filter_high_id; /* Filter range */
42 BOOL anon;
43};
44
45struct idmap_ldap_alloc_context {
46 struct smbldap_state *smbldap_state;
47 char *url;
48 char *suffix;
49 char *user_dn;
50 uid_t low_uid, high_uid; /* Range of uids */
51 gid_t low_gid, high_gid; /* Range of gids */
52
53};
54
55#define CHECK_ALLOC_DONE(mem) do { \
56 if (!mem) { \
57 DEBUG(0, ("Out of memory!\n")); \
58 ret = NT_STATUS_NO_MEMORY; \
59 goto done; \
60 } } while (0)
61
62/**********************************************************************
63 IDMAP ALLOC TDB BACKEND
64**********************************************************************/
65
66static struct idmap_ldap_alloc_context *idmap_alloc_ldap;
67
68/*********************************************************************
69 ********************************************************************/
70
71static NTSTATUS get_credentials( TALLOC_CTX *mem_ctx,
72 struct smbldap_state *ldap_state,
73 const char *config_option,
74 struct idmap_domain *dom,
75 char **dn )
76{
77 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
78 char *secret = NULL;
79 const char *tmp = NULL;
80 char *user_dn = NULL;
81 BOOL anon = False;
82
83 /* assume anonymous if we don't have a specified user */
84
85 tmp = lp_parm_const_string(-1, config_option, "ldap_user_dn", NULL);
86
87 if ( tmp ) {
88 if (!dom) {
89 /* only the alloc backend can pass in a NULL dom */
90 secret = idmap_fetch_secret("ldap", True,
91 NULL, tmp);
92 } else {
93 secret = idmap_fetch_secret("ldap", False,
94 dom->name, tmp);
95 }
96
97 if (!secret) {
98 DEBUG(0, ("get_credentials: Unable to fetch "
99 "auth credentials for %s in %s\n",
100 tmp, (dom==NULL)?"ALLOC":dom->name));
101 ret = NT_STATUS_ACCESS_DENIED;
102 goto done;
103 }
104 *dn = talloc_strdup(mem_ctx, tmp);
105 CHECK_ALLOC_DONE(*dn);
106 } else {
107 if (!fetch_ldap_pw(&user_dn, &secret)) {
108 DEBUG(2, ("get_credentials: Failed to lookup ldap "
109 "bind creds. Using anonymous connection.\n"));
110 anon = True;
111 } else {
112 *dn = talloc_strdup(mem_ctx, user_dn);
113 SAFE_FREE( user_dn );
114 CHECK_ALLOC_DONE(*dn);
115 }
116 }
117
118 smbldap_set_creds(ldap_state, anon, *dn, secret);
119 ret = NT_STATUS_OK;
120
121done:
122 SAFE_FREE(secret);
123
124 return ret;
125}
126
127
128/**********************************************************************
129 Verify the sambaUnixIdPool entry in the directory.
130**********************************************************************/
131
132static NTSTATUS verify_idpool(void)
133{
134 NTSTATUS ret;
135 TALLOC_CTX *ctx;
136 LDAPMessage *result = NULL;
137 LDAPMod **mods = NULL;
138 const char **attr_list;
139 char *filter;
140 int count;
141 int rc;
142
143 if ( ! idmap_alloc_ldap) {
144 return NT_STATUS_UNSUCCESSFUL;
145 }
146
147 ctx = talloc_new(idmap_alloc_ldap);
148 if ( ! ctx) {
149 DEBUG(0, ("Out of memory!\n"));
150 return NT_STATUS_NO_MEMORY;
151 }
152
153 filter = talloc_asprintf(ctx, "(objectclass=%s)", LDAP_OBJ_IDPOOL);
154 CHECK_ALLOC_DONE(filter);
155
156 attr_list = get_attr_list(ctx, idpool_attr_list);
157 CHECK_ALLOC_DONE(attr_list);
158
159 rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
160 idmap_alloc_ldap->suffix,
161 LDAP_SCOPE_SUBTREE,
162 filter,
163 attr_list,
164 0,
165 &result);
166
167 if (rc != LDAP_SUCCESS) {
168 DEBUG(1, ("Unable to verify the idpool, "
169 "cannot continue initialization!\n"));
170 return NT_STATUS_UNSUCCESSFUL;
171 }
172
173 count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
174 result);
175
176 ldap_msgfree(result);
177
178 if ( count > 1 ) {
179 DEBUG(0,("Multiple entries returned from %s (base == %s)\n",
180 filter, idmap_alloc_ldap->suffix));
181 ret = NT_STATUS_UNSUCCESSFUL;
182 goto done;
183 }
184 else if (count == 0) {
185 char *uid_str, *gid_str;
186
187 uid_str = talloc_asprintf(ctx, "%lu",
188 (unsigned long)idmap_alloc_ldap->low_uid);
189 gid_str = talloc_asprintf(ctx, "%lu",
190 (unsigned long)idmap_alloc_ldap->low_gid);
191
192 smbldap_set_mod(&mods, LDAP_MOD_ADD,
193 "objectClass", LDAP_OBJ_IDPOOL);
194 smbldap_set_mod(&mods, LDAP_MOD_ADD,
195 get_attr_key2string(idpool_attr_list,
196 LDAP_ATTR_UIDNUMBER),
197 uid_str);
198 smbldap_set_mod(&mods, LDAP_MOD_ADD,
199 get_attr_key2string(idpool_attr_list,
200 LDAP_ATTR_GIDNUMBER),
201 gid_str);
202 if (mods) {
203 rc = smbldap_modify(idmap_alloc_ldap->smbldap_state,
204 idmap_alloc_ldap->suffix,
205 mods);
206 ldap_mods_free(mods, True);
207 } else {
208 ret = NT_STATUS_UNSUCCESSFUL;
209 goto done;
210 }
211 }
212
213 ret = (rc == LDAP_SUCCESS)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
214done:
215 talloc_free(ctx);
216 return ret;
217}
218
219/*****************************************************************************
220 Initialise idmap database.
221*****************************************************************************/
222
223static NTSTATUS idmap_ldap_alloc_init(const char *params)
224{
225 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
226 const char *range;
227 const char *tmp;
228 uid_t low_uid = 0;
229 uid_t high_uid = 0;
230 gid_t low_gid = 0;
231 gid_t high_gid = 0;
232
233 /* Only do init if we are online */
234 if (idmap_is_offline()) {
235 return NT_STATUS_FILE_IS_OFFLINE;
236 }
237
238 idmap_alloc_ldap = TALLOC_ZERO_P(NULL, struct idmap_ldap_alloc_context);
239 CHECK_ALLOC_DONE( idmap_alloc_ldap );
240
241 /* load ranges */
242
243 idmap_alloc_ldap->low_uid = 0;
244 idmap_alloc_ldap->high_uid = 0;
245 idmap_alloc_ldap->low_gid = 0;
246 idmap_alloc_ldap->high_gid = 0;
247
248 range = lp_parm_const_string(-1, "idmap alloc config", "range", NULL);
249 if (range && range[0]) {
250 unsigned low_id, high_id;
251
252 if (sscanf(range, "%u - %u", &low_id, &high_id) == 2) {
253 if (low_id < high_id) {
254 idmap_alloc_ldap->low_gid = low_id;
255 idmap_alloc_ldap->low_uid = low_id;
256 idmap_alloc_ldap->high_gid = high_id;
257 idmap_alloc_ldap->high_uid = high_id;
258 } else {
259 DEBUG(1, ("ERROR: invalid idmap alloc range "
260 "[%s]", range));
261 }
262 } else {
263 DEBUG(1, ("ERROR: invalid syntax for idmap alloc "
264 "config:range [%s]", range));
265 }
266 }
267
268 if (lp_idmap_uid(&low_uid, &high_uid)) {
269 idmap_alloc_ldap->low_uid = low_uid;
270 idmap_alloc_ldap->high_uid = high_uid;
271 }
272
273 if (lp_idmap_gid(&low_gid, &high_gid)) {
274 idmap_alloc_ldap->low_gid = low_gid;
275 idmap_alloc_ldap->high_gid= high_gid;
276 }
277
278 if (idmap_alloc_ldap->high_uid <= idmap_alloc_ldap->low_uid) {
279 DEBUG(1, ("idmap uid range missing or invalid\n"));
280 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
281 ret = NT_STATUS_UNSUCCESSFUL;
282 goto done;
283 }
284
285 if (idmap_alloc_ldap->high_gid <= idmap_alloc_ldap->low_gid) {
286 DEBUG(1, ("idmap gid range missing or invalid\n"));
287 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
288 ret = NT_STATUS_UNSUCCESSFUL;
289 goto done;
290 }
291
292 if (params && *params) {
293 /* assume location is the only parameter */
294 idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, params);
295 } else {
296 tmp = lp_parm_const_string(-1, "idmap alloc config",
297 "ldap_url", NULL);
298
299 if ( ! tmp) {
300 DEBUG(1, ("ERROR: missing idmap ldap url\n"));
301 ret = NT_STATUS_UNSUCCESSFUL;
302 goto done;
303 }
304
305 idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, tmp);
306 }
307 CHECK_ALLOC_DONE( idmap_alloc_ldap->url );
308
309 tmp = lp_parm_const_string(-1, "idmap alloc config",
310 "ldap_base_dn", NULL);
311 if ( ! tmp || ! *tmp) {
312 tmp = lp_ldap_idmap_suffix();
313 if ( ! tmp) {
314 DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
315 ret = NT_STATUS_UNSUCCESSFUL;
316 goto done;
317 }
318 }
319
320 idmap_alloc_ldap->suffix = talloc_strdup(idmap_alloc_ldap, tmp);
321 CHECK_ALLOC_DONE( idmap_alloc_ldap->suffix );
322
323 ret = smbldap_init(idmap_alloc_ldap, idmap_alloc_ldap->url,
324 &idmap_alloc_ldap->smbldap_state);
325 if (!NT_STATUS_IS_OK(ret)) {
326 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n",
327 idmap_alloc_ldap->url));
328 goto done;
329 }
330
331 ret = get_credentials( idmap_alloc_ldap,
332 idmap_alloc_ldap->smbldap_state,
333 "idmap alloc config", NULL,
334 &idmap_alloc_ldap->user_dn );
335 if ( !NT_STATUS_IS_OK(ret) ) {
336 DEBUG(1,("idmap_ldap_alloc_init: Failed to get connection "
337 "credentials (%s)\n", nt_errstr(ret)));
338 goto done;
339 }
340
341 /* see if the idmap suffix and sub entries exists */
342
343 ret = verify_idpool();
344
345 done:
346 if ( !NT_STATUS_IS_OK( ret ) )
347 TALLOC_FREE( idmap_alloc_ldap );
348
349 return ret;
350}
351
352/********************************
353 Allocate a new uid or gid
354********************************/
355
356static NTSTATUS idmap_ldap_allocate_id(struct unixid *xid)
357{
358 TALLOC_CTX *ctx;
359 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
360 int rc = LDAP_SERVER_DOWN;
361 int count = 0;
362 LDAPMessage *result = NULL;
363 LDAPMessage *entry = NULL;
364 LDAPMod **mods = NULL;
365 char *id_str;
366 char *new_id_str;
367 char *filter = NULL;
368 const char *dn = NULL;
369 const char **attr_list;
370 const char *type;
371
372 /* Only do query if we are online */
373 if (idmap_is_offline()) {
374 return NT_STATUS_FILE_IS_OFFLINE;
375 }
376
377 if ( ! idmap_alloc_ldap) {
378 return NT_STATUS_UNSUCCESSFUL;
379 }
380
381 ctx = talloc_new(idmap_alloc_ldap);
382 if ( ! ctx) {
383 DEBUG(0, ("Out of memory!\n"));
384 return NT_STATUS_NO_MEMORY;
385 }
386
387 /* get type */
388 switch (xid->type) {
389
390 case ID_TYPE_UID:
391 type = get_attr_key2string(idpool_attr_list,
392 LDAP_ATTR_UIDNUMBER);
393 break;
394
395 case ID_TYPE_GID:
396 type = get_attr_key2string(idpool_attr_list,
397 LDAP_ATTR_GIDNUMBER);
398 break;
399
400 default:
401 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
402 return NT_STATUS_INVALID_PARAMETER;
403 }
404
405 filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
406 CHECK_ALLOC_DONE(filter);
407
408 attr_list = get_attr_list(ctx, idpool_attr_list);
409 CHECK_ALLOC_DONE(attr_list);
410
411 DEBUG(10, ("Search of the id pool (filter: %s)\n", filter));
412
413 rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
414 idmap_alloc_ldap->suffix,
415 LDAP_SCOPE_SUBTREE, filter,
416 attr_list, 0, &result);
417
418 if (rc != LDAP_SUCCESS) {
419 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
420 goto done;
421 }
422
423 talloc_autofree_ldapmsg(ctx, result);
424
425 count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
426 result);
427 if (count != 1) {
428 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
429 goto done;
430 }
431
432 entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
433 result);
434
435 dn = smbldap_talloc_dn(ctx,
436 idmap_alloc_ldap->smbldap_state->ldap_struct,
437 entry);
438 if ( ! dn) {
439 goto done;
440 }
441
442 if ( ! (id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
443 entry, type, ctx))) {
444 DEBUG(0,("%s attribute not found\n", type));
445 goto done;
446 }
447 if ( ! id_str) {
448 DEBUG(0,("Out of memory\n"));
449 ret = NT_STATUS_NO_MEMORY;
450 goto done;
451 }
452
453 xid->id = strtoul(id_str, NULL, 10);
454
455 /* make sure we still have room to grow */
456
457 switch (xid->type) {
458 case ID_TYPE_UID:
459 if (xid->id > idmap_alloc_ldap->high_uid) {
460 DEBUG(0,("Cannot allocate uid above %lu!\n",
461 (unsigned long)idmap_alloc_ldap->high_uid));
462 goto done;
463 }
464 break;
465
466 case ID_TYPE_GID:
467 if (xid->id > idmap_alloc_ldap->high_gid) {
468 DEBUG(0,("Cannot allocate gid above %lu!\n",
469 (unsigned long)idmap_alloc_ldap->high_uid));
470 goto done;
471 }
472 break;
473
474 default:
475 /* impossible */
476 goto done;
477 }
478
479 new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id + 1);
480 if ( ! new_id_str) {
481 DEBUG(0,("Out of memory\n"));
482 ret = NT_STATUS_NO_MEMORY;
483 goto done;
484 }
485
486 smbldap_set_mod(&mods, LDAP_MOD_DELETE, type, id_str);
487 smbldap_set_mod(&mods, LDAP_MOD_ADD, type, new_id_str);
488
489 if (mods == NULL) {
490 DEBUG(0,("smbldap_set_mod() failed.\n"));
491 goto done;
492 }
493
494 DEBUG(10, ("Try to atomically increment the id (%s -> %s)\n",
495 id_str, new_id_str));
496
497 rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
498
499 ldap_mods_free(mods, True);
500
501 if (rc != LDAP_SUCCESS) {
502 DEBUG(1,("Failed to allocate new %s. "
503 "smbldap_modify() failed.\n", type));
504 goto done;
505 }
506
507 ret = NT_STATUS_OK;
508
509done:
510 talloc_free(ctx);
511 return ret;
512}
513
514/**********************************
515 Get current highest id.
516**********************************/
517
518static NTSTATUS idmap_ldap_get_hwm(struct unixid *xid)
519{
520 TALLOC_CTX *memctx;
521 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
522 int rc = LDAP_SERVER_DOWN;
523 int count = 0;
524 LDAPMessage *result = NULL;
525 LDAPMessage *entry = NULL;
526 char *id_str;
527 char *filter = NULL;
528 const char **attr_list;
529 const char *type;
530
531 /* Only do query if we are online */
532 if (idmap_is_offline()) {
533 return NT_STATUS_FILE_IS_OFFLINE;
534 }
535
536 if ( ! idmap_alloc_ldap) {
537 return NT_STATUS_UNSUCCESSFUL;
538 }
539
540 memctx = talloc_new(idmap_alloc_ldap);
541 if ( ! memctx) {
542 DEBUG(0, ("Out of memory!\n"));
543 return NT_STATUS_NO_MEMORY;
544 }
545
546 /* get type */
547 switch (xid->type) {
548
549 case ID_TYPE_UID:
550 type = get_attr_key2string(idpool_attr_list,
551 LDAP_ATTR_UIDNUMBER);
552 break;
553
554 case ID_TYPE_GID:
555 type = get_attr_key2string(idpool_attr_list,
556 LDAP_ATTR_GIDNUMBER);
557 break;
558
559 default:
560 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
561 return NT_STATUS_INVALID_PARAMETER;
562 }
563
564 filter = talloc_asprintf(memctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
565 CHECK_ALLOC_DONE(filter);
566
567 attr_list = get_attr_list(memctx, idpool_attr_list);
568 CHECK_ALLOC_DONE(attr_list);
569
570 rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
571 idmap_alloc_ldap->suffix,
572 LDAP_SCOPE_SUBTREE, filter,
573 attr_list, 0, &result);
574
575 if (rc != LDAP_SUCCESS) {
576 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
577 goto done;
578 }
579
580 talloc_autofree_ldapmsg(memctx, result);
581
582 count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
583 result);
584 if (count != 1) {
585 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
586 goto done;
587 }
588
589 entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
590 result);
591
592 id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
593 entry, type, memctx);
594 if ( ! id_str) {
595 DEBUG(0,("%s attribute not found\n", type));
596 goto done;
597 }
598 if ( ! id_str) {
599 DEBUG(0,("Out of memory\n"));
600 ret = NT_STATUS_NO_MEMORY;
601 goto done;
602 }
603
604 xid->id = strtoul(id_str, NULL, 10);
605
606 ret = NT_STATUS_OK;
607done:
608 talloc_free(memctx);
609 return ret;
610}
611/**********************************
612 Set highest id.
613**********************************/
614
615static NTSTATUS idmap_ldap_set_hwm(struct unixid *xid)
616{
617 TALLOC_CTX *ctx;
618 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
619 int rc = LDAP_SERVER_DOWN;
620 int count = 0;
621 LDAPMessage *result = NULL;
622 LDAPMessage *entry = NULL;
623 LDAPMod **mods = NULL;
624 char *new_id_str;
625 char *filter = NULL;
626 const char *dn = NULL;
627 const char **attr_list;
628 const char *type;
629
630 /* Only do query if we are online */
631 if (idmap_is_offline()) {
632 return NT_STATUS_FILE_IS_OFFLINE;
633 }
634
635 if ( ! idmap_alloc_ldap) {
636 return NT_STATUS_UNSUCCESSFUL;
637 }
638
639 ctx = talloc_new(idmap_alloc_ldap);
640 if ( ! ctx) {
641 DEBUG(0, ("Out of memory!\n"));
642 return NT_STATUS_NO_MEMORY;
643 }
644
645 /* get type */
646 switch (xid->type) {
647
648 case ID_TYPE_UID:
649 type = get_attr_key2string(idpool_attr_list,
650 LDAP_ATTR_UIDNUMBER);
651 break;
652
653 case ID_TYPE_GID:
654 type = get_attr_key2string(idpool_attr_list,
655 LDAP_ATTR_GIDNUMBER);
656 break;
657
658 default:
659 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
660 return NT_STATUS_INVALID_PARAMETER;
661 }
662
663 filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
664 CHECK_ALLOC_DONE(filter);
665
666 attr_list = get_attr_list(ctx, idpool_attr_list);
667 CHECK_ALLOC_DONE(attr_list);
668
669 rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
670 idmap_alloc_ldap->suffix,
671 LDAP_SCOPE_SUBTREE, filter,
672 attr_list, 0, &result);
673
674 if (rc != LDAP_SUCCESS) {
675 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
676 goto done;
677 }
678
679 talloc_autofree_ldapmsg(ctx, result);
680
681 count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
682 result);
683 if (count != 1) {
684 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
685 goto done;
686 }
687
688 entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
689 result);
690
691 dn = smbldap_talloc_dn(ctx,
692 idmap_alloc_ldap->smbldap_state->ldap_struct,
693 entry);
694 if ( ! dn) {
695 goto done;
696 }
697
698 new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id);
699 if ( ! new_id_str) {
700 DEBUG(0,("Out of memory\n"));
701 ret = NT_STATUS_NO_MEMORY;
702 goto done;
703 }
704
705 smbldap_set_mod(&mods, LDAP_MOD_REPLACE, type, new_id_str);
706
707 if (mods == NULL) {
708 DEBUG(0,("smbldap_set_mod() failed.\n"));
709 goto done;
710 }
711
712 rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
713
714 ldap_mods_free(mods, True);
715
716 if (rc != LDAP_SUCCESS) {
717 DEBUG(1,("Failed to allocate new %s. "
718 "smbldap_modify() failed.\n", type));
719 goto done;
720 }
721
722 ret = NT_STATUS_OK;
723
724done:
725 talloc_free(ctx);
726 return ret;
727}
728
729/**********************************
730 Close idmap ldap alloc
731**********************************/
732
733static NTSTATUS idmap_ldap_alloc_close(void)
734{
735 if (idmap_alloc_ldap) {
736 smbldap_free_struct(&idmap_alloc_ldap->smbldap_state);
737 DEBUG(5,("The connection to the LDAP server was closed\n"));
738 /* maybe free the results here --metze */
739 TALLOC_FREE(idmap_alloc_ldap);
740 }
741 return NT_STATUS_OK;
742}
743
744
745/**********************************************************************
746 IDMAP MAPPING LDAP BACKEND
747**********************************************************************/
748
749static int idmap_ldap_close_destructor(struct idmap_ldap_context *ctx)
750{
751 smbldap_free_struct(&ctx->smbldap_state);
752 DEBUG(5,("The connection to the LDAP server was closed\n"));
753 /* maybe free the results here --metze */
754
755 return 0;
756}
757
758/********************************
759 Initialise idmap database.
760********************************/
761
762static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
763{
764 NTSTATUS ret;
765 struct idmap_ldap_context *ctx = NULL;
766 char *config_option = NULL;
767 const char *range = NULL;
768 const char *tmp = NULL;
769
770 /* Only do init if we are online */
771 if (idmap_is_offline()) {
772 return NT_STATUS_FILE_IS_OFFLINE;
773 }
774
775 ctx = TALLOC_ZERO_P(dom, struct idmap_ldap_context);
776 if ( ! ctx) {
777 DEBUG(0, ("Out of memory!\n"));
778 return NT_STATUS_NO_MEMORY;
779 }
780
781 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
782 if ( ! config_option) {
783 DEBUG(0, ("Out of memory!\n"));
784 ret = NT_STATUS_NO_MEMORY;
785 goto done;
786 }
787
788 /* load ranges */
789 range = lp_parm_const_string(-1, config_option, "range", NULL);
790 if (range && range[0]) {
791 if ((sscanf(range, "%u - %u", &ctx->filter_low_id,
792 &ctx->filter_high_id) != 2) ||
793 (ctx->filter_low_id > ctx->filter_high_id)) {
794 DEBUG(1, ("ERROR: invalid filter range [%s]", range));
795 ctx->filter_low_id = 0;
796 ctx->filter_high_id = 0;
797 }
798 }
799
800 if (dom->params && *(dom->params)) {
801 /* assume location is the only parameter */
802 ctx->url = talloc_strdup(ctx, dom->params);
803 } else {
804 tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
805
806 if ( ! tmp) {
807 DEBUG(1, ("ERROR: missing idmap ldap url\n"));
808 ret = NT_STATUS_UNSUCCESSFUL;
809 goto done;
810 }
811
812 ctx->url = talloc_strdup(ctx, tmp);
813 }
814 CHECK_ALLOC_DONE(ctx->url);
815
816 tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL);
817 if ( ! tmp || ! *tmp) {
818 tmp = lp_ldap_idmap_suffix();
819 if ( ! tmp) {
820 DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
821 ret = NT_STATUS_UNSUCCESSFUL;
822 goto done;
823 }
824 }
825
826 ctx->suffix = talloc_strdup(ctx, tmp);
827 CHECK_ALLOC_DONE(ctx->suffix);
828
829 ret = smbldap_init(ctx, ctx->url, &ctx->smbldap_state);
830 if (!NT_STATUS_IS_OK(ret)) {
831 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", ctx->url));
832 goto done;
833 }
834
835 ret = get_credentials( ctx, ctx->smbldap_state, config_option,
836 dom, &ctx->user_dn );
837 if ( !NT_STATUS_IS_OK(ret) ) {
838 DEBUG(1,("idmap_ldap_db_init: Failed to get connection "
839 "credentials (%s)\n", nt_errstr(ret)));
840 goto done;
841 }
842
843 /* set the destructor on the context, so that resource are properly
844 freed if the contexts is released */
845
846 talloc_set_destructor(ctx, idmap_ldap_close_destructor);
847
848 dom->private_data = ctx;
849 dom->initialized = True;
850
851 talloc_free(config_option);
852 return NT_STATUS_OK;
853
854/*failed */
855done:
856 talloc_free(ctx);
857 return ret;
858}
859
860/* max number of ids requested per batch query */
861#define IDMAP_LDAP_MAX_IDS 30
862
863/**********************************
864 lookup a set of unix ids.
865**********************************/
866
867/* this function searches up to IDMAP_LDAP_MAX_IDS entries
868 * in maps for a match */
869static struct id_map *find_map_by_id(struct id_map **maps,
870 enum id_type type,
871 uint32_t id)
872{
873 int i;
874
875 for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {
876 if (maps[i] == NULL) { /* end of the run */
877 return NULL;
878 }
879 if ((maps[i]->xid.type == type) && (maps[i]->xid.id == id)) {
880 return maps[i];
881 }
882 }
883
884 return NULL;
885}
886
887static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom,
888 struct id_map **ids)
889{
890 NTSTATUS ret;
891 TALLOC_CTX *memctx;
892 struct idmap_ldap_context *ctx;
893 LDAPMessage *result = NULL;
894 const char *uidNumber;
895 const char *gidNumber;
896 const char **attr_list;
897 char *filter = NULL;
898 BOOL multi = False;
899 int idx = 0;
900 int bidx = 0;
901 int count;
902 int rc;
903 int i;
904
905 /* Only do query if we are online */
906 if (idmap_is_offline()) {
907 return NT_STATUS_FILE_IS_OFFLINE;
908 }
909
910 /* Initilization my have been deferred because we were offline */
911 if ( ! dom->initialized) {
912 ret = idmap_ldap_db_init(dom);
913 if ( ! NT_STATUS_IS_OK(ret)) {
914 return ret;
915 }
916 }
917
918 ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
919
920 memctx = talloc_new(ctx);
921 if ( ! memctx) {
922 DEBUG(0, ("Out of memory!\n"));
923 return NT_STATUS_NO_MEMORY;
924 }
925
926 uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER);
927 gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER);
928
929 attr_list = get_attr_list(memctx, sidmap_attr_list);
930
931 if ( ! ids[1]) {
932 /* if we are requested just one mapping use the simple filter */
933
934 filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%lu))",
935 LDAP_OBJ_IDMAP_ENTRY,
936 (ids[0]->xid.type==ID_TYPE_UID)?uidNumber:gidNumber,
937 (unsigned long)ids[0]->xid.id);
938 CHECK_ALLOC_DONE(filter);
939 DEBUG(10, ("Filter: [%s]\n", filter));
940 } else {
941 /* multiple mappings */
942 multi = True;
943 }
944
945again:
946 if (multi) {
947
948 talloc_free(filter);
949 filter = talloc_asprintf(memctx,
950 "(&(objectClass=%s)(|",
951 LDAP_OBJ_IDMAP_ENTRY);
952 CHECK_ALLOC_DONE(filter);
953
954 bidx = idx;
955 for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
956 filter = talloc_asprintf_append(filter, "(%s=%lu)",
957 (ids[idx]->xid.type==ID_TYPE_UID)?uidNumber:gidNumber,
958 (unsigned long)ids[idx]->xid.id);
959 CHECK_ALLOC_DONE(filter);
960 }
961 filter = talloc_asprintf_append(filter, "))");
962 CHECK_ALLOC_DONE(filter);
963 DEBUG(10, ("Filter: [%s]\n", filter));
964 } else {
965 bidx = 0;
966 idx = 1;
967 }
968
969 rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE,
970 filter, attr_list, 0, &result);
971
972 if (rc != LDAP_SUCCESS) {
973 DEBUG(3,("Failure looking up ids (%s)\n", ldap_err2string(rc)));
974 ret = NT_STATUS_UNSUCCESSFUL;
975 goto done;
976 }
977
978 count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
979
980 if (count == 0) {
981 DEBUG(10, ("NO SIDs found\n"));
982 }
983
984 for (i = 0; i < count; i++) {
985 LDAPMessage *entry = NULL;
986 char *sidstr = NULL;
987 char *tmp = NULL;
988 enum id_type type;
989 struct id_map *map;
990 uint32_t id;
991
992 if (i == 0) { /* first entry */
993 entry = ldap_first_entry(ctx->smbldap_state->ldap_struct,
994 result);
995 } else { /* following ones */
996 entry = ldap_next_entry(ctx->smbldap_state->ldap_struct,
997 entry);
998 }
999 if ( ! entry) {
1000 DEBUG(2, ("ERROR: Unable to fetch ldap entries "
1001 "from results\n"));
1002 break;
1003 }
1004
1005 /* first check if the SID is present */
1006 sidstr = smbldap_talloc_single_attribute(
1007 ctx->smbldap_state->ldap_struct,
1008 entry, LDAP_ATTRIBUTE_SID, memctx);
1009 if ( ! sidstr) { /* no sid, skip entry */
1010 DEBUG(2, ("WARNING SID not found on entry\n"));
1011 continue;
1012 }
1013
1014 /* now try to see if it is a uid, if not try with a gid
1015 * (gid is more common, but in case both uidNumber and
1016 * gidNumber are returned the SID is mapped to the uid
1017 *not the gid) */
1018 type = ID_TYPE_UID;
1019 tmp = smbldap_talloc_single_attribute(
1020 ctx->smbldap_state->ldap_struct,
1021 entry, uidNumber, memctx);
1022 if ( ! tmp) {
1023 type = ID_TYPE_GID;
1024 tmp = smbldap_talloc_single_attribute(
1025 ctx->smbldap_state->ldap_struct,
1026 entry, gidNumber, memctx);
1027 }
1028 if ( ! tmp) { /* wow very strange entry, how did it match ? */
1029 DEBUG(5, ("Unprobable match on (%s), no uidNumber, "
1030 "nor gidNumber returned\n", sidstr));
1031 TALLOC_FREE(sidstr);
1032 continue;
1033 }
1034
1035 id = strtoul(tmp, NULL, 10);
1036 if ((id == 0) ||
1037 (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
1038 (ctx->filter_high_id && (id > ctx->filter_high_id))) {
1039 DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
1040 "Filtered!\n", id,
1041 ctx->filter_low_id, ctx->filter_high_id));
1042 TALLOC_FREE(sidstr);
1043 TALLOC_FREE(tmp);
1044 continue;
1045 }
1046 TALLOC_FREE(tmp);
1047
1048 map = find_map_by_id(&ids[bidx], type, id);
1049 if (!map) {
1050 DEBUG(2, ("WARNING: couldn't match sid (%s) "
1051 "with requested ids\n", sidstr));
1052 TALLOC_FREE(sidstr);
1053 continue;
1054 }
1055
1056 if ( ! string_to_sid(map->sid, sidstr)) {
1057 DEBUG(2, ("ERROR: Invalid SID on entry\n"));
1058 TALLOC_FREE(sidstr);
1059 continue;
1060 }
1061 TALLOC_FREE(sidstr);
1062
1063 /* mapped */
1064 map->status = ID_MAPPED;
1065
1066 DEBUG(10, ("Mapped %s -> %lu (%d)\n",
1067 sid_string_static(map->sid),
1068 (unsigned long)map->xid.id, map->xid.type));
1069 }
1070
1071 /* free the ldap results */
1072 if (result) {
1073 ldap_msgfree(result);
1074 result = NULL;
1075 }
1076
1077 if (multi && ids[idx]) { /* still some values to map */
1078 goto again;
1079 }
1080
1081 ret = NT_STATUS_OK;
1082
1083 /* mark all unknwon/expired ones as unmapped */
1084 for (i = 0; ids[i]; i++) {
1085 if (ids[i]->status != ID_MAPPED)
1086 ids[i]->status = ID_UNMAPPED;
1087 }
1088
1089done:
1090 talloc_free(memctx);
1091 return ret;
1092}
1093
1094/**********************************
1095 lookup a set of sids.
1096**********************************/
1097
1098/* this function searches up to IDMAP_LDAP_MAX_IDS entries
1099 * in maps for a match */
1100static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID *sid)
1101{
1102 int i;
1103
1104 for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {
1105 if (maps[i] == NULL) { /* end of the run */
1106 return NULL;
1107 }
1108 if (sid_equal(maps[i]->sid, sid)) {
1109 return maps[i];
1110 }
1111 }
1112
1113 return NULL;
1114}
1115
1116static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom,
1117 struct id_map **ids)
1118{
1119 LDAPMessage *entry = NULL;
1120 NTSTATUS ret;
1121 TALLOC_CTX *memctx;
1122 struct idmap_ldap_context *ctx;
1123 LDAPMessage *result = NULL;
1124 const char *uidNumber;
1125 const char *gidNumber;
1126 const char **attr_list;
1127 char *filter = NULL;
1128 BOOL multi = False;
1129 int idx = 0;
1130 int bidx = 0;
1131 int count;
1132 int rc;
1133 int i;
1134
1135 /* Only do query if we are online */
1136 if (idmap_is_offline()) {
1137 return NT_STATUS_FILE_IS_OFFLINE;
1138 }
1139
1140 /* Initilization my have been deferred because we were offline */
1141 if ( ! dom->initialized) {
1142 ret = idmap_ldap_db_init(dom);
1143 if ( ! NT_STATUS_IS_OK(ret)) {
1144 return ret;
1145 }
1146 }
1147
1148 ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
1149
1150 memctx = talloc_new(ctx);
1151 if ( ! memctx) {
1152 DEBUG(0, ("Out of memory!\n"));
1153 return NT_STATUS_NO_MEMORY;
1154 }
1155
1156 uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER);
1157 gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER);
1158
1159 attr_list = get_attr_list(memctx, sidmap_attr_list);
1160
1161 if ( ! ids[1]) {
1162 /* if we are requested just one mapping use the simple filter */
1163
1164 filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%s))",
1165 LDAP_OBJ_IDMAP_ENTRY,
1166 LDAP_ATTRIBUTE_SID,
1167 sid_string_static(ids[0]->sid));
1168 CHECK_ALLOC_DONE(filter);
1169 DEBUG(10, ("Filter: [%s]\n", filter));
1170 } else {
1171 /* multiple mappings */
1172 multi = True;
1173 }
1174
1175again:
1176 if (multi) {
1177
1178 TALLOC_FREE(filter);
1179 filter = talloc_asprintf(memctx,
1180 "(&(objectClass=%s)(|",
1181 LDAP_OBJ_IDMAP_ENTRY);
1182 CHECK_ALLOC_DONE(filter);
1183
1184 bidx = idx;
1185 for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
1186 filter = talloc_asprintf_append(filter, "(%s=%s)",
1187 LDAP_ATTRIBUTE_SID,
1188 sid_string_static(ids[idx]->sid));
1189 CHECK_ALLOC_DONE(filter);
1190 }
1191 filter = talloc_asprintf_append(filter, "))");
1192 CHECK_ALLOC_DONE(filter);
1193 DEBUG(10, ("Filter: [%s]", filter));
1194 } else {
1195 bidx = 0;
1196 idx = 1;
1197 }
1198
1199 rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE,
1200 filter, attr_list, 0, &result);
1201
1202 if (rc != LDAP_SUCCESS) {
1203 DEBUG(3,("Failure looking up sids (%s)\n",
1204 ldap_err2string(rc)));
1205 ret = NT_STATUS_UNSUCCESSFUL;
1206 goto done;
1207 }
1208
1209 count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
1210
1211 if (count == 0) {
1212 DEBUG(10, ("NO SIDs found\n"));
1213 }
1214
1215 for (i = 0; i < count; i++) {
1216 char *sidstr = NULL;
1217 char *tmp = NULL;
1218 enum id_type type;
1219 struct id_map *map;
1220 DOM_SID sid;
1221 uint32_t id;
1222
1223 if (i == 0) { /* first entry */
1224 entry = ldap_first_entry(ctx->smbldap_state->ldap_struct,
1225 result);
1226 } else { /* following ones */
1227 entry = ldap_next_entry(ctx->smbldap_state->ldap_struct,
1228 entry);
1229 }
1230 if ( ! entry) {
1231 DEBUG(2, ("ERROR: Unable to fetch ldap entries "
1232 "from results\n"));
1233 break;
1234 }
1235
1236 /* first check if the SID is present */
1237 sidstr = smbldap_talloc_single_attribute(
1238 ctx->smbldap_state->ldap_struct,
1239 entry, LDAP_ATTRIBUTE_SID, memctx);
1240 if ( ! sidstr) { /* no sid ??, skip entry */
1241 DEBUG(2, ("WARNING SID not found on entry\n"));
1242 continue;
1243 }
1244
1245 if ( ! string_to_sid(&sid, sidstr)) {
1246 DEBUG(2, ("ERROR: Invalid SID on entry\n"));
1247 TALLOC_FREE(sidstr);
1248 continue;
1249 }
1250
1251 map = find_map_by_sid(&ids[bidx], &sid);
1252 if (!map) {
1253 DEBUG(2, ("WARNING: couldn't find entry sid (%s) "
1254 "in ids", sidstr));
1255 TALLOC_FREE(sidstr);
1256 continue;
1257 }
1258
1259 TALLOC_FREE(sidstr);
1260
1261 /* now try to see if it is a uid, if not try with a gid
1262 * (gid is more common, but in case both uidNumber and
1263 * gidNumber are returned the SID is mapped to the uid
1264 * not the gid) */
1265 type = ID_TYPE_UID;
1266 tmp = smbldap_talloc_single_attribute(
1267 ctx->smbldap_state->ldap_struct,
1268 entry, uidNumber, memctx);
1269 if ( ! tmp) {
1270 type = ID_TYPE_GID;
1271 tmp = smbldap_talloc_single_attribute(
1272 ctx->smbldap_state->ldap_struct,
1273 entry, gidNumber, memctx);
1274 }
1275 if ( ! tmp) { /* no ids ?? */
1276 DEBUG(5, ("no uidNumber, "
1277 "nor gidNumber attributes found\n"));
1278 continue;
1279 }
1280
1281 id = strtoul(tmp, NULL, 10);
1282 if ((id == 0) ||
1283 (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
1284 (ctx->filter_high_id && (id > ctx->filter_high_id))) {
1285 DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
1286 "Filtered!\n", id,
1287 ctx->filter_low_id, ctx->filter_high_id));
1288 TALLOC_FREE(tmp);
1289 continue;
1290 }
1291 TALLOC_FREE(tmp);
1292
1293 /* mapped */
1294 map->xid.type = type;
1295 map->xid.id = id;
1296 map->status = ID_MAPPED;
1297
1298 DEBUG(10, ("Mapped %s -> %lu (%d)\n",
1299 sid_string_static(map->sid),
1300 (unsigned long)map->xid.id, map->xid.type));
1301 }
1302
1303 /* free the ldap results */
1304 if (result) {
1305 ldap_msgfree(result);
1306 result = NULL;
1307 }
1308
1309 if (multi && ids[idx]) { /* still some values to map */
1310 goto again;
1311 }
1312
1313 ret = NT_STATUS_OK;
1314
1315 /* mark all unknwon/expired ones as unmapped */
1316 for (i = 0; ids[i]; i++) {
1317 if (ids[i]->status != ID_MAPPED)
1318 ids[i]->status = ID_UNMAPPED;
1319 }
1320
1321done:
1322 talloc_free(memctx);
1323 return ret;
1324}
1325
1326/**********************************
1327 set a mapping.
1328**********************************/
1329
1330/* TODO: change this: This function cannot be called to modify a mapping,
1331 * only set a new one */
1332
1333static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
1334 const struct id_map *map)
1335{
1336 NTSTATUS ret;
1337 TALLOC_CTX *memctx;
1338 struct idmap_ldap_context *ctx;
1339 LDAPMessage *entry = NULL;
1340 LDAPMod **mods = NULL;
1341 const char *type;
1342 char *id_str;
1343 char *sid;
1344 char *dn;
1345 int rc = -1;
1346
1347 /* Only do query if we are online */
1348 if (idmap_is_offline()) {
1349 return NT_STATUS_FILE_IS_OFFLINE;
1350 }
1351
1352 /* Initilization my have been deferred because we were offline */
1353 if ( ! dom->initialized) {
1354 ret = idmap_ldap_db_init(dom);
1355 if ( ! NT_STATUS_IS_OK(ret)) {
1356 return ret;
1357 }
1358 }
1359
1360 ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
1361
1362 switch(map->xid.type) {
1363 case ID_TYPE_UID:
1364 type = get_attr_key2string(sidmap_attr_list,
1365 LDAP_ATTR_UIDNUMBER);
1366 break;
1367
1368 case ID_TYPE_GID:
1369 type = get_attr_key2string(sidmap_attr_list,
1370 LDAP_ATTR_GIDNUMBER);
1371 break;
1372
1373 default:
1374 return NT_STATUS_INVALID_PARAMETER;
1375 }
1376
1377 memctx = talloc_new(ctx);
1378 if ( ! memctx) {
1379 DEBUG(0, ("Out of memory!\n"));
1380 return NT_STATUS_NO_MEMORY;
1381 }
1382
1383 id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id);
1384 CHECK_ALLOC_DONE(id_str);
1385
1386 sid = talloc_strdup(memctx, sid_string_static(map->sid));
1387 CHECK_ALLOC_DONE(sid);
1388
1389 dn = talloc_asprintf(memctx, "%s=%s,%s",
1390 get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
1391 sid,
1392 ctx->suffix);
1393 CHECK_ALLOC_DONE(dn);
1394
1395 smbldap_set_mod(&mods, LDAP_MOD_ADD,
1396 "objectClass", LDAP_OBJ_IDMAP_ENTRY);
1397
1398 smbldap_make_mod(ctx->smbldap_state->ldap_struct,
1399 entry, &mods, type, id_str);
1400
1401 smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods,
1402 get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
1403 sid);
1404
1405 if ( ! mods) {
1406 DEBUG(2, ("ERROR: No mods?\n"));
1407 ret = NT_STATUS_UNSUCCESSFUL;
1408 goto done;
1409 }
1410
1411 /* TODO: remove conflicting mappings! */
1412
1413 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY);
1414
1415 DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str));
1416
1417 rc = smbldap_add(ctx->smbldap_state, dn, mods);
1418 ldap_mods_free(mods, True);
1419
1420 if (rc != LDAP_SUCCESS) {
1421 char *ld_error = NULL;
1422 ldap_get_option(ctx->smbldap_state->ldap_struct,
1423 LDAP_OPT_ERROR_STRING, &ld_error);
1424 DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "
1425 "mapping [%s]\n", sid,
1426 (unsigned long)map->xid.id, type));
1427 DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
1428 ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
1429 if (ld_error) {
1430 ldap_memfree(ld_error);
1431 }
1432 ret = NT_STATUS_UNSUCCESSFUL;
1433 goto done;
1434 }
1435
1436 DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "
1437 "%lu [%s]\n", sid, (unsigned long)map->xid.id, type));
1438
1439 ret = NT_STATUS_OK;
1440
1441done:
1442 talloc_free(memctx);
1443 return ret;
1444}
1445
1446/**********************************
1447 Close the idmap ldap instance
1448**********************************/
1449
1450static NTSTATUS idmap_ldap_close(struct idmap_domain *dom)
1451{
1452 struct idmap_ldap_context *ctx;
1453
1454 if (dom->private_data) {
1455 ctx = talloc_get_type(dom->private_data,
1456 struct idmap_ldap_context);
1457
1458 talloc_free(ctx);
1459 dom->private_data = NULL;
1460 }
1461
1462 return NT_STATUS_OK;
1463}
1464
1465static struct idmap_methods idmap_ldap_methods = {
1466
1467 .init = idmap_ldap_db_init,
1468 .unixids_to_sids = idmap_ldap_unixids_to_sids,
1469 .sids_to_unixids = idmap_ldap_sids_to_unixids,
1470 .set_mapping = idmap_ldap_set_mapping,
1471 .close_fn = idmap_ldap_close
1472};
1473
1474static struct idmap_alloc_methods idmap_ldap_alloc_methods = {
1475
1476 .init = idmap_ldap_alloc_init,
1477 .allocate_id = idmap_ldap_allocate_id,
1478 .get_id_hwm = idmap_ldap_get_hwm,
1479 .set_id_hwm = idmap_ldap_set_hwm,
1480 .close_fn = idmap_ldap_alloc_close,
1481 /* .dump_data = TODO */
1482};
1483
1484NTSTATUS idmap_alloc_ldap_init(void)
1485{
1486 return smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "ldap",
1487 &idmap_ldap_alloc_methods);
1488}
1489
1490NTSTATUS idmap_ldap_init(void)
1491{
1492 NTSTATUS ret;
1493
1494 /* FIXME: bad hack to actually register also the alloc_ldap module
1495 * without changining configure.in */
1496 ret = idmap_alloc_ldap_init();
1497 if (! NT_STATUS_IS_OK(ret)) {
1498 return ret;
1499 }
1500 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap",
1501 &idmap_ldap_methods);
1502}
1503
Note: See TracBrowser for help on using the repository browser.