source: trunk/samba/source/nsswitch/idmap_ldap.c @ 22

Last change on this file since 22 was 22, checked in by Yuri Dario, 14 years ago

Source code upgrade to 3.0.25pre2.

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