~ubuntu-branches/ubuntu/quantal/samba/quantal

« back to all changes in this revision

Viewing changes to source3/winbindd/idmap_autorid.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-02-21 09:06:34 UTC
  • mfrom: (0.39.23 sid)
  • Revision ID: package-import@ubuntu.com-20120221090634-svd7q7m33pfz0847
Tags: 2:3.6.3-1ubuntu1
* 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/fix-samba-printer-browsing.patch: No longer needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#define DBGC_CLASS DBGC_IDMAP
35
35
 
36
36
#define HWM "NEXT RANGE"
 
37
#define ALLOC_HWM_UID "NEXT ALLOC UID"
 
38
#define ALLOC_HWM_GID "NEXT ALLOC GID"
 
39
#define ALLOC_RANGE "ALLOC"
37
40
#define CONFIGKEY "CONFIG"
38
41
 
39
42
struct autorid_global_config {
43
46
};
44
47
 
45
48
struct autorid_domain_config {
46
 
        struct dom_sid sid;
 
49
        fstring sid;
47
50
        uint32_t domainnum;
48
51
        struct autorid_global_config *globalcfg;
49
52
};
56
59
{
57
60
        NTSTATUS ret;
58
61
        uint32_t domainnum, hwm;
59
 
        fstring sidstr;
60
62
        char *numstr;
61
63
        struct autorid_domain_config *cfg;
62
64
 
63
65
        cfg = (struct autorid_domain_config *)private_data;
64
 
        dom_sid_string_buf(&(cfg->sid), sidstr, sizeof(sidstr));
65
66
 
66
 
        if (!dbwrap_fetch_uint32(db, sidstr, &domainnum)) {
67
 
                DEBUG(10, ("Acquiring new range for domain %s\n", sidstr));
 
67
        if (!dbwrap_fetch_uint32(db, cfg->sid, &domainnum)) {
 
68
                DEBUG(10, ("Acquiring new range for domain %s\n", cfg->sid));
68
69
 
69
70
                /* fetch the current HWM */
70
71
                if (!dbwrap_fetch_uint32(db, HWM, &hwm)) {
90
91
                }
91
92
 
92
93
                /* store away the new mapping in both directions */
93
 
                ret = dbwrap_trans_store_uint32(db, sidstr, domainnum);
 
94
                ret = dbwrap_trans_store_uint32(db, cfg->sid, domainnum);
94
95
                if (!NT_STATUS_IS_OK(ret)) {
95
96
                        DEBUG(1, ("Fatal error while storing new "
96
97
                                  "domain->range assignment!\n"));
104
105
                }
105
106
 
106
107
                ret = dbwrap_trans_store_bystring(db, numstr,
107
 
                                                  string_term_tdb_data(sidstr),
108
 
                                                  TDB_INSERT);
 
108
                                string_term_tdb_data(cfg->sid), TDB_INSERT);
 
109
 
109
110
                talloc_free(numstr);
110
111
                if (!NT_STATUS_IS_OK(ret)) {
111
112
                        DEBUG(1, ("Fatal error while storing "
113
114
                        goto error;
114
115
                }
115
116
                DEBUG(5, ("Acquired new range #%d for domain %s\n",
116
 
                          domainnum, sidstr));
 
117
                          domainnum, cfg->sid));
117
118
        }
118
119
 
119
 
        DEBUG(10, ("Using range #%d for domain %s\n", domainnum, sidstr));
 
120
        DEBUG(10, ("Using range #%d for domain %s\n", domainnum, cfg->sid));
120
121
        cfg->domainnum = domainnum;
121
122
 
122
123
        return NT_STATUS_OK;
164
165
                DEBUG(4, ("id %d belongs to range %d which does not have "
165
166
                          "domain mapping, ignoring mapping request\n",
166
167
                          map->xid.id, range));
 
168
                TALLOC_FREE(data.dptr);
 
169
                map->status = ID_UNKNOWN;
 
170
                return NT_STATUS_OK;
 
171
        }
 
172
 
 
173
        if (strncmp((const char *)data.dptr,
 
174
                    ALLOC_RANGE,
 
175
                    strlen(ALLOC_RANGE)) == 0) {
 
176
                /* this is from the alloc range, there is no mapping back */
 
177
                DEBUG(5, ("id %d belongs to alloc range, cannot map back\n",
 
178
                          map->xid.id));
 
179
                TALLOC_FREE(data.dptr);
167
180
                map->status = ID_UNKNOWN;
168
181
                return NT_STATUS_OK;
169
182
        }
274
287
                struct winbindd_tdc_domain *domain;
275
288
                struct autorid_domain_config domaincfg;
276
289
                uint32_t rid;
 
290
                struct dom_sid domainsid;
277
291
 
278
292
                ZERO_STRUCT(domaincfg);
279
293
 
280
 
                sid_copy(&domaincfg.sid, ids[i]->sid);
281
 
                if (!sid_split_rid(&domaincfg.sid, &rid)) {
 
294
                sid_copy(&domainsid, ids[i]->sid);
 
295
                if (!sid_split_rid(&domainsid, &rid)) {
282
296
                        DEBUG(4, ("Could not determine domain SID from %s, "
283
297
                                  "ignoring mapping request\n",
284
298
                                  sid_string_dbg(ids[i]->sid)));
289
303
                 * Check if the domain is around
290
304
                 */
291
305
                domain = wcache_tdc_fetch_domainbysid(talloc_tos(),
292
 
                                                      &domaincfg.sid);
 
306
                                                      &domainsid);
293
307
                if (domain == NULL) {
294
308
                        DEBUG(10, ("Ignoring unknown domain sid %s\n",
295
 
                                   sid_string_dbg(&domaincfg.sid)));
 
309
                                   sid_string_dbg(&domainsid)));
296
310
                        continue;
297
311
                }
298
312
                TALLOC_FREE(domain);
299
313
 
300
314
                domaincfg.globalcfg = global;
 
315
                sid_to_fstring(domaincfg.sid, &domainsid);
301
316
 
302
317
                ret = dbwrap_trans_do(autorid_db,
303
318
                                      idmap_autorid_get_domainrange,
326
341
 
327
342
}
328
343
 
 
344
/* initialize the given HWM to 0 if it does not exist yet */
 
345
static NTSTATUS idmap_autorid_init_hwm(const char *hwm) {
 
346
 
 
347
        NTSTATUS status;
 
348
        int32_t hwmval;
 
349
 
 
350
        hwmval = dbwrap_fetch_int32(autorid_db, hwm);
 
351
        if ((hwmval < 0))  {
 
352
                status = dbwrap_trans_store_int32(autorid_db, hwm, 0);
 
353
                if (!NT_STATUS_IS_OK(status)) {
 
354
                        DEBUG(0,
 
355
                              ("Unable to initialise HWM (%s) in autorid "
 
356
                               "database: %s\n", hwm, nt_errstr(status)));
 
357
                        return NT_STATUS_INTERNAL_DB_ERROR;
 
358
                }
 
359
        }
 
360
 
 
361
        return NT_STATUS_OK;
 
362
}
 
363
 
329
364
/*
330
365
 * open and initialize the database which stores the ranges for the domains
331
366
 */
332
367
static NTSTATUS idmap_autorid_db_init(void)
333
368
{
334
 
        int32_t hwm;
 
369
        NTSTATUS status;
335
370
 
336
371
        if (autorid_db) {
337
372
                /* its already open */
349
384
        }
350
385
 
351
386
        /* 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;
 
387
 
 
388
        status = idmap_autorid_init_hwm(HWM);
 
389
        NT_STATUS_NOT_OK_RETURN(status);
 
390
 
 
391
        status = idmap_autorid_init_hwm(ALLOC_HWM_UID);
 
392
        NT_STATUS_NOT_OK_RETURN(status);
 
393
 
 
394
        status = idmap_autorid_init_hwm(ALLOC_HWM_GID);
 
395
 
 
396
        return status;
364
397
}
365
398
 
366
399
static struct autorid_global_config *idmap_autorid_loadconfig(TALLOC_CTX * ctx)
541
574
        return status;
542
575
}
543
576
 
 
577
static NTSTATUS idmap_autorid_allocate_id(struct idmap_domain *dom,
 
578
                                          struct unixid *xid) {
 
579
 
 
580
        NTSTATUS ret;
 
581
        struct autorid_global_config *globalcfg;
 
582
        struct autorid_domain_config domaincfg;
 
583
        uint32_t hwm;
 
584
        const char *hwmkey;
 
585
 
 
586
        if (!strequal(dom->name, "*")) {
 
587
                DEBUG(3, ("idmap_autorid_allocate_id: "
 
588
                          "Refusing creation of mapping for domain'%s'. "
 
589
                          "Currently only supported for the default "
 
590
                          "domain \"*\".\n",
 
591
                           dom->name));
 
592
                return NT_STATUS_NOT_IMPLEMENTED;
 
593
        }
 
594
 
 
595
        if ((xid->type != ID_TYPE_UID) && (xid->type != ID_TYPE_GID)) {
 
596
                return NT_STATUS_INVALID_PARAMETER;
 
597
        }
 
598
 
 
599
 
 
600
        globalcfg = talloc_get_type(dom->private_data,
 
601
                                    struct autorid_global_config);
 
602
 
 
603
        /* fetch the range for the allocation pool */
 
604
 
 
605
        ZERO_STRUCT(domaincfg);
 
606
 
 
607
        domaincfg.globalcfg = globalcfg;
 
608
        fstrcpy(domaincfg.sid, ALLOC_RANGE);
 
609
 
 
610
        ret = dbwrap_trans_do(autorid_db,
 
611
                              idmap_autorid_get_domainrange,
 
612
                              &domaincfg);
 
613
        if (!NT_STATUS_IS_OK(ret)) {
 
614
                DEBUG(3, ("Could not determine range for allocation pool, "
 
615
                          "check previous messages for reason\n"));
 
616
                return ret;
 
617
        }
 
618
 
 
619
        /* fetch the current HWM */
 
620
        hwmkey = (xid->type==ID_TYPE_UID)?ALLOC_HWM_UID:ALLOC_HWM_GID;
 
621
 
 
622
        if (!dbwrap_fetch_uint32(autorid_db, hwmkey, &hwm)) {
 
623
                DEBUG(1, ("Failed to fetch current allocation HWM value: %s\n",
 
624
                          nt_errstr(ret)));
 
625
                return NT_STATUS_INTERNAL_ERROR;
 
626
        }
 
627
 
 
628
        if (hwm >= globalcfg->rangesize) {
 
629
                DEBUG(1, ("allocation range is depleted!\n"));
 
630
                return NT_STATUS_NO_MEMORY;
 
631
        }
 
632
 
 
633
        ret = dbwrap_change_uint32_atomic(autorid_db, hwmkey, &(xid->id), 1);
 
634
        if (!NT_STATUS_IS_OK(ret)) {
 
635
                DEBUG(1, ("Fatal error while allocating new ID!\n"));
 
636
                return ret;
 
637
        }
 
638
 
 
639
        xid->id = globalcfg->minvalue +
 
640
                  globalcfg->rangesize * domaincfg.domainnum +
 
641
                  xid->id;
 
642
 
 
643
        DEBUG(10, ("Returned new %s %d from allocation range\n",
 
644
                   (xid->type==ID_TYPE_UID)?"uid":"gid", xid->id));
 
645
 
 
646
        return ret;
 
647
}
 
648
 
544
649
/*
545
650
  Close the idmap tdb instance
546
651
*/
548
653
        .init = idmap_autorid_initialize,
549
654
        .unixids_to_sids = idmap_autorid_unixids_to_sids,
550
655
        .sids_to_unixids = idmap_autorid_sids_to_unixids,
 
656
        .allocate_id     = idmap_autorid_allocate_id
551
657
};
552
658
 
553
659
NTSTATUS idmap_autorid_init(void)