~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source3/winbindd/idmap_autorid.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:
 
1
/*
 
2
 *  idmap_autorid: static map between Active Directory/NT RIDs
 
3
 *  and RFC 2307 accounts
 
4
 *
 
5
 *  based on the idmap_rid module, but this module defines the ranges
 
6
 *  for the domains by automatically allocating a range for each domain
 
7
 *
 
8
 *  Copyright (C) Christian Ambach, 2010-2011
 
9
 *
 
10
 *  This program is free software; you can redistribute it and/or modify
 
11
 *  it under the terms of the GNU General Public License as published by
 
12
 *  the Free Software Foundation; either version 3 of the License, or
 
13
 *  (at your option) any later version.
 
14
 *
 
15
 *  This program is distributed in the hope that it will be useful,
 
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 *  GNU General Public License for more details.
 
19
 *
 
20
 *  You should have received a copy of the GNU General Public License
 
21
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 
22
 *
 
23
 */
 
24
 
 
25
#include "includes.h"
 
26
#include "system/filesys.h"
 
27
#include "winbindd.h"
 
28
#include "dbwrap.h"
 
29
#include "idmap.h"
 
30
#include "../libcli/security/dom_sid.h"
 
31
#include "util_tdb.h"
 
32
 
 
33
#undef DBGC_CLASS
 
34
#define DBGC_CLASS DBGC_IDMAP
 
35
 
 
36
#define HWM "NEXT RANGE"
 
37
#define CONFIGKEY "CONFIG"
 
38
 
 
39
struct autorid_global_config {
 
40
        uint32_t minvalue;
 
41
        uint32_t rangesize;
 
42
        uint32_t maxranges;
 
43
};
 
44
 
 
45
struct autorid_domain_config {
 
46
        struct dom_sid sid;
 
47
        uint32_t domainnum;
 
48
        struct autorid_global_config *globalcfg;
 
49
};
 
50
 
 
51
/* handle to the tdb storing domain <-> range assignments */
 
52
static struct db_context *autorid_db;
 
53
 
 
54
static NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
 
55
                                              void *private_data)
 
56
{
 
57
        NTSTATUS ret;
 
58
        uint32_t domainnum, hwm;
 
59
        fstring sidstr;
 
60
        char *numstr;
 
61
        struct autorid_domain_config *cfg;
 
62
 
 
63
        cfg = (struct autorid_domain_config *)private_data;
 
64
        dom_sid_string_buf(&(cfg->sid), sidstr, sizeof(sidstr));
 
65
 
 
66
        if (!dbwrap_fetch_uint32(db, sidstr, &domainnum)) {
 
67
                DEBUG(10, ("Acquiring new range for domain %s\n", sidstr));
 
68
 
 
69
                /* fetch the current HWM */
 
70
                if (!dbwrap_fetch_uint32(db, HWM, &hwm)) {
 
71
                        DEBUG(1, ("Fatal error while fetching current "
 
72
                                  "HWM value!\n"));
 
73
                        ret = NT_STATUS_INTERNAL_ERROR;
 
74
                        goto error;
 
75
                }
 
76
 
 
77
                /* do we have a range left? */
 
78
                if (hwm >= cfg->globalcfg->maxranges) {
 
79
                        DEBUG(1, ("No more domain ranges available!\n"));
 
80
                        ret = NT_STATUS_NO_MEMORY;
 
81
                        goto error;
 
82
                }
 
83
 
 
84
                /* increase the HWM */
 
85
                ret = dbwrap_change_uint32_atomic(db, HWM, &domainnum, 1);
 
86
                if (!NT_STATUS_IS_OK(ret)) {
 
87
                        DEBUG(1, ("Fatal error while fetching a new "
 
88
                                  "domain range value!\n"));
 
89
                        goto error;
 
90
                }
 
91
 
 
92
                /* store away the new mapping in both directions */
 
93
                ret = dbwrap_trans_store_uint32(db, sidstr, domainnum);
 
94
                if (!NT_STATUS_IS_OK(ret)) {
 
95
                        DEBUG(1, ("Fatal error while storing new "
 
96
                                  "domain->range assignment!\n"));
 
97
                        goto error;
 
98
                }
 
99
 
 
100
                numstr = talloc_asprintf(db, "%u", domainnum);
 
101
                if (!numstr) {
 
102
                        ret = NT_STATUS_NO_MEMORY;
 
103
                        goto error;
 
104
                }
 
105
 
 
106
                ret = dbwrap_trans_store_bystring(db, numstr,
 
107
                                                  string_term_tdb_data(sidstr),
 
108
                                                  TDB_INSERT);
 
109
                talloc_free(numstr);
 
110
                if (!NT_STATUS_IS_OK(ret)) {
 
111
                        DEBUG(1, ("Fatal error while storing "
 
112
                                  "new domain->range assignment!\n"));
 
113
                        goto error;
 
114
                }
 
115
                DEBUG(5, ("Acquired new range #%d for domain %s\n",
 
116
                          domainnum, sidstr));
 
117
        }
 
118
 
 
119
        DEBUG(10, ("Using range #%d for domain %s\n", domainnum, sidstr));
 
120
        cfg->domainnum = domainnum;
 
121
 
 
122
        return NT_STATUS_OK;
 
123
 
 
124
      error:
 
125
        return ret;
 
126
 
 
127
}
 
128
 
 
129
static NTSTATUS idmap_autorid_id_to_sid(struct autorid_global_config *cfg,
 
130
                                        struct id_map *map)
 
131
{
 
132
        uint32_t range;
 
133
        TDB_DATA data;
 
134
        char *keystr;
 
135
        struct dom_sid sid;
 
136
 
 
137
        /* can this be one of our ids? */
 
138
        if (map->xid.id < cfg->minvalue) {
 
139
                DEBUG(10, ("id %d is lower than minimum value, "
 
140
                           "ignoring mapping request\n", map->xid.id));
 
141
                map->status = ID_UNKNOWN;
 
142
                return NT_STATUS_OK;
 
143
        }
 
144
 
 
145
        if (map->xid.id > (cfg->minvalue + cfg->rangesize * cfg->maxranges)) {
 
146
                DEBUG(10, ("id %d is outside of maximum id value, "
 
147
                           "ignoring mapping request\n", map->xid.id));
 
148
                map->status = ID_UNKNOWN;
 
149
                return NT_STATUS_OK;
 
150
        }
 
151
 
 
152
        /* determine the range of this uid */
 
153
        range = ((map->xid.id - cfg->minvalue) / cfg->rangesize);
 
154
 
 
155
        keystr = talloc_asprintf(talloc_tos(), "%u", range);
 
156
        if (!keystr) {
 
157
                return NT_STATUS_NO_MEMORY;
 
158
        }
 
159
 
 
160
        data = dbwrap_fetch_bystring(autorid_db, talloc_tos(), keystr);
 
161
        TALLOC_FREE(keystr);
 
162
 
 
163
        if (!data.dptr) {
 
164
                DEBUG(4, ("id %d belongs to range %d which does not have "
 
165
                          "domain mapping, ignoring mapping request\n",
 
166
                          map->xid.id, range));
 
167
                map->status = ID_UNKNOWN;
 
168
                return NT_STATUS_OK;
 
169
        }
 
170
 
 
171
        string_to_sid(&sid, (const char *)data.dptr);
 
172
        TALLOC_FREE(data.dptr);
 
173
 
 
174
        sid_compose(map->sid, &sid,
 
175
                    (map->xid.id - cfg->minvalue -
 
176
                     range * cfg->rangesize));
 
177
 
 
178
        /* We **really** should have some way of validating
 
179
           the SID exists and is the correct type here.  But
 
180
           that is a deficiency in the idmap_rid design. */
 
181
 
 
182
        map->status = ID_MAPPED;
 
183
        return NT_STATUS_OK;
 
184
}
 
185
 
 
186
/**********************************
 
187
 Single sid to id lookup function.
 
188
**********************************/
 
189
 
 
190
static NTSTATUS idmap_autorid_sid_to_id(struct autorid_global_config *global,
 
191
                                        struct autorid_domain_config *domain,
 
192
                                        struct id_map *map)
 
193
{
 
194
        uint32_t rid;
 
195
 
 
196
        sid_peek_rid(map->sid, &rid);
 
197
 
 
198
        /* if the rid is higher than the size of the range, we cannot map it */
 
199
        if (rid >= global->rangesize) {
 
200
                map->status = ID_UNKNOWN;
 
201
                DEBUG(2, ("RID %d is larger then size of range (%d), "
 
202
                          "user cannot be mapped\n", rid, global->rangesize));
 
203
                return NT_STATUS_UNSUCCESSFUL;
 
204
        }
 
205
        map->xid.id = global->minvalue +
 
206
            (global->rangesize * domain->domainnum)+rid;
 
207
 
 
208
        /* We **really** should have some way of validating
 
209
           the SID exists and is the correct type here.  But
 
210
           that is a deficiency in the idmap_rid design. */
 
211
 
 
212
        map->status = ID_MAPPED;
 
213
 
 
214
        return NT_STATUS_OK;
 
215
}
 
216
 
 
217
/**********************************
 
218
 lookup a set of unix ids.
 
219
**********************************/
 
220
 
 
221
static NTSTATUS idmap_autorid_unixids_to_sids(struct idmap_domain *dom,
 
222
                                              struct id_map **ids)
 
223
{
 
224
        struct autorid_global_config *globalcfg;
 
225
        NTSTATUS ret;
 
226
        int i;
 
227
 
 
228
        /* initialize the status to avoid surprise */
 
229
        for (i = 0; ids[i]; i++) {
 
230
                ids[i]->status = ID_UNKNOWN;
 
231
        }
 
232
 
 
233
        globalcfg = talloc_get_type(dom->private_data,
 
234
                                    struct autorid_global_config);
 
235
 
 
236
        for (i = 0; ids[i]; i++) {
 
237
 
 
238
                ret = idmap_autorid_id_to_sid(globalcfg, ids[i]);
 
239
 
 
240
                if ((!NT_STATUS_IS_OK(ret)) &&
 
241
                    (!NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED))) {
 
242
                        /* some fatal error occurred, log it */
 
243
                        DEBUG(3, ("Unexpected error resolving an ID "
 
244
                                  " (%d)\n", ids[i]->xid.id));
 
245
                        goto failure;
 
246
                }
 
247
        }
 
248
        return NT_STATUS_OK;
 
249
 
 
250
      failure:
 
251
        return ret;
 
252
}
 
253
 
 
254
/**********************************
 
255
 lookup a set of sids.
 
256
**********************************/
 
257
 
 
258
static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom,
 
259
                                              struct id_map **ids)
 
260
{
 
261
        struct autorid_global_config *global;
 
262
        NTSTATUS ret;
 
263
        int i;
 
264
 
 
265
        /* initialize the status to avoid surprise */
 
266
        for (i = 0; ids[i]; i++) {
 
267
                ids[i]->status = ID_UNKNOWN;
 
268
        }
 
269
 
 
270
        global = talloc_get_type(dom->private_data,
 
271
                                 struct autorid_global_config);
 
272
 
 
273
        for (i = 0; ids[i]; i++) {
 
274
                struct winbindd_tdc_domain *domain;
 
275
                struct autorid_domain_config domaincfg;
 
276
                uint32_t rid;
 
277
 
 
278
                ZERO_STRUCT(domaincfg);
 
279
 
 
280
                sid_copy(&domaincfg.sid, ids[i]->sid);
 
281
                if (!sid_split_rid(&domaincfg.sid, &rid)) {
 
282
                        DEBUG(4, ("Could not determine domain SID from %s, "
 
283
                                  "ignoring mapping request\n",
 
284
                                  sid_string_dbg(ids[i]->sid)));
 
285
                        continue;
 
286
                }
 
287
 
 
288
                /*
 
289
                 * Check if the domain is around
 
290
                 */
 
291
                domain = wcache_tdc_fetch_domainbysid(talloc_tos(),
 
292
                                                      &domaincfg.sid);
 
293
                if (domain == NULL) {
 
294
                        DEBUG(10, ("Ignoring unknown domain sid %s\n",
 
295
                                   sid_string_dbg(&domaincfg.sid)));
 
296
                        continue;
 
297
                }
 
298
                TALLOC_FREE(domain);
 
299
 
 
300
                domaincfg.globalcfg = global;
 
301
 
 
302
                ret = dbwrap_trans_do(autorid_db,
 
303
                                      idmap_autorid_get_domainrange,
 
304
                                      &domaincfg);
 
305
 
 
306
                if (!NT_STATUS_IS_OK(ret)) {
 
307
                        DEBUG(3, ("Could not determine range for domain, "
 
308
                                  "check previous messages for reason\n"));
 
309
                        goto failure;
 
310
                }
 
311
 
 
312
                ret = idmap_autorid_sid_to_id(global, &domaincfg, ids[i]);
 
313
 
 
314
                if ((!NT_STATUS_IS_OK(ret)) &&
 
315
                    (!NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED))) {
 
316
                        /* some fatal error occurred, log it */
 
317
                        DEBUG(3, ("Unexpected error resolving a SID (%s)\n",
 
318
                                  sid_string_dbg(ids[i]->sid)));
 
319
                        goto failure;
 
320
                }
 
321
        }
 
322
        return NT_STATUS_OK;
 
323
 
 
324
      failure:
 
325
        return ret;
 
326
 
 
327
}
 
328
 
 
329
/*
 
330
 * open and initialize the database which stores the ranges for the domains
 
331
 */
 
332
static NTSTATUS idmap_autorid_db_init(void)
 
333
{
 
334
        int32_t hwm;
 
335
 
 
336
        if (autorid_db) {
 
337
                /* its already open */
 
338
                return NT_STATUS_OK;
 
339
        }
 
340
 
 
341
        /* Open idmap repository */
 
342
        autorid_db = db_open(NULL, state_path("autorid.tdb"), 0,
 
343
                             TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
 
344
 
 
345
        if (!autorid_db) {
 
346
                DEBUG(0, ("Unable to open idmap_autorid database '%s'\n",
 
347
                          state_path("autorid.tdb")));
 
348
                return NT_STATUS_UNSUCCESSFUL;
 
349
        }
 
350
 
 
351
        /* Initialize high water mark for the currently used range to 0 */
 
352
        hwm = dbwrap_fetch_int32(autorid_db, HWM);
 
353
        if ((hwm < 0)) {
 
354
                if (!NT_STATUS_IS_OK
 
355
                    (dbwrap_trans_store_int32(autorid_db, HWM, 0))) {
 
356
                        DEBUG(0,
 
357
                              ("Unable to initialise HWM in autorid "
 
358
                               "database\n"));
 
359
                        return NT_STATUS_INTERNAL_DB_ERROR;
 
360
                }
 
361
        }
 
362
 
 
363
        return NT_STATUS_OK;
 
364
}
 
365
 
 
366
static struct autorid_global_config *idmap_autorid_loadconfig(TALLOC_CTX * ctx)
 
367
{
 
368
 
 
369
        TDB_DATA data;
 
370
        struct autorid_global_config *cfg;
 
371
        unsigned long minvalue, rangesize, maxranges;
 
372
 
 
373
        data = dbwrap_fetch_bystring(autorid_db, ctx, CONFIGKEY);
 
374
 
 
375
        if (!data.dptr) {
 
376
                DEBUG(10, ("No saved config found\n"));
 
377
                return NULL;
 
378
        }
 
379
 
 
380
        cfg = TALLOC_ZERO_P(ctx, struct autorid_global_config);
 
381
        if (!cfg) {
 
382
                return NULL;
 
383
        }
 
384
 
 
385
        if (sscanf((char *)data.dptr,
 
386
                   "minvalue:%lu rangesize:%lu maxranges:%lu",
 
387
                   &minvalue, &rangesize, &maxranges) != 3) {
 
388
                DEBUG(1,
 
389
                      ("Found invalid configuration data"
 
390
                       "creating new config\n"));
 
391
                return NULL;
 
392
        }
 
393
 
 
394
        cfg->minvalue = minvalue;
 
395
        cfg->rangesize = rangesize;
 
396
        cfg->maxranges = maxranges;
 
397
 
 
398
        DEBUG(10, ("Loaded previously stored configuration "
 
399
                   "minvalue:%d rangesize:%d\n",
 
400
                   cfg->minvalue, cfg->rangesize));
 
401
 
 
402
        return cfg;
 
403
 
 
404
}
 
405
 
 
406
static NTSTATUS idmap_autorid_saveconfig(struct autorid_global_config *cfg)
 
407
{
 
408
 
 
409
        NTSTATUS status;
 
410
        TDB_DATA data;
 
411
        char *cfgstr;
 
412
 
 
413
        cfgstr =
 
414
            talloc_asprintf(talloc_tos(),
 
415
                            "minvalue:%u rangesize:%u maxranges:%u",
 
416
                            cfg->minvalue, cfg->rangesize, cfg->maxranges);
 
417
 
 
418
        if (!cfgstr) {
 
419
                return NT_STATUS_NO_MEMORY;
 
420
        }
 
421
 
 
422
        data = string_tdb_data(cfgstr);
 
423
 
 
424
        status = dbwrap_trans_store_bystring(autorid_db, CONFIGKEY,
 
425
                                             data, TDB_REPLACE);
 
426
 
 
427
        talloc_free(cfgstr);
 
428
 
 
429
        return status;
 
430
}
 
431
 
 
432
static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
 
433
{
 
434
        struct autorid_global_config *config;
 
435
        struct autorid_global_config *storedconfig = NULL;
 
436
        NTSTATUS status;
 
437
        uint32_t hwm;
 
438
 
 
439
        if (!strequal(dom->name, "*")) {
 
440
                DEBUG(0, ("idmap_autorid_initialize: Error: autorid configured "
 
441
                          "for domain '%s'. But autorid can only be used for "
 
442
                          "the default idmap configuration.\n", dom->name));
 
443
                return NT_STATUS_INVALID_PARAMETER;
 
444
        }
 
445
 
 
446
        config = TALLOC_ZERO_P(dom, struct autorid_global_config);
 
447
        if (!config) {
 
448
                DEBUG(0, ("Out of memory!\n"));
 
449
                return NT_STATUS_NO_MEMORY;
 
450
        }
 
451
 
 
452
        status = idmap_autorid_db_init();
 
453
        if (!NT_STATUS_IS_OK(status)) {
 
454
                goto error;
 
455
        }
 
456
 
 
457
        config->minvalue = dom->low_id;
 
458
        config->rangesize = lp_parm_int(-1, "idmap config *", "rangesize", 100000);
 
459
 
 
460
        if (config->rangesize < 2000) {
 
461
                DEBUG(1, ("autorid rangesize must be at least 2000\n"));
 
462
                status = NT_STATUS_INVALID_PARAMETER;
 
463
                goto error;
 
464
        }
 
465
 
 
466
        config->maxranges = (dom->high_id - dom->low_id + 1) /
 
467
            config->rangesize;
 
468
 
 
469
        if (config->maxranges == 0) {
 
470
                DEBUG(1, ("allowed uid range is smaller then rangesize, "
 
471
                          "increase uid range or decrease rangesize\n"));
 
472
                status = NT_STATUS_INVALID_PARAMETER;
 
473
                goto error;
 
474
        }
 
475
 
 
476
        /* check if the high-low limit is a multiple of the rangesize */
 
477
        if ((dom->high_id - dom->low_id + 1) % config->rangesize != 0) {
 
478
                DEBUG(5, ("High uid-low uid difference of %d "
 
479
                          "is not a multiple of the rangesize %d, "
 
480
                          "limiting ranges to lower boundary number of %d\n",
 
481
                          (dom->high_id - dom->low_id + 1), config->rangesize,
 
482
                          config->maxranges));
 
483
        }
 
484
 
 
485
        DEBUG(10, ("Current configuration in config is "
 
486
                   "minvalue:%d rangesize:%d maxranges:%d\n",
 
487
                   config->minvalue, config->rangesize, config->maxranges));
 
488
 
 
489
        /* read previously stored config and current HWM */
 
490
        storedconfig = idmap_autorid_loadconfig(talloc_tos());
 
491
 
 
492
        if (!dbwrap_fetch_uint32(autorid_db, HWM, &hwm)) {
 
493
                DEBUG(1, ("Fatal error while fetching current "
 
494
                          "HWM value!\n"));
 
495
                status = NT_STATUS_INTERNAL_ERROR;
 
496
                goto error;
 
497
        }
 
498
 
 
499
        /* did the minimum value or rangesize change? */
 
500
        if (storedconfig &&
 
501
            ((storedconfig->minvalue != config->minvalue) ||
 
502
             (storedconfig->rangesize != config->rangesize))) {
 
503
                DEBUG(1, ("New configuration values for rangesize or "
 
504
                          "minimum uid value conflict with previously "
 
505
                          "used values! Aborting initialization\n"));
 
506
                status = NT_STATUS_INVALID_PARAMETER;
 
507
                goto error;
 
508
        }
 
509
 
 
510
        /*
 
511
         * has the highest uid value been reduced to setting that is not
 
512
         * sufficient any more for already existing ranges?
 
513
         */
 
514
        if (hwm > config->maxranges) {
 
515
                DEBUG(1, ("New upper uid limit is too low to cover "
 
516
                          "existing mappings! Aborting initialization\n"));
 
517
                status = NT_STATUS_INVALID_PARAMETER;
 
518
                goto error;
 
519
        }
 
520
 
 
521
        status = idmap_autorid_saveconfig(config);
 
522
 
 
523
        if (!NT_STATUS_IS_OK(status)) {
 
524
                DEBUG(1, ("Failed to store configuration data!\n"));
 
525
                goto error;
 
526
        }
 
527
 
 
528
        DEBUG(5, ("%d domain ranges with a size of %d are available\n",
 
529
                  config->maxranges, config->rangesize));
 
530
 
 
531
        dom->private_data = config;
 
532
 
 
533
        goto done;
 
534
 
 
535
error:
 
536
        talloc_free(config);
 
537
 
 
538
done:
 
539
        talloc_free(storedconfig);
 
540
 
 
541
        return status;
 
542
}
 
543
 
 
544
/*
 
545
  Close the idmap tdb instance
 
546
*/
 
547
static struct idmap_methods autorid_methods = {
 
548
        .init = idmap_autorid_initialize,
 
549
        .unixids_to_sids = idmap_autorid_unixids_to_sids,
 
550
        .sids_to_unixids = idmap_autorid_sids_to_unixids,
 
551
};
 
552
 
 
553
NTSTATUS idmap_autorid_init(void)
 
554
{
 
555
        return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
 
556
                                  "autorid", &autorid_methods);
 
557
}