static TDB_CONTEXT * tdbsam_tdbopen (const char *name, int open_flags) { TDB_CONTEXT *pdb_tdb; tdbsamver_t version; /* Try to open tdb passwd */ if (!(pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT, open_flags, 0600))) { DEBUG(0, ("Unable to open/create TDB passwd\n")); return NULL; } /* Check the version */ version = (tdbsamver_t) tdb_fetch_int32(pdb_tdb, TDBSAM_VERSION_STRING); if (version == -1) version = 0; /* Version not found, assume version 0 */ /* Compare the version */ if (version > TDBSAM_VERSION) { /* Version more recent than the latest known */ DEBUG(0, ("TDBSAM version unknown: %d\n", version)); tdb_close(pdb_tdb); pdb_tdb = NULL; } else if (version < TDBSAM_VERSION) { /* Older version, must be converted */ DEBUG(1, ("TDBSAM version too old (%d), trying to convert it.\n", version)); /* Reopen the pdb file with read-write access if needed */ if (!(open_flags & O_RDWR)) { DEBUG(10, ("tdbsam_tdbopen: TDB file opened with read only access, reopen it with read-write access.\n")); tdb_close(pdb_tdb); pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT, (open_flags & 07777770) | O_RDWR, 0600); } /* Convert */ if (!tdbsam_convert(pdb_tdb, version)){ DEBUG(0, ("tdbsam_tdbopen: Error when trying to convert tdbsam: %s\n",name)); tdb_close(pdb_tdb); pdb_tdb = NULL; } else { DEBUG(1, ("TDBSAM converted successfully.\n")); } /* Reopen the pdb file as it must be */ if (!(open_flags & O_RDWR)) { tdb_close(pdb_tdb); pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT, open_flags, 0600); } } return pdb_tdb; }
static bool tdbsam_open( const char *name ) { int32_t version; int32_t minor_version; NTSTATUS status; /* check if we are already open */ if ( db_sam ) { return true; } /* Try to open tdb passwd. Create a new one if necessary */ db_sam = db_open(NULL, name, 0, TDB_DEFAULT, O_CREAT|O_RDWR, 0600, DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE); if (db_sam == NULL) { DEBUG(0, ("tdbsam_open: Failed to open/create TDB passwd " "[%s]\n", name)); return false; } /* Check the version */ status = dbwrap_fetch_int32_bystring(db_sam, TDBSAM_VERSION_STRING, &version); if (!NT_STATUS_IS_OK(status)) { version = 0; /* Version not found, assume version 0 */ } /* Get the minor version */ status = dbwrap_fetch_int32_bystring( db_sam, TDBSAM_MINOR_VERSION_STRING, &minor_version); if (!NT_STATUS_IS_OK(status)) { minor_version = 0; /* Minor version not found, assume 0 */ } /* Compare the version */ if (version > TDBSAM_VERSION) { /* Version more recent than the latest known */ DEBUG(0, ("tdbsam_open: unknown version => %d\n", version)); TALLOC_FREE(db_sam); return false; } if ( version < TDBSAM_VERSION || (version == TDBSAM_VERSION && minor_version < TDBSAM_MINOR_VERSION) ) { /* * Ok - we think we're going to have to convert. * Due to the backup process we now must do to * upgrade we have to get a mutex and re-check * the version. Someone else may have upgraded * whilst we were checking. */ struct named_mutex *mtx = grab_named_mutex(NULL, "tdbsam_upgrade_mutex", 600); if (!mtx) { DEBUG(0, ("tdbsam_open: failed to grab mutex.\n")); TALLOC_FREE(db_sam); return false; } /* Re-check the version */ status = dbwrap_fetch_int32_bystring( db_sam, TDBSAM_VERSION_STRING, &version); if (!NT_STATUS_IS_OK(status)) { version = 0; /* Version not found, assume version 0 */ } /* Re-check the minor version */ status = dbwrap_fetch_int32_bystring( db_sam, TDBSAM_MINOR_VERSION_STRING, &minor_version); if (!NT_STATUS_IS_OK(status)) { minor_version = 0; /* Minor version not found, assume 0 */ } /* Compare the version */ if (version > TDBSAM_VERSION) { /* Version more recent than the latest known */ DEBUG(0, ("tdbsam_open: unknown version => %d\n", version)); TALLOC_FREE(db_sam); TALLOC_FREE(mtx); return false; } if ( version < TDBSAM_VERSION || (version == TDBSAM_VERSION && minor_version < TDBSAM_MINOR_VERSION) ) { /* * Note that minor versions we read that are greater * than the current minor version we have hard coded * are assumed to be compatible if they have the same * major version. That allows previous versions of the * passdb code that don't know about minor versions to * still use this database. JRA. */ DEBUG(1, ("tdbsam_open: Converting version %d.%d database to " "version %d.%d.\n", version, minor_version, TDBSAM_VERSION, TDBSAM_MINOR_VERSION)); if ( !tdbsam_convert(&db_sam, name, version) ) { DEBUG(0, ("tdbsam_open: Error when trying to convert " "tdbsam [%s]\n",name)); TALLOC_FREE(db_sam); TALLOC_FREE(mtx); return false; } DEBUG(3, ("TDBSAM converted successfully.\n")); } TALLOC_FREE(mtx); } DEBUG(4,("tdbsam_open: successfully opened %s\n", name )); return true; }