~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source3/winbindd/idmap_ldap.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
   Copyright (C) Jim McDonough <jmcd@us.ibm.com>        2003
8
8
   Copyright (C) Gerald Carter          2003
9
9
   Copyright (C) Simo Sorce             2003-2007
 
10
   Copyright (C) Michael Adam           2010
10
11
 
11
12
   This program is free software; you can redistribute it and/or modify
12
13
   it under the terms of the GNU General Public License as published by
24
25
 
25
26
#include "includes.h"
26
27
#include "winbindd.h"
 
28
#include "secrets.h"
 
29
#include "idmap.h"
 
30
#include "idmap_rw.h"
 
31
#include "../libcli/security/security.h"
27
32
 
28
33
#undef DBGC_CLASS
29
34
#define DBGC_CLASS DBGC_IDMAP
33
38
 
34
39
#include "smbldap.h"
35
40
 
36
 
static char *idmap_fetch_secret(const char *backend, bool alloc,
 
41
static char *idmap_fetch_secret(const char *backend,
37
42
                                const char *domain, const char *identity)
38
43
{
39
44
        char *tmp, *ret;
40
45
        int r;
41
46
 
42
 
        if (alloc) {
43
 
                r = asprintf(&tmp, "IDMAP_ALLOC_%s", backend);
44
 
        } else {
45
 
                r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
46
 
        }
 
47
        r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
47
48
 
48
49
        if (r < 0)
49
50
                return NULL;
61
62
        char *url;
62
63
        char *suffix;
63
64
        char *user_dn;
64
 
        uint32_t filter_low_id, filter_high_id;         /* Filter range */
65
65
        bool anon;
66
 
};
67
 
 
68
 
struct idmap_ldap_alloc_context {
69
 
        struct smbldap_state *smbldap_state;
70
 
        char *url;
71
 
        char *suffix;
72
 
        char *user_dn;
73
 
        uid_t low_uid, high_uid;      /* Range of uids */
74
 
        gid_t low_gid, high_gid;      /* Range of gids */
75
 
 
 
66
        struct idmap_rw_ops *rw_ops;
76
67
};
77
68
 
78
69
#define CHECK_ALLOC_DONE(mem) do { \
86
77
 IDMAP ALLOC TDB BACKEND
87
78
**********************************************************************/
88
79
 
89
 
static struct idmap_ldap_alloc_context *idmap_alloc_ldap;
90
 
 
91
80
/*********************************************************************
92
81
 ********************************************************************/
93
82
 
109
98
 
110
99
        if ( tmp ) {
111
100
                if (!dom) {
112
 
                        /* only the alloc backend can pass in a NULL dom */
113
 
                        secret = idmap_fetch_secret("ldap", True,
114
 
                                                    NULL, tmp);
 
101
                        DEBUG(0, ("get_credentials: Invalid domain 'NULL' "
 
102
                                  "encountered for user DN %s\n",
 
103
                                  tmp));
 
104
                        ret = NT_STATUS_UNSUCCESSFUL;
 
105
                        goto done;
115
106
                } else {
116
 
                        secret = idmap_fetch_secret("ldap", False,
117
 
                                                    dom->name, tmp);
 
107
                        secret = idmap_fetch_secret("ldap", dom->name, tmp);
118
108
                }
119
109
 
120
110
                if (!secret) {
153
143
 Verify the sambaUnixIdPool entry in the directory.
154
144
**********************************************************************/
155
145
 
156
 
static NTSTATUS verify_idpool(void)
 
146
static NTSTATUS verify_idpool(struct idmap_domain *dom)
157
147
{
158
148
        NTSTATUS ret;
159
 
        TALLOC_CTX *ctx;
 
149
        TALLOC_CTX *mem_ctx;
160
150
        LDAPMessage *result = NULL;
161
151
        LDAPMod **mods = NULL;
162
152
        const char **attr_list;
163
153
        char *filter;
164
154
        int count;
165
155
        int rc;
166
 
 
167
 
        if ( ! idmap_alloc_ldap) {
168
 
                return NT_STATUS_UNSUCCESSFUL;
169
 
        }
170
 
 
171
 
        ctx = talloc_new(idmap_alloc_ldap);
172
 
        if ( ! ctx) {
 
156
        struct idmap_ldap_context *ctx;
 
157
 
 
158
        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
 
159
 
 
160
        mem_ctx = talloc_new(ctx);
 
161
        if (mem_ctx == NULL) {
173
162
                DEBUG(0, ("Out of memory!\n"));
174
163
                return NT_STATUS_NO_MEMORY;
175
164
        }
176
165
 
177
 
        filter = talloc_asprintf(ctx, "(objectclass=%s)", LDAP_OBJ_IDPOOL);
 
166
        filter = talloc_asprintf(mem_ctx, "(objectclass=%s)", LDAP_OBJ_IDPOOL);
178
167
        CHECK_ALLOC_DONE(filter);
179
168
 
180
 
        attr_list = get_attr_list(ctx, idpool_attr_list);
 
169
        attr_list = get_attr_list(mem_ctx, idpool_attr_list);
181
170
        CHECK_ALLOC_DONE(attr_list);
182
171
 
183
 
        rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
184
 
                                idmap_alloc_ldap->suffix,
 
172
        rc = smbldap_search(ctx->smbldap_state,
 
173
                                ctx->suffix,
185
174
                                LDAP_SCOPE_SUBTREE,
186
175
                                filter,
187
176
                                attr_list,
194
183
                return NT_STATUS_UNSUCCESSFUL;
195
184
        }
196
185
 
197
 
        count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
198
 
                                   result);
 
186
        count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
199
187
 
200
188
        ldap_msgfree(result);
201
189
 
202
190
        if ( count > 1 ) {
203
191
                DEBUG(0,("Multiple entries returned from %s (base == %s)\n",
204
 
                        filter, idmap_alloc_ldap->suffix));
 
192
                        filter, ctx->suffix));
205
193
                ret = NT_STATUS_UNSUCCESSFUL;
206
194
                goto done;
207
195
        }
208
196
        else if (count == 0) {
209
197
                char *uid_str, *gid_str;
210
198
 
211
 
                uid_str = talloc_asprintf(ctx, "%lu",
212
 
                                (unsigned long)idmap_alloc_ldap->low_uid);
213
 
                gid_str = talloc_asprintf(ctx, "%lu",
214
 
                                (unsigned long)idmap_alloc_ldap->low_gid);
 
199
                uid_str = talloc_asprintf(mem_ctx, "%lu",
 
200
                                (unsigned long)dom->low_id);
 
201
                gid_str = talloc_asprintf(mem_ctx, "%lu",
 
202
                                (unsigned long)dom->low_id);
215
203
 
216
204
                smbldap_set_mod(&mods, LDAP_MOD_ADD,
217
205
                                "objectClass", LDAP_OBJ_IDPOOL);
224
212
                                                    LDAP_ATTR_GIDNUMBER),
225
213
                                gid_str);
226
214
                if (mods) {
227
 
                        rc = smbldap_modify(idmap_alloc_ldap->smbldap_state,
228
 
                                                idmap_alloc_ldap->suffix,
 
215
                        rc = smbldap_modify(ctx->smbldap_state,
 
216
                                                ctx->suffix,
229
217
                                                mods);
230
218
                        ldap_mods_free(mods, True);
231
219
                } else {
236
224
 
237
225
        ret = (rc == LDAP_SUCCESS)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
238
226
done:
239
 
        talloc_free(ctx);
240
 
        return ret;
241
 
}
242
 
 
243
 
/*****************************************************************************
244
 
 Initialise idmap database.
245
 
*****************************************************************************/
246
 
 
247
 
static NTSTATUS idmap_ldap_alloc_init(const char *params)
248
 
{
249
 
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
250
 
        const char *tmp;
251
 
        uid_t low_uid = 0;
252
 
        uid_t high_uid = 0;
253
 
        gid_t low_gid = 0;
254
 
        gid_t high_gid = 0;
255
 
 
256
 
        /* Only do init if we are online */
257
 
        if (idmap_is_offline()) {
258
 
                return NT_STATUS_FILE_IS_OFFLINE;
259
 
        }
260
 
 
261
 
        idmap_alloc_ldap = TALLOC_ZERO_P(NULL, struct idmap_ldap_alloc_context);
262
 
        CHECK_ALLOC_DONE( idmap_alloc_ldap );
263
 
 
264
 
        /* load ranges */
265
 
 
266
 
        if (!lp_idmap_uid(&low_uid, &high_uid)
267
 
            || !lp_idmap_gid(&low_gid, &high_gid)) {
268
 
                DEBUG(1, ("idmap uid or idmap gid missing\n"));
269
 
                ret = NT_STATUS_UNSUCCESSFUL;
270
 
                goto done;
271
 
        }
272
 
 
273
 
        idmap_alloc_ldap->low_uid = low_uid;
274
 
        idmap_alloc_ldap->high_uid = high_uid;
275
 
        idmap_alloc_ldap->low_gid = low_gid;
276
 
        idmap_alloc_ldap->high_gid= high_gid;
277
 
 
278
 
        if (idmap_alloc_ldap->high_uid <= idmap_alloc_ldap->low_uid) {
279
 
                DEBUG(1, ("idmap uid range 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 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
 
        trim_char(idmap_alloc_ldap->url, '\"', '\"');
310
 
 
311
 
        tmp = lp_parm_const_string(-1, "idmap alloc config",
312
 
                                   "ldap_base_dn", NULL);
313
 
        if ( ! tmp || ! *tmp) {
314
 
                tmp = lp_ldap_idmap_suffix();
315
 
                if ( ! tmp) {
316
 
                        DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
317
 
                        ret = NT_STATUS_UNSUCCESSFUL;
318
 
                        goto done;
319
 
                }
320
 
        }
321
 
 
322
 
        idmap_alloc_ldap->suffix = talloc_strdup(idmap_alloc_ldap, tmp);
323
 
        CHECK_ALLOC_DONE( idmap_alloc_ldap->suffix );
324
 
 
325
 
        ret = smbldap_init(idmap_alloc_ldap, winbind_event_context(),
326
 
                           idmap_alloc_ldap->url,
327
 
                           &idmap_alloc_ldap->smbldap_state);
328
 
        if (!NT_STATUS_IS_OK(ret)) {
329
 
                DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n",
330
 
                          idmap_alloc_ldap->url));
331
 
                goto done;
332
 
        }
333
 
 
334
 
        ret = get_credentials( idmap_alloc_ldap,
335
 
                               idmap_alloc_ldap->smbldap_state,
336
 
                               "idmap alloc config", NULL,
337
 
                               &idmap_alloc_ldap->user_dn );
338
 
        if ( !NT_STATUS_IS_OK(ret) ) {
339
 
                DEBUG(1,("idmap_ldap_alloc_init: Failed to get connection "
340
 
                         "credentials (%s)\n", nt_errstr(ret)));
341
 
                goto done;
342
 
        }
343
 
 
344
 
        /* see if the idmap suffix and sub entries exists */
345
 
 
346
 
        ret = verify_idpool();
347
 
 
348
 
 done:
349
 
        if ( !NT_STATUS_IS_OK( ret ) )
350
 
                TALLOC_FREE( idmap_alloc_ldap );
351
 
 
 
227
        talloc_free(mem_ctx);
352
228
        return ret;
353
229
}
354
230
 
356
232
 Allocate a new uid or gid
357
233
********************************/
358
234
 
359
 
static NTSTATUS idmap_ldap_allocate_id(struct unixid *xid)
 
235
static NTSTATUS idmap_ldap_allocate_id_internal(struct idmap_domain *dom,
 
236
                                                struct unixid *xid)
360
237
{
361
 
        TALLOC_CTX *ctx;
 
238
        TALLOC_CTX *mem_ctx;
362
239
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
363
240
        int rc = LDAP_SERVER_DOWN;
364
241
        int count = 0;
371
248
        const char *dn = NULL;
372
249
        const char **attr_list;
373
250
        const char *type;
 
251
        struct idmap_ldap_context *ctx;
374
252
 
375
253
        /* Only do query if we are online */
376
254
        if (idmap_is_offline()) {
377
255
                return NT_STATUS_FILE_IS_OFFLINE;
378
256
        }
379
257
 
380
 
        if ( ! idmap_alloc_ldap) {
381
 
                return NT_STATUS_UNSUCCESSFUL;
382
 
        }
 
258
        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
383
259
 
384
 
        ctx = talloc_new(idmap_alloc_ldap);
385
 
        if ( ! ctx) {
 
260
        mem_ctx = talloc_new(ctx);
 
261
        if (!mem_ctx) {
386
262
                DEBUG(0, ("Out of memory!\n"));
387
263
                return NT_STATUS_NO_MEMORY;
388
264
        }
405
281
                return NT_STATUS_INVALID_PARAMETER;
406
282
        }
407
283
 
408
 
        filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
 
284
        filter = talloc_asprintf(mem_ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
409
285
        CHECK_ALLOC_DONE(filter);
410
286
 
411
 
        attr_list = get_attr_list(ctx, idpool_attr_list);
 
287
        attr_list = get_attr_list(mem_ctx, idpool_attr_list);
412
288
        CHECK_ALLOC_DONE(attr_list);
413
289
 
414
290
        DEBUG(10, ("Search of the id pool (filter: %s)\n", filter));
415
291
 
416
 
        rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
417
 
                                idmap_alloc_ldap->suffix,
418
 
                               LDAP_SCOPE_SUBTREE, filter,
419
 
                               attr_list, 0, &result);
 
292
        rc = smbldap_search(ctx->smbldap_state,
 
293
                           ctx->suffix,
 
294
                           LDAP_SCOPE_SUBTREE, filter,
 
295
                           attr_list, 0, &result);
420
296
 
421
297
        if (rc != LDAP_SUCCESS) {
422
298
                DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
423
299
                goto done;
424
300
        }
425
301
 
426
 
        talloc_autofree_ldapmsg(ctx, result);
 
302
        talloc_autofree_ldapmsg(mem_ctx, result);
427
303
 
428
 
        count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
429
 
                                   result);
 
304
        count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
430
305
        if (count != 1) {
431
306
                DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
432
307
                goto done;
433
308
        }
434
309
 
435
 
        entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
436
 
                                 result);
 
310
        entry = ldap_first_entry(ctx->smbldap_state->ldap_struct, result);
437
311
 
438
 
        dn = smbldap_talloc_dn(ctx,
439
 
                               idmap_alloc_ldap->smbldap_state->ldap_struct,
 
312
        dn = smbldap_talloc_dn(mem_ctx,
 
313
                               ctx->smbldap_state->ldap_struct,
440
314
                               entry);
441
315
        if ( ! dn) {
442
316
                goto done;
443
317
        }
444
318
 
445
 
        if ( ! (id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
446
 
                                entry, type, ctx))) {
 
319
        id_str = smbldap_talloc_single_attribute(
 
320
                                ctx->smbldap_state->ldap_struct,
 
321
                                entry, type, mem_ctx);
 
322
        if (id_str == NULL) {
447
323
                DEBUG(0,("%s attribute not found\n", type));
448
 
                goto done;
449
 
        }
450
 
        if ( ! id_str) {
451
 
                DEBUG(0,("Out of memory\n"));
452
 
                ret = NT_STATUS_NO_MEMORY;
 
324
                ret = NT_STATUS_UNSUCCESSFUL;
453
325
                goto done;
454
326
        }
455
327
 
459
331
 
460
332
        switch (xid->type) {
461
333
        case ID_TYPE_UID:
462
 
                if (xid->id > idmap_alloc_ldap->high_uid) {
 
334
                if (xid->id > dom->high_id) {
463
335
                        DEBUG(0,("Cannot allocate uid above %lu!\n",
464
 
                                 (unsigned long)idmap_alloc_ldap->high_uid));
 
336
                                 (unsigned long)dom->high_id));
465
337
                        goto done;
466
338
                }
467
339
                break;
468
340
 
469
341
        case ID_TYPE_GID:
470
 
                if (xid->id > idmap_alloc_ldap->high_gid) {
 
342
                if (xid->id > dom->high_id) {
471
343
                        DEBUG(0,("Cannot allocate gid above %lu!\n",
472
 
                                 (unsigned long)idmap_alloc_ldap->high_uid));
 
344
                                 (unsigned long)dom->high_id));
473
345
                        goto done;
474
346
                }
475
347
                break;
479
351
                goto done;
480
352
        }
481
353
 
482
 
        new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id + 1);
 
354
        new_id_str = talloc_asprintf(mem_ctx, "%lu", (unsigned long)xid->id + 1);
483
355
        if ( ! new_id_str) {
484
356
                DEBUG(0,("Out of memory\n"));
485
357
                ret = NT_STATUS_NO_MEMORY;
497
369
        DEBUG(10, ("Try to atomically increment the id (%s -> %s)\n",
498
370
                   id_str, new_id_str));
499
371
 
500
 
        rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
501
 
 
502
 
        ldap_mods_free(mods, True);
503
 
 
504
 
        if (rc != LDAP_SUCCESS) {
505
 
                DEBUG(1,("Failed to allocate new %s. "
506
 
                         "smbldap_modify() failed.\n", type));
507
 
                goto done;
508
 
        }
509
 
 
510
 
        ret = NT_STATUS_OK;
511
 
 
512
 
done:
513
 
        talloc_free(ctx);
514
 
        return ret;
515
 
}
516
 
 
517
 
/**********************************
518
 
 Get current highest id.
519
 
**********************************/
520
 
 
521
 
static NTSTATUS idmap_ldap_get_hwm(struct unixid *xid)
522
 
{
523
 
        TALLOC_CTX *memctx;
524
 
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
525
 
        int rc = LDAP_SERVER_DOWN;
526
 
        int count = 0;
527
 
        LDAPMessage *result = NULL;
528
 
        LDAPMessage *entry = NULL;
529
 
        char *id_str;
530
 
        char *filter = NULL;
531
 
        const char **attr_list;
532
 
        const char *type;
533
 
 
534
 
        /* Only do query if we are online */
535
 
        if (idmap_is_offline()) {
536
 
                return NT_STATUS_FILE_IS_OFFLINE;
537
 
        }
538
 
 
539
 
        if ( ! idmap_alloc_ldap) {
540
 
                return NT_STATUS_UNSUCCESSFUL;
541
 
        }
542
 
 
543
 
        memctx = talloc_new(idmap_alloc_ldap);
544
 
        if ( ! memctx) {
545
 
                DEBUG(0, ("Out of memory!\n"));
546
 
                return NT_STATUS_NO_MEMORY;
547
 
        }
548
 
 
549
 
        /* get type */
550
 
        switch (xid->type) {
551
 
 
552
 
        case ID_TYPE_UID:
553
 
                type = get_attr_key2string(idpool_attr_list,
554
 
                                           LDAP_ATTR_UIDNUMBER);
555
 
                break;
556
 
 
557
 
        case ID_TYPE_GID:
558
 
                type = get_attr_key2string(idpool_attr_list,
559
 
                                           LDAP_ATTR_GIDNUMBER);
560
 
                break;
561
 
 
562
 
        default:
563
 
                DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
564
 
                return NT_STATUS_INVALID_PARAMETER;
565
 
        }
566
 
 
567
 
        filter = talloc_asprintf(memctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
568
 
        CHECK_ALLOC_DONE(filter);
569
 
 
570
 
        attr_list = get_attr_list(memctx, idpool_attr_list);
571
 
        CHECK_ALLOC_DONE(attr_list);
572
 
 
573
 
        rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
574
 
                                idmap_alloc_ldap->suffix,
575
 
                               LDAP_SCOPE_SUBTREE, filter,
576
 
                               attr_list, 0, &result);
577
 
 
578
 
        if (rc != LDAP_SUCCESS) {
579
 
                DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
580
 
                goto done;
581
 
        }
582
 
 
583
 
        talloc_autofree_ldapmsg(memctx, result);
584
 
 
585
 
        count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
586
 
                                   result);
587
 
        if (count != 1) {
588
 
                DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
589
 
                goto done;
590
 
        }
591
 
 
592
 
        entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
593
 
                                 result);
594
 
 
595
 
        id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
596
 
                        entry, type, memctx);
597
 
        if ( ! id_str) {
598
 
                DEBUG(0,("%s attribute not found\n", type));
599
 
                goto done;
600
 
        }
601
 
        if ( ! id_str) {
602
 
                DEBUG(0,("Out of memory\n"));
603
 
                ret = NT_STATUS_NO_MEMORY;
604
 
                goto done;
605
 
        }
606
 
 
607
 
        xid->id = strtoul(id_str, NULL, 10);
608
 
 
609
 
        ret = NT_STATUS_OK;
610
 
done:
611
 
        talloc_free(memctx);
612
 
        return ret;
613
 
}
614
 
/**********************************
615
 
 Set highest id.
616
 
**********************************/
617
 
 
618
 
static NTSTATUS idmap_ldap_set_hwm(struct unixid *xid)
619
 
{
620
 
        TALLOC_CTX *ctx;
621
 
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
622
 
        int rc = LDAP_SERVER_DOWN;
623
 
        int count = 0;
624
 
        LDAPMessage *result = NULL;
625
 
        LDAPMessage *entry = NULL;
626
 
        LDAPMod **mods = NULL;
627
 
        char *new_id_str;
628
 
        char *filter = NULL;
629
 
        const char *dn = NULL;
630
 
        const char **attr_list;
631
 
        const char *type;
632
 
 
633
 
        /* Only do query if we are online */
634
 
        if (idmap_is_offline()) {
635
 
                return NT_STATUS_FILE_IS_OFFLINE;
636
 
        }
637
 
 
638
 
        if ( ! idmap_alloc_ldap) {
639
 
                return NT_STATUS_UNSUCCESSFUL;
640
 
        }
641
 
 
642
 
        ctx = talloc_new(idmap_alloc_ldap);
643
 
        if ( ! ctx) {
644
 
                DEBUG(0, ("Out of memory!\n"));
645
 
                return NT_STATUS_NO_MEMORY;
646
 
        }
647
 
 
648
 
        /* get type */
649
 
        switch (xid->type) {
650
 
 
651
 
        case ID_TYPE_UID:
652
 
                type = get_attr_key2string(idpool_attr_list,
653
 
                                           LDAP_ATTR_UIDNUMBER);
654
 
                break;
655
 
 
656
 
        case ID_TYPE_GID:
657
 
                type = get_attr_key2string(idpool_attr_list,
658
 
                                           LDAP_ATTR_GIDNUMBER);
659
 
                break;
660
 
 
661
 
        default:
662
 
                DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
663
 
                return NT_STATUS_INVALID_PARAMETER;
664
 
        }
665
 
 
666
 
        filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
667
 
        CHECK_ALLOC_DONE(filter);
668
 
 
669
 
        attr_list = get_attr_list(ctx, idpool_attr_list);
670
 
        CHECK_ALLOC_DONE(attr_list);
671
 
 
672
 
        rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
673
 
                                idmap_alloc_ldap->suffix,
674
 
                               LDAP_SCOPE_SUBTREE, filter,
675
 
                               attr_list, 0, &result);
676
 
 
677
 
        if (rc != LDAP_SUCCESS) {
678
 
                DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
679
 
                goto done;
680
 
        }
681
 
 
682
 
        talloc_autofree_ldapmsg(ctx, result);
683
 
 
684
 
        count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
685
 
                                   result);
686
 
        if (count != 1) {
687
 
                DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
688
 
                goto done;
689
 
        }
690
 
 
691
 
        entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
692
 
                                 result);
693
 
 
694
 
        dn = smbldap_talloc_dn(ctx,
695
 
                                idmap_alloc_ldap->smbldap_state->ldap_struct,
696
 
                                entry);
697
 
        if ( ! dn) {
698
 
                goto done;
699
 
        }
700
 
 
701
 
        new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id);
702
 
        if ( ! new_id_str) {
703
 
                DEBUG(0,("Out of memory\n"));
704
 
                ret = NT_STATUS_NO_MEMORY;
705
 
                goto done;
706
 
        }
707
 
 
708
 
        smbldap_set_mod(&mods, LDAP_MOD_REPLACE, type, new_id_str);
709
 
 
710
 
        if (mods == NULL) {
711
 
                DEBUG(0,("smbldap_set_mod() failed.\n"));
712
 
                goto done;
713
 
        }
714
 
 
715
 
        rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
716
 
 
717
 
        ldap_mods_free(mods, True);
718
 
 
719
 
        if (rc != LDAP_SUCCESS) {
720
 
                DEBUG(1,("Failed to allocate new %s. "
721
 
                         "smbldap_modify() failed.\n", type));
722
 
                goto done;
723
 
        }
724
 
 
725
 
        ret = NT_STATUS_OK;
726
 
 
727
 
done:
728
 
        talloc_free(ctx);
729
 
        return ret;
730
 
}
731
 
 
732
 
/**********************************
733
 
 Close idmap ldap alloc
734
 
**********************************/
735
 
 
736
 
static NTSTATUS idmap_ldap_alloc_close(void)
737
 
{
738
 
        if (idmap_alloc_ldap) {
739
 
                smbldap_free_struct(&idmap_alloc_ldap->smbldap_state);
740
 
                DEBUG(5,("The connection to the LDAP server was closed\n"));
741
 
                /* maybe free the results here --metze */
742
 
                TALLOC_FREE(idmap_alloc_ldap);
743
 
        }
744
 
        return NT_STATUS_OK;
 
372
        rc = smbldap_modify(ctx->smbldap_state, dn, mods);
 
373
 
 
374
        ldap_mods_free(mods, True);
 
375
 
 
376
        if (rc != LDAP_SUCCESS) {
 
377
                DEBUG(1,("Failed to allocate new %s. "
 
378
                         "smbldap_modify() failed.\n", type));
 
379
                goto done;
 
380
        }
 
381
 
 
382
        ret = NT_STATUS_OK;
 
383
 
 
384
done:
 
385
        talloc_free(mem_ctx);
 
386
        return ret;
 
387
}
 
388
 
 
389
/**
 
390
 * Allocate a new unix-ID.
 
391
 * For now this is for the default idmap domain only.
 
392
 * Should be extended later on.
 
393
 */
 
394
static NTSTATUS idmap_ldap_allocate_id(struct idmap_domain *dom,
 
395
                                       struct unixid *id)
 
396
{
 
397
        NTSTATUS ret;
 
398
 
 
399
        if (!strequal(dom->name, "*")) {
 
400
                DEBUG(3, ("idmap_ldap_allocate_id: "
 
401
                          "Refusing allocation of a new unixid for domain'%s'. "
 
402
                          "This is only supported for the default "
 
403
                          "domain \"*\".\n",
 
404
                           dom->name));
 
405
                return NT_STATUS_NOT_IMPLEMENTED;
 
406
        }
 
407
 
 
408
        ret = idmap_ldap_allocate_id_internal(dom, id);
 
409
 
 
410
        return ret;
745
411
}
746
412
 
747
413
 
762
428
 Initialise idmap database.
763
429
********************************/
764
430
 
765
 
static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom,
766
 
                                   const char *params)
 
431
static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
 
432
                                       const struct id_map *map);
 
433
 
 
434
static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
767
435
{
768
436
        NTSTATUS ret;
769
437
        struct idmap_ldap_context *ctx = NULL;
781
449
                return NT_STATUS_NO_MEMORY;
782
450
        }
783
451
 
784
 
        if (strequal(dom->name, "*")) {
785
 
                uid_t low_uid = 0;
786
 
                uid_t high_uid = 0;
787
 
                gid_t low_gid = 0;
788
 
                gid_t high_gid = 0;
789
 
 
790
 
                ctx->filter_low_id = 0;
791
 
                ctx->filter_high_id = 0;
792
 
 
793
 
                if (lp_idmap_uid(&low_uid, &high_uid)) {
794
 
                        ctx->filter_low_id = low_uid;
795
 
                        ctx->filter_high_id = high_uid;
796
 
                } else {
797
 
                        DEBUG(3, ("Warning: 'idmap uid' not set!\n"));
798
 
                }
799
 
 
800
 
                if (lp_idmap_gid(&low_gid, &high_gid)) {
801
 
                        if ((low_gid != low_uid) || (high_gid != high_uid)) {
802
 
                                DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'"
803
 
                                      " ranges do not agree -- building "
804
 
                                      "intersection\n"));
805
 
                                ctx->filter_low_id = MAX(ctx->filter_low_id,
806
 
                                                         low_gid);
807
 
                                ctx->filter_high_id = MIN(ctx->filter_high_id,
808
 
                                                          high_gid);
809
 
                        }
810
 
                } else {
811
 
                        DEBUG(3, ("Warning: 'idmap gid' not set!\n"));
812
 
                }
813
 
        } else {
814
 
                const char *range = NULL;
815
 
 
816
 
                config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
817
 
                if ( ! config_option) {
818
 
                        DEBUG(0, ("Out of memory!\n"));
819
 
                        ret = NT_STATUS_NO_MEMORY;
820
 
                        goto done;
821
 
                }
822
 
 
823
 
                /* load ranges */
824
 
                range = lp_parm_const_string(-1, config_option, "range", NULL);
825
 
                if (range && range[0]) {
826
 
                        if ((sscanf(range, "%u - %u", &ctx->filter_low_id,
827
 
                                                        &ctx->filter_high_id) != 2))
828
 
                        {
829
 
                                DEBUG(1, ("ERROR: invalid filter range [%s]", range));
830
 
                                ctx->filter_low_id = 0;
831
 
                                ctx->filter_high_id = 0;
832
 
                        }
833
 
                }
834
 
        }
835
 
 
836
 
        if (ctx->filter_low_id > ctx->filter_high_id) {
837
 
                DEBUG(1, ("ERROR: invalid filter range [%u-%u]",
838
 
                      ctx->filter_low_id, ctx->filter_high_id));
839
 
                ctx->filter_low_id = 0;
840
 
                ctx->filter_high_id = 0;
841
 
        }
842
 
 
843
 
        if (params != NULL) {
844
 
                /* assume location is the only parameter */
845
 
                ctx->url = talloc_strdup(ctx, params);
846
 
        } else {
847
 
                tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
848
 
 
849
 
                if ( ! tmp) {
850
 
                        DEBUG(1, ("ERROR: missing idmap ldap url\n"));
851
 
                        ret = NT_STATUS_UNSUCCESSFUL;
852
 
                        goto done;
853
 
                }
854
 
 
855
 
                ctx->url = talloc_strdup(ctx, tmp);
856
 
        }
857
 
        CHECK_ALLOC_DONE(ctx->url);
 
452
        config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
 
453
        if (!config_option) {
 
454
                DEBUG(0, ("Out of memory!\n"));
 
455
                ret = NT_STATUS_NO_MEMORY;
 
456
                goto done;
 
457
        }
 
458
 
 
459
        tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
 
460
 
 
461
        if ( ! tmp) {
 
462
                DEBUG(1, ("ERROR: missing idmap ldap url\n"));
 
463
                ret = NT_STATUS_UNSUCCESSFUL;
 
464
                goto done;
 
465
        }
 
466
 
 
467
        ctx->url = talloc_strdup(ctx, tmp);
858
468
 
859
469
        trim_char(ctx->url, '\"', '\"');
860
470
 
861
 
        tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL);
862
 
        if ( ! tmp || ! *tmp) {
863
 
                tmp = lp_ldap_idmap_suffix();
864
 
                if ( ! tmp) {
865
 
                        DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
866
 
                        ret = NT_STATUS_UNSUCCESSFUL;
867
 
                        goto done;
 
471
        tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL);
 
472
        if ( ! tmp || ! *tmp) {
 
473
                tmp = lp_ldap_idmap_suffix();
 
474
                if ( ! tmp) {
 
475
                        DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
 
476
                        ret = NT_STATUS_UNSUCCESSFUL;
 
477
                        goto done;
868
478
                }
869
 
        }
 
479
        }
870
480
 
871
481
        ctx->suffix = talloc_strdup(ctx, tmp);
872
482
        CHECK_ALLOC_DONE(ctx->suffix);
873
483
 
 
484
        ctx->rw_ops = talloc_zero(ctx, struct idmap_rw_ops);
 
485
        CHECK_ALLOC_DONE(ctx->rw_ops);
 
486
 
 
487
        ctx->rw_ops->get_new_id = idmap_ldap_allocate_id_internal;
 
488
        ctx->rw_ops->set_mapping = idmap_ldap_set_mapping;
 
489
 
874
490
        ret = smbldap_init(ctx, winbind_event_context(), ctx->url,
875
491
                           &ctx->smbldap_state);
876
492
        if (!NT_STATUS_IS_OK(ret)) {
878
494
                goto done;
879
495
        }
880
496
 
881
 
        ret = get_credentials( ctx, ctx->smbldap_state, config_option,
 
497
        ret = get_credentials( ctx, ctx->smbldap_state, config_option,
882
498
                               dom, &ctx->user_dn );
883
499
        if ( !NT_STATUS_IS_OK(ret) ) {
884
500
                DEBUG(1,("idmap_ldap_db_init: Failed to get connection "
886
502
                goto done;
887
503
        }
888
504
 
889
 
        /* set the destructor on the context, so that resource are properly
890
 
           freed if the contexts is released */
891
 
 
 
505
        /*
 
506
         * Set the destructor on the context, so that resources are
 
507
         * properly freed when the context is released.
 
508
         */
892
509
        talloc_set_destructor(ctx, idmap_ldap_close_destructor);
893
510
 
894
511
        dom->private_data = ctx;
895
512
 
 
513
        ret = verify_idpool(dom);
 
514
        if (!NT_STATUS_IS_OK(ret)) {
 
515
                DEBUG(1, ("idmap_ldap_db_init: failed to verify ID pool (%s)\n",
 
516
                         nt_errstr(ret)));
 
517
                goto done;
 
518
        }
 
519
 
896
520
        talloc_free(config_option);
897
521
        return NT_STATUS_OK;
898
522
 
902
526
        return ret;
903
527
}
904
528
 
 
529
/**
 
530
 * set a mapping.
 
531
 */
 
532
 
 
533
/* TODO: change this:  This function cannot be called to modify a mapping,
 
534
 * only set a new one */
 
535
 
 
536
static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
 
537
                                       const struct id_map *map)
 
538
{
 
539
        NTSTATUS ret;
 
540
        TALLOC_CTX *memctx;
 
541
        struct idmap_ldap_context *ctx;
 
542
        LDAPMessage *entry = NULL;
 
543
        LDAPMod **mods = NULL;
 
544
        const char *type;
 
545
        char *id_str;
 
546
        char *sid;
 
547
        char *dn;
 
548
        int rc = -1;
 
549
 
 
550
        /* Only do query if we are online */
 
551
        if (idmap_is_offline()) {
 
552
                return NT_STATUS_FILE_IS_OFFLINE;
 
553
        }
 
554
 
 
555
        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
 
556
 
 
557
        switch(map->xid.type) {
 
558
        case ID_TYPE_UID:
 
559
                type = get_attr_key2string(sidmap_attr_list,
 
560
                                           LDAP_ATTR_UIDNUMBER);
 
561
                break;
 
562
 
 
563
        case ID_TYPE_GID:
 
564
                type = get_attr_key2string(sidmap_attr_list,
 
565
                                           LDAP_ATTR_GIDNUMBER);
 
566
                break;
 
567
 
 
568
        default:
 
569
                return NT_STATUS_INVALID_PARAMETER;
 
570
        }
 
571
 
 
572
        memctx = talloc_new(ctx);
 
573
        if ( ! memctx) {
 
574
                DEBUG(0, ("Out of memory!\n"));
 
575
                return NT_STATUS_NO_MEMORY;
 
576
        }
 
577
 
 
578
        id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id);
 
579
        CHECK_ALLOC_DONE(id_str);
 
580
 
 
581
        sid = talloc_strdup(memctx, sid_string_talloc(memctx, map->sid));
 
582
        CHECK_ALLOC_DONE(sid);
 
583
 
 
584
        dn = talloc_asprintf(memctx, "%s=%s,%s",
 
585
                        get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
 
586
                        sid,
 
587
                        ctx->suffix);
 
588
        CHECK_ALLOC_DONE(dn);
 
589
 
 
590
        smbldap_set_mod(&mods, LDAP_MOD_ADD,
 
591
                        "objectClass", LDAP_OBJ_IDMAP_ENTRY);
 
592
 
 
593
        smbldap_make_mod(ctx->smbldap_state->ldap_struct,
 
594
                         entry, &mods, type, id_str);
 
595
 
 
596
        smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods,
 
597
                         get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
 
598
                         sid);
 
599
 
 
600
        if ( ! mods) {
 
601
                DEBUG(2, ("ERROR: No mods?\n"));
 
602
                ret = NT_STATUS_UNSUCCESSFUL;
 
603
                goto done;
 
604
        }
 
605
 
 
606
        /* TODO: remove conflicting mappings! */
 
607
 
 
608
        smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY);
 
609
 
 
610
        DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str));
 
611
 
 
612
        rc = smbldap_add(ctx->smbldap_state, dn, mods);
 
613
        ldap_mods_free(mods, True);
 
614
 
 
615
        if (rc != LDAP_SUCCESS) {
 
616
                char *ld_error = NULL;
 
617
                ldap_get_option(ctx->smbldap_state->ldap_struct,
 
618
                                LDAP_OPT_ERROR_STRING, &ld_error);
 
619
                DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "
 
620
                         "mapping [%s]\n", sid,
 
621
                         (unsigned long)map->xid.id, type));
 
622
                DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
 
623
                        ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
 
624
                if (ld_error) {
 
625
                        ldap_memfree(ld_error);
 
626
                }
 
627
                ret = NT_STATUS_UNSUCCESSFUL;
 
628
                goto done;
 
629
        }
 
630
 
 
631
        DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "
 
632
                  "%lu [%s]\n", sid, (unsigned long)map->xid.id, type));
 
633
 
 
634
        ret = NT_STATUS_OK;
 
635
 
 
636
done:
 
637
        talloc_free(memctx);
 
638
        return ret;
 
639
}
 
640
 
 
641
/**
 
642
 * Create a new mapping for an unmapped SID, also allocating a new ID.
 
643
 * If possible, this should be run inside a transaction to make the
 
644
 * action atomic.
 
645
 */
 
646
static NTSTATUS idmap_ldap_new_mapping(struct idmap_domain *dom, struct id_map *map)
 
647
{
 
648
        NTSTATUS ret;
 
649
        struct idmap_ldap_context *ctx;
 
650
 
 
651
        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
 
652
 
 
653
        ret = idmap_rw_new_mapping(dom, ctx->rw_ops, map);
 
654
 
 
655
        return ret;
 
656
}
 
657
 
 
658
 
905
659
/* max number of ids requested per batch query */
906
660
#define IDMAP_LDAP_MAX_IDS 30
907
661
 
1025
779
 
1026
780
        for (i = 0; i < count; i++) {
1027
781
                char *sidstr = NULL;
1028
 
                char *tmp = NULL;
 
782
                char *tmp = NULL;
1029
783
                enum id_type type;
1030
784
                struct id_map *map;
1031
785
                uint32_t id;
1074
828
                }
1075
829
 
1076
830
                id = strtoul(tmp, NULL, 10);
1077
 
                if ((id == 0) ||
1078
 
                    (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
1079
 
                    (ctx->filter_high_id && (id > ctx->filter_high_id))) {
 
831
                if (!idmap_unix_id_is_in_range(id, dom)) {
1080
832
                        DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
1081
833
                                  "Filtered!\n", id,
1082
 
                                  ctx->filter_low_id, ctx->filter_high_id));
 
834
                                  dom->low_id, dom->high_id));
1083
835
                        TALLOC_FREE(sidstr);
1084
836
                        TALLOC_FREE(tmp);
1085
837
                        continue;
1145
897
 
1146
898
/* this function searches up to IDMAP_LDAP_MAX_IDS entries
1147
899
 * in maps for a match */
1148
 
static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID *sid)
 
900
static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid)
1149
901
{
1150
902
        int i;
1151
903
 
1153
905
                if (maps[i] == NULL) { /* end of the run */
1154
906
                        return NULL;
1155
907
                }
1156
 
                if (sid_equal(maps[i]->sid, sid)) {
 
908
                if (dom_sid_equal(maps[i]->sid, sid)) {
1157
909
                        return maps[i];
1158
910
                }
1159
911
        }
1164
916
static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom,
1165
917
                                           struct id_map **ids)
1166
918
{
1167
 
        LDAPMessage *entry = NULL;
 
919
        LDAPMessage *entry = NULL;
1168
920
        NTSTATUS ret;
1169
921
        TALLOC_CTX *memctx;
1170
922
        struct idmap_ldap_context *ctx;
1262
1014
                char *tmp = NULL;
1263
1015
                enum id_type type;
1264
1016
                struct id_map *map;
1265
 
                DOM_SID sid;
 
1017
                struct dom_sid sid;
1266
1018
                uint32_t id;
1267
1019
 
1268
1020
                if (i == 0) { /* first entry */
1323
1075
                }
1324
1076
 
1325
1077
                id = strtoul(tmp, NULL, 10);
1326
 
                if ((id == 0) ||
1327
 
                    (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
1328
 
                    (ctx->filter_high_id && (id > ctx->filter_high_id))) {
 
1078
                if (!idmap_unix_id_is_in_range(id, dom)) {
1329
1079
                        DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
1330
1080
                                  "Filtered!\n", id,
1331
 
                                  ctx->filter_low_id, ctx->filter_high_id));
 
1081
                                  dom->low_id, dom->high_id));
1332
1082
                        TALLOC_FREE(sidstr);
1333
1083
                        TALLOC_FREE(tmp);
1334
1084
                        continue;
1363
1113
                goto again;
1364
1114
        }
1365
1115
 
1366
 
        ret = NT_STATUS_OK;
1367
 
 
1368
 
        /* mark all unknwon/expired ones as unmapped */
 
1116
        /*
 
1117
         *  try to create new mappings for unmapped sids
 
1118
         */
1369
1119
        for (i = 0; ids[i]; i++) {
1370
 
                if (ids[i]->status != ID_MAPPED)
 
1120
                if (ids[i]->status != ID_MAPPED) {
1371
1121
                        ids[i]->status = ID_UNMAPPED;
1372
 
        }
1373
 
 
1374
 
done:
1375
 
        talloc_free(memctx);
1376
 
        return ret;
1377
 
}
1378
 
 
1379
 
/**********************************
1380
 
 set a mapping.
1381
 
**********************************/
1382
 
 
1383
 
/* TODO: change this:  This function cannot be called to modify a mapping,
1384
 
 * only set a new one */
1385
 
 
1386
 
static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
1387
 
                                       const struct id_map *map)
1388
 
{
1389
 
        NTSTATUS ret;
1390
 
        TALLOC_CTX *memctx;
1391
 
        struct idmap_ldap_context *ctx;
1392
 
        LDAPMessage *entry = NULL;
1393
 
        LDAPMod **mods = NULL;
1394
 
        const char *type;
1395
 
        char *id_str;
1396
 
        char *sid;
1397
 
        char *dn;
1398
 
        int rc = -1;
1399
 
 
1400
 
        /* Only do query if we are online */
1401
 
        if (idmap_is_offline()) {
1402
 
                return NT_STATUS_FILE_IS_OFFLINE;
1403
 
        }
1404
 
 
1405
 
        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
1406
 
 
1407
 
        switch(map->xid.type) {
1408
 
        case ID_TYPE_UID:
1409
 
                type = get_attr_key2string(sidmap_attr_list,
1410
 
                                           LDAP_ATTR_UIDNUMBER);
1411
 
                break;
1412
 
 
1413
 
        case ID_TYPE_GID:
1414
 
                type = get_attr_key2string(sidmap_attr_list,
1415
 
                                           LDAP_ATTR_GIDNUMBER);
1416
 
                break;
1417
 
 
1418
 
        default:
1419
 
                return NT_STATUS_INVALID_PARAMETER;
1420
 
        }
1421
 
 
1422
 
        memctx = talloc_new(ctx);
1423
 
        if ( ! memctx) {
1424
 
                DEBUG(0, ("Out of memory!\n"));
1425
 
                return NT_STATUS_NO_MEMORY;
1426
 
        }
1427
 
 
1428
 
        id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id);
1429
 
        CHECK_ALLOC_DONE(id_str);
1430
 
 
1431
 
        sid = talloc_strdup(memctx, sid_string_talloc(memctx, map->sid));
1432
 
        CHECK_ALLOC_DONE(sid);
1433
 
 
1434
 
        dn = talloc_asprintf(memctx, "%s=%s,%s",
1435
 
                        get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
1436
 
                        sid,
1437
 
                        ctx->suffix);
1438
 
        CHECK_ALLOC_DONE(dn);
1439
 
 
1440
 
        smbldap_set_mod(&mods, LDAP_MOD_ADD,
1441
 
                        "objectClass", LDAP_OBJ_IDMAP_ENTRY);
1442
 
 
1443
 
        smbldap_make_mod(ctx->smbldap_state->ldap_struct,
1444
 
                         entry, &mods, type, id_str);
1445
 
 
1446
 
        smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods,
1447
 
                         get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
1448
 
                         sid);
1449
 
 
1450
 
        if ( ! mods) {
1451
 
                DEBUG(2, ("ERROR: No mods?\n"));
1452
 
                ret = NT_STATUS_UNSUCCESSFUL;
1453
 
                goto done;
1454
 
        }
1455
 
 
1456
 
        /* TODO: remove conflicting mappings! */
1457
 
 
1458
 
        smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY);
1459
 
 
1460
 
        DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str));
1461
 
 
1462
 
        rc = smbldap_add(ctx->smbldap_state, dn, mods);
1463
 
        ldap_mods_free(mods, True);
1464
 
 
1465
 
        if (rc != LDAP_SUCCESS) {
1466
 
                char *ld_error = NULL;
1467
 
                ldap_get_option(ctx->smbldap_state->ldap_struct,
1468
 
                                LDAP_OPT_ERROR_STRING, &ld_error);
1469
 
                DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "
1470
 
                         "mapping [%s]\n", sid,
1471
 
                         (unsigned long)map->xid.id, type));
1472
 
                DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
1473
 
                        ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
1474
 
                if (ld_error) {
1475
 
                        ldap_memfree(ld_error);
 
1122
                        if (ids[i]->sid != NULL) {
 
1123
                                ret = idmap_ldap_new_mapping(dom, ids[i]);
 
1124
                                if (!NT_STATUS_IS_OK(ret)) {
 
1125
                                        goto done;
 
1126
                                }
 
1127
                        }
1476
1128
                }
1477
 
                ret = NT_STATUS_UNSUCCESSFUL;
1478
 
                goto done;
1479
1129
        }
1480
1130
 
1481
 
        DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "
1482
 
                  "%lu [%s]\n", sid, (unsigned long)map->xid.id, type));
1483
 
 
1484
1131
        ret = NT_STATUS_OK;
1485
1132
 
1486
1133
done:
1492
1139
 Close the idmap ldap instance
1493
1140
**********************************/
1494
1141
 
1495
 
static NTSTATUS idmap_ldap_close(struct idmap_domain *dom)
1496
 
{
1497
 
        struct idmap_ldap_context *ctx;
1498
 
 
1499
 
        if (dom->private_data) {
1500
 
                ctx = talloc_get_type(dom->private_data,
1501
 
                                      struct idmap_ldap_context);
1502
 
 
1503
 
                talloc_free(ctx);
1504
 
                dom->private_data = NULL;
1505
 
        }
1506
 
 
1507
 
        return NT_STATUS_OK;
1508
 
}
1509
 
 
1510
1142
static struct idmap_methods idmap_ldap_methods = {
1511
1143
 
1512
1144
        .init = idmap_ldap_db_init,
1513
1145
        .unixids_to_sids = idmap_ldap_unixids_to_sids,
1514
1146
        .sids_to_unixids = idmap_ldap_sids_to_unixids,
1515
 
        .set_mapping = idmap_ldap_set_mapping,
1516
 
        .close_fn = idmap_ldap_close
1517
 
};
1518
 
 
1519
 
static struct idmap_alloc_methods idmap_ldap_alloc_methods = {
1520
 
 
1521
 
        .init = idmap_ldap_alloc_init,
1522
1147
        .allocate_id = idmap_ldap_allocate_id,
1523
 
        .get_id_hwm = idmap_ldap_get_hwm,
1524
 
        .set_id_hwm = idmap_ldap_set_hwm,
1525
 
        .close_fn = idmap_ldap_alloc_close,
1526
 
        /* .dump_data = TODO */
1527
1148
};
1528
1149
 
1529
 
static NTSTATUS idmap_alloc_ldap_init(void)
1530
 
{
1531
 
        return smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "ldap",
1532
 
                                        &idmap_ldap_alloc_methods);
1533
 
}
1534
 
 
1535
1150
NTSTATUS idmap_ldap_init(void);
1536
1151
NTSTATUS idmap_ldap_init(void)
1537
1152
{
1538
 
        NTSTATUS ret;
1539
 
 
1540
 
        /* FIXME: bad hack to actually register also the alloc_ldap module
1541
 
         * without changining configure.in */
1542
 
        ret = idmap_alloc_ldap_init();
1543
 
        if (! NT_STATUS_IS_OK(ret)) {
1544
 
                return ret;
1545
 
        }
1546
1153
        return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap",
1547
1154
                                  &idmap_ldap_methods);
1548
1155
}