Ignore:
Timestamp:
May 27, 2009, 11:39:15 AM (16 years ago)
Author:
Herwig Bauernfeind
Message:

Update 3.2 branch to 3.2.9

Location:
branches/samba-3.2.x/source/passdb
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.2.x/source/passdb/lookup_sid.c

    r136 r233  
    805805                        /* This is a normal SID with rid component */
    806806                        if (!sid_split_rid(&sid, &rid)) {
    807                                 result = NT_STATUS_INVALID_PARAMETER;
     807                                result = NT_STATUS_INVALID_SID;
    808808                                goto fail;
    809809                        }
  • branches/samba-3.2.x/source/passdb/pdb_tdb.c

    r133 r233  
    55 * Copyright (C) Simo Sorce        2000-2003
    66 * Copyright (C) Gerald Carter     2000-2006
    7  * Copyright (C) Jeremy Allison    2001
     7 * Copyright (C) Jeremy Allison    2001-2009
    88 * Copyright (C) Andrew Bartlett   2002
    99 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
     
    3939
    4040#define TDBSAM_VERSION  3       /* Most recent TDBSAM version */
     41#define TDBSAM_MINOR_VERSION    1       /* Most recent TDBSAM minor version */
    4142#define TDBSAM_VERSION_STRING   "INFO/version"
     43#define TDBSAM_MINOR_VERSION_STRING     "INFO/minor_version"
    4244#define PASSDB_FILE_NAME        "passdb.tdb"
    4345#define USERPREFIX              "USER_"
     
    688690
    689691/**********************************************************************
    690  Intialize a BYTE buffer from a struct samu struct
     692 Struct and function to update an old record.
    691693 *********************************************************************/
    692694
     
    773775}
    774776
    775 static bool tdbsam_convert(struct db_context *db, int32 from)
     777/**********************************************************************
     778 Struct and function to backup an old record.
     779 *********************************************************************/
     780
     781struct tdbsam_backup_state {
     782        struct db_context *new_db;
     783        bool success;
     784};
     785
     786static int backup_copy_fn(struct db_record *orig_rec, void *state)
     787{
     788        struct tdbsam_backup_state *bs = (struct tdbsam_backup_state *)state;
     789        struct db_record *new_rec;
     790        NTSTATUS status;
     791
     792        new_rec = bs->new_db->fetch_locked(bs->new_db, talloc_tos(), orig_rec->key);
     793        if (new_rec == NULL) {
     794                bs->success = false;
     795                return 1;
     796        }
     797
     798        status = new_rec->store(new_rec, orig_rec->value, TDB_INSERT);
     799
     800        TALLOC_FREE(new_rec);
     801
     802        if (!NT_STATUS_IS_OK(status)) {
     803                bs->success = false;
     804                return 1;
     805        }
     806        return 0;
     807}
     808
     809/**********************************************************************
     810 Make a backup of an old passdb and replace the new one with it. We
     811 have to do this as between 3.0.x and 3.2.x the hash function changed
     812 by mistake (used unsigned char * instead of char *). This means the
     813 previous simple update code will fail due to not being able to find
     814 existing records to replace in the tdbsam_convert_one() function. JRA.
     815 *********************************************************************/
     816
     817static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
     818{
     819        TALLOC_CTX *frame = talloc_stackframe();
     820        const char *tmp_fname = NULL;
     821        struct db_context *tmp_db = NULL;
     822        struct db_context *orig_db = *pp_db;
     823        struct tdbsam_backup_state bs;
     824        int ret;
     825
     826        tmp_fname = talloc_asprintf(frame, "%s.tmp", dbname);
     827        if (!tmp_fname) {
     828                TALLOC_FREE(frame);
     829                return false;
     830        }
     831
     832        unlink(tmp_fname);
     833
     834        /* Remember to open this on the NULL context. We need
     835         * it to stay around after we return from here. */
     836
     837        tmp_db = db_open_trans(NULL, tmp_fname, 0,
     838                                TDB_DEFAULT, O_CREAT|O_RDWR, 0600);
     839        if (tmp_db == NULL) {
     840                DEBUG(0, ("tdbsam_convert_backup: Failed to create backup TDB passwd "
     841                          "[%s]\n", tmp_fname));
     842                TALLOC_FREE(frame);
     843                return false;
     844        }
     845
     846        if (orig_db->transaction_start(orig_db) != 0) {
     847                DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (1)\n"));
     848                unlink(tmp_fname);
     849                TALLOC_FREE(tmp_db);
     850                TALLOC_FREE(frame);
     851                return false;
     852        }
     853        if (tmp_db->transaction_start(tmp_db) != 0) {
     854                DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (2)\n"));
     855                orig_db->transaction_cancel(orig_db);
     856                unlink(tmp_fname);
     857                TALLOC_FREE(tmp_db);
     858                TALLOC_FREE(frame);
     859                return false;
     860        }
     861
     862        bs.new_db = tmp_db;
     863        bs.success = true;
     864
     865        ret = orig_db->traverse(orig_db, backup_copy_fn, (void *)&bs);
     866        if (ret < 0) {
     867                DEBUG(0, ("tdbsam_convert_backup: traverse failed\n"));
     868                goto cancel;
     869        }
     870
     871        if (!bs.success) {
     872                DEBUG(0, ("tdbsam_convert_backup: Rewriting records failed\n"));
     873                goto cancel;
     874        }
     875
     876        if (orig_db->transaction_commit(orig_db) != 0) {
     877                smb_panic("tdbsam_convert_backup: orig commit failed\n");
     878        }
     879        if (tmp_db->transaction_commit(tmp_db) != 0) {
     880                smb_panic("tdbsam_convert_backup: orig commit failed\n");
     881        }
     882
     883        /* This is safe from other users as we know we're
     884         * under a mutex here. */
     885
     886        if (rename(tmp_fname, dbname) == -1) {
     887                DEBUG(0, ("tdbsam_convert_backup: rename of %s to %s failed %s\n",
     888                        tmp_fname,
     889                        dbname,
     890                        strerror(errno)));
     891                smb_panic("tdbsam_convert_backup: replace passdb failed\n");
     892        }
     893
     894        TALLOC_FREE(frame);
     895        TALLOC_FREE(orig_db);
     896
     897        DEBUG(1, ("tdbsam_convert_backup: updated %s file.\n",
     898                dbname ));
     899
     900        /* Replace the global db pointer. */
     901        *pp_db = tmp_db;
     902        return true;
     903
     904  cancel:
     905
     906        if (orig_db->transaction_cancel(orig_db) != 0) {
     907                smb_panic("tdbsam_convert: transaction_cancel failed");
     908        }
     909
     910        if (tmp_db->transaction_cancel(tmp_db) != 0) {
     911                smb_panic("tdbsam_convert: transaction_cancel failed");
     912        }
     913
     914        unlink(tmp_fname);
     915        TALLOC_FREE(tmp_db);
     916        TALLOC_FREE(frame);
     917        return false;
     918}
     919
     920static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 from)
    776921{
    777922        struct tdbsam_convert_state state;
     923        struct db_context *db = NULL;
    778924        int ret;
    779925
     926        /* We only need the update backup for local db's. */
     927        if (db_is_local(name) && !tdbsam_convert_backup(name, pp_db)) {
     928                DEBUG(0, ("tdbsam_convert: Could not backup %s\n", name));
     929                return false;
     930        }
     931
     932        db = *pp_db;
    780933        state.from = from;
    781934        state.success = true;
    782935
    783936        if (db->transaction_start(db) != 0) {
    784                 DEBUG(0, ("Could not start transaction\n"));
     937                DEBUG(0, ("tdbsam_convert: Could not start transaction\n"));
    785938                return false;
    786939        }
     
    788941        ret = db->traverse(db, tdbsam_convert_one, &state);
    789942        if (ret < 0) {
    790                 DEBUG(0, ("traverse failed\n"));
     943                DEBUG(0, ("tdbsam_convert: traverse failed\n"));
    791944                goto cancel;
    792945        }
    793946
    794947        if (!state.success) {
    795                 DEBUG(0, ("Converting records failed\n"));
     948                DEBUG(0, ("tdbsam_convert: Converting records failed\n"));
    796949                goto cancel;
    797950        }
     
    799952        if (dbwrap_store_int32(db, TDBSAM_VERSION_STRING,
    800953                               TDBSAM_VERSION) != 0) {
    801                 DEBUG(0, ("Could not store tdbsam version\n"));
     954                DEBUG(0, ("tdbsam_convert: Could not store tdbsam version\n"));
    802955                goto cancel;
    803956        }
    804957
     958        if (dbwrap_store_int32(db, TDBSAM_MINOR_VERSION_STRING,
     959                               TDBSAM_MINOR_VERSION) != 0) {
     960                DEBUG(0, ("tdbsam_convert: Could not store tdbsam minor version\n"));
     961                goto cancel;
     962        }
     963
    805964        if (db->transaction_commit(db) != 0) {
    806                 DEBUG(0, ("Could not commit transaction\n"));
     965                DEBUG(0, ("tdbsam_convert: Could not commit transaction\n"));
    807966                goto cancel;
    808967        }
     
    812971 cancel:
    813972        if (db->transaction_cancel(db) != 0) {
    814                 smb_panic("transaction_cancel failed");
     973                smb_panic("tdbsam_convert: transaction_cancel failed");
    815974        }
    816975
     
    826985{
    827986        int32   version;
     987        int32   minor_version;
    828988
    829989        /* check if we are already open */
     
    8461006        if (version == -1) {
    8471007                version = 0;    /* Version not found, assume version 0 */
     1008        }
     1009
     1010        /* Get the minor version */
     1011        minor_version = dbwrap_fetch_int32(db_sam, TDBSAM_MINOR_VERSION_STRING);
     1012        if (minor_version == -1) {
     1013                minor_version = 0; /* Minor version not found, assume 0 */
    8481014        }
    8491015
     
    8561022        }
    8571023
    858         if ( version < TDBSAM_VERSION ) {
    859                 DEBUG(1, ("tdbsam_open: Converting version %d database to "
    860                           "version %d.\n", version, TDBSAM_VERSION));
    861 
    862                 if ( !tdbsam_convert(db_sam, version) ) {
    863                         DEBUG(0, ("tdbsam_open: Error when trying to convert "
    864                                   "tdbsam [%s]\n",name));
     1024        if ( version < TDBSAM_VERSION ||
     1025                        (version == TDBSAM_VERSION &&
     1026                         minor_version < TDBSAM_MINOR_VERSION) ) {
     1027                /*
     1028                 * Ok - we think we're going to have to convert.
     1029                 * Due to the backup process we now must do to
     1030                 * upgrade we have to get a mutex and re-check
     1031                 * the version. Someone else may have upgraded
     1032                 * whilst we were checking.
     1033                 */
     1034
     1035                struct named_mutex *mtx = grab_named_mutex(NULL,
     1036                                                "tdbsam_upgrade_mutex",
     1037                                                600);
     1038
     1039                if (!mtx) {
     1040                        DEBUG(0, ("tdbsam_open: failed to grab mutex.\n"));
    8651041                        TALLOC_FREE(db_sam);
    8661042                        return false;
    8671043                }
    8681044
    869                 DEBUG(3, ("TDBSAM converted successfully.\n"));
     1045                /* Re-check the version */
     1046                version = dbwrap_fetch_int32(db_sam, TDBSAM_VERSION_STRING);
     1047                if (version == -1) {
     1048                        version = 0;    /* Version not found, assume version 0 */
     1049                }
     1050
     1051                /* Re-check the minor version */
     1052                minor_version = dbwrap_fetch_int32(db_sam, TDBSAM_MINOR_VERSION_STRING);
     1053                if (minor_version == -1) {
     1054                        minor_version = 0; /* Minor version not found, assume 0 */
     1055                }
     1056
     1057                /* Compare the version */
     1058                if (version > TDBSAM_VERSION) {
     1059                        /* Version more recent than the latest known */
     1060                        DEBUG(0, ("tdbsam_open: unknown version => %d\n", version));
     1061                        TALLOC_FREE(db_sam);
     1062                        TALLOC_FREE(mtx);
     1063                        return false;
     1064                }
     1065
     1066                if ( version < TDBSAM_VERSION ||
     1067                                (version == TDBSAM_VERSION &&
     1068                                 minor_version < TDBSAM_MINOR_VERSION) ) {
     1069                        /*
     1070                         * Note that minor versions we read that are greater
     1071                         * than the current minor version we have hard coded
     1072                         * are assumed to be compatible if they have the same
     1073                         * major version. That allows previous versions of the
     1074                         * passdb code that don't know about minor versions to
     1075                         * still use this database. JRA.
     1076                         */
     1077
     1078                        DEBUG(1, ("tdbsam_open: Converting version %d.%d database to "
     1079                                  "version %d.%d.\n",
     1080                                        version,
     1081                                        minor_version,
     1082                                        TDBSAM_VERSION,
     1083                                        TDBSAM_MINOR_VERSION));
     1084
     1085                        if ( !tdbsam_convert(&db_sam, name, version) ) {
     1086                                DEBUG(0, ("tdbsam_open: Error when trying to convert "
     1087                                          "tdbsam [%s]\n",name));
     1088                                TALLOC_FREE(db_sam);
     1089                                TALLOC_FREE(mtx);
     1090                                return false;
     1091                        }
     1092
     1093                        DEBUG(3, ("TDBSAM converted successfully.\n"));
     1094                }
     1095                TALLOC_FREE(mtx);
    8701096        }
    8711097
Note: See TracChangeset for help on using the changeset viewer.