示例#1
0
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;
}
示例#2
0
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;
}