~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source3/lib/util_tdb.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:
20
20
*/
21
21
 
22
22
#include "includes.h"
 
23
#include "system/filesys.h"
 
24
#include "util_tdb.h"
 
25
 
23
26
#undef malloc
24
27
#undef realloc
25
28
#undef calloc
34
37
 Signal function to tell us we timed out.
35
38
****************************************************************/
36
39
 
37
 
static void gotalarm_sig(void)
 
40
static void gotalarm_sig(int signum)
38
41
{
39
42
        gotalarm = 1;
40
43
}
50
53
        gotalarm = 0;
51
54
 
52
55
        if (timeout) {
53
 
                CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
 
56
                CatchSignal(SIGALRM, gotalarm_sig);
54
57
                tdb_setalarm_sigptr(tdb, &gotalarm);
55
58
                alarm(timeout);
56
59
        }
63
66
        if (timeout) {
64
67
                alarm(0);
65
68
                tdb_setalarm_sigptr(tdb, NULL);
66
 
                CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
 
69
                CatchSignal(SIGALRM, SIG_IGN);
67
70
                if (gotalarm && (ret == -1)) {
68
71
                        DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n",
69
72
                                timeout, key.dptr, tdb_name(tdb)));
481
484
        return res;
482
485
}
483
486
 
484
 
/*
485
 
 Log tdb messages via DEBUG().
486
 
*/
487
 
static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, 
488
 
                         const char *format, ...) PRINTF_ATTRIBUTE(3,4);
489
 
 
490
 
static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, 
491
 
                         const char *format, ...)
492
 
{
493
 
        va_list ap;
494
 
        char *ptr = NULL;
495
 
        int debuglevel = 0;
496
 
        int ret;
497
 
 
498
 
        switch (level) {
499
 
        case TDB_DEBUG_FATAL:
500
 
                debuglevel = 0;
501
 
                break;
502
 
        case TDB_DEBUG_ERROR:
503
 
                debuglevel = 1;
504
 
                break;
505
 
        case TDB_DEBUG_WARNING:
506
 
                debuglevel = 2;
507
 
                break;
508
 
        case TDB_DEBUG_TRACE:
509
 
                debuglevel = 5;
510
 
                break;
511
 
        default:
512
 
                debuglevel = 0;
513
 
        }               
514
 
 
515
 
        va_start(ap, format);
516
 
        ret = vasprintf(&ptr, format, ap);
517
 
        va_end(ap);
518
 
 
519
 
        if (ret != -1) {
520
 
                const char *name = tdb_name(tdb);
521
 
                DEBUG(debuglevel, ("tdb(%s): %s", name ? name : "unnamed", ptr));
522
 
                free(ptr);
523
 
        }
524
 
}
525
 
 
526
 
static struct tdb_wrap *tdb_list;
527
 
 
528
 
/* destroy the last connection to a tdb */
529
 
static int tdb_wrap_destructor(struct tdb_wrap *w)
530
 
{
531
 
        tdb_close(w->tdb);
532
 
        DLIST_REMOVE(tdb_list, w);
533
 
        return 0;
534
 
}                                
535
 
 
536
 
/*
537
 
  wrapped connection to a tdb database
538
 
  to close just talloc_free() the tdb_wrap pointer
539
 
 */
540
 
struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,
541
 
                               const char *name, int hash_size, int tdb_flags,
542
 
                               int open_flags, mode_t mode)
543
 
{
544
 
        struct tdb_wrap *w;
545
 
        struct tdb_logging_context log_ctx;
546
 
        log_ctx.log_fn = tdb_wrap_log;
547
 
 
548
 
        if (!lp_use_mmap())
549
 
                tdb_flags |= TDB_NOMMAP;
550
 
 
551
 
        for (w=tdb_list;w;w=w->next) {
552
 
                if (strcmp(name, w->name) == 0) {
553
 
                        /*
554
 
                         * Yes, talloc_reference is exactly what we want
555
 
                         * here. Otherwise we would have to implement our own
556
 
                         * reference counting.
557
 
                         */
558
 
                        return talloc_reference(mem_ctx, w);
559
 
                }
560
 
        }
561
 
 
562
 
        w = talloc(mem_ctx, struct tdb_wrap);
563
 
        if (w == NULL) {
564
 
                return NULL;
565
 
        }
566
 
 
567
 
        if (!(w->name = talloc_strdup(w, name))) {
568
 
                talloc_free(w);
569
 
                return NULL;
570
 
        }
571
 
 
572
 
        if ((hash_size == 0) && (name != NULL)) {
573
 
                const char *base = strrchr_m(name, '/');
574
 
                if (base != NULL) {
575
 
                        base += 1;
576
 
                }
577
 
                else {
578
 
                        base = name;
579
 
                }
580
 
                hash_size = lp_parm_int(-1, "tdb_hashsize", base, 0);
581
 
        }
582
 
 
583
 
        w->tdb = tdb_open_ex(name, hash_size, tdb_flags, 
584
 
                             open_flags, mode, &log_ctx, NULL);
585
 
        if (w->tdb == NULL) {
586
 
                talloc_free(w);
587
 
                return NULL;
588
 
        }
589
 
 
590
 
        talloc_set_destructor(w, tdb_wrap_destructor);
591
 
 
592
 
        DLIST_ADD(tdb_list, w);
593
 
 
594
 
        return w;
595
 
}
596
 
 
597
487
NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err)
598
488
{
599
 
        struct { enum TDB_ERROR err; NTSTATUS status; } map[] =
600
 
                { { TDB_SUCCESS,        NT_STATUS_OK },
601
 
                  { TDB_ERR_CORRUPT,    NT_STATUS_INTERNAL_DB_CORRUPTION },
602
 
                  { TDB_ERR_IO,         NT_STATUS_UNEXPECTED_IO_ERROR },
603
 
                  { TDB_ERR_OOM,        NT_STATUS_NO_MEMORY },
604
 
                  { TDB_ERR_EXISTS,     NT_STATUS_OBJECT_NAME_COLLISION },
605
 
 
606
 
                  /*
607
 
                   * TDB_ERR_LOCK is very broad, we could for example
608
 
                   * distinguish between fcntl locks and invalid lock
609
 
                   * sequences. So NT_STATUS_FILE_LOCK_CONFLICT is a
610
 
                   * compromise.
611
 
                   */
612
 
                  { TDB_ERR_LOCK,       NT_STATUS_FILE_LOCK_CONFLICT },
613
 
                  /*
614
 
                   * The next two ones in the enum are not actually used
615
 
                   */
616
 
                  { TDB_ERR_NOLOCK,     NT_STATUS_FILE_LOCK_CONFLICT },
617
 
                  { TDB_ERR_LOCK_TIMEOUT, NT_STATUS_FILE_LOCK_CONFLICT },
618
 
                  { TDB_ERR_NOEXIST,    NT_STATUS_NOT_FOUND },
619
 
                  { TDB_ERR_EINVAL,     NT_STATUS_INVALID_PARAMETER },
620
 
                  { TDB_ERR_RDONLY,     NT_STATUS_ACCESS_DENIED }
621
 
                };
622
 
 
623
 
        int i;
624
 
 
625
 
        for (i=0; i < sizeof(map) / sizeof(map[0]); i++) {
626
 
                if (err == map[i].err) {
627
 
                        return map[i].status;
628
 
                }
629
 
        }
630
 
 
631
 
        return NT_STATUS_INTERNAL_ERROR;
 
489
        NTSTATUS result = NT_STATUS_INTERNAL_ERROR;
 
490
 
 
491
        switch (err) {
 
492
        case TDB_SUCCESS:
 
493
                result = NT_STATUS_OK;
 
494
                break;
 
495
        case TDB_ERR_CORRUPT:
 
496
                result = NT_STATUS_INTERNAL_DB_CORRUPTION;
 
497
                break;
 
498
        case TDB_ERR_IO:
 
499
                result = NT_STATUS_UNEXPECTED_IO_ERROR;
 
500
                break;
 
501
        case TDB_ERR_OOM:
 
502
                result = NT_STATUS_NO_MEMORY;
 
503
                break;
 
504
        case TDB_ERR_EXISTS:
 
505
                result = NT_STATUS_OBJECT_NAME_COLLISION;
 
506
                break;
 
507
 
 
508
        case TDB_ERR_LOCK:
 
509
                /*
 
510
                 * TDB_ERR_LOCK is very broad, we could for example
 
511
                 * distinguish between fcntl locks and invalid lock
 
512
                 * sequences. So NT_STATUS_FILE_LOCK_CONFLICT is a
 
513
                 * compromise.
 
514
                 */
 
515
                result = NT_STATUS_FILE_LOCK_CONFLICT;
 
516
                break;
 
517
 
 
518
        case TDB_ERR_NOLOCK:
 
519
        case TDB_ERR_LOCK_TIMEOUT:
 
520
                /*
 
521
                 * These two ones in the enum are not actually used
 
522
                 */
 
523
                result = NT_STATUS_FILE_LOCK_CONFLICT;
 
524
                break;
 
525
        case TDB_ERR_NOEXIST:
 
526
                result = NT_STATUS_NOT_FOUND;
 
527
                break;
 
528
        case TDB_ERR_EINVAL:
 
529
                result = NT_STATUS_INVALID_PARAMETER;
 
530
                break;
 
531
        case TDB_ERR_RDONLY:
 
532
                result = NT_STATUS_ACCESS_DENIED;
 
533
                break;
 
534
        case TDB_ERR_NESTING:
 
535
                result = NT_STATUS_INTERNAL_ERROR;
 
536
                break;
 
537
        };
 
538
        return result;
632
539
}
633
540
 
634
541
int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2)