Beispiel #1
0
static NTSTATUS net_idmap_fixup_hwm(void)
{
	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
	TDB_CONTEXT *idmap_tdb;
	char *tdbfile = NULL;

	struct hwms hwms;
	struct hwms highest;

	if (!lp_idmap_uid(&hwms.user_hwm, &highest.user_hwm) ||
	    !lp_idmap_gid(&hwms.group_hwm, &highest.group_hwm)) {
		d_fprintf(stderr, "idmap range missing\n");
		return NT_STATUS_UNSUCCESSFUL;
	}

	tdbfile = SMB_STRDUP(lock_path("winbindd_idmap.tdb"));
	if (!tdbfile) {
		DEBUG(0, ("idmap_init: out of memory!\n"));
		return NT_STATUS_NO_MEMORY;
	}

	idmap_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0);

	if (idmap_tdb == NULL) {
		d_fprintf(stderr, "Could not open idmap: %s\n", tdbfile);
		return NT_STATUS_NO_SUCH_FILE;
	}

	hwms.ok = True;

	tdb_traverse(idmap_tdb, net_idmap_find_max_id, &hwms);

	if (!hwms.ok) {
		goto done;
	}

	d_printf("USER HWM: %d  GROUP HWM: %d\n",
		 hwms.user_hwm, hwms.group_hwm);

	if (hwms.user_hwm >= highest.user_hwm) {
		d_fprintf(stderr, "Highest UID out of uid range\n");
		goto done;
	}

	if (hwms.group_hwm >= highest.group_hwm) {
		d_fprintf(stderr, "Highest GID out of gid range\n");
		goto done;
	}

	if ((tdb_store_int32(idmap_tdb, "USER HWM", (int32)hwms.user_hwm) != 0) ||
	    (tdb_store_int32(idmap_tdb, "GROUP HWM", (int32)hwms.group_hwm) != 0)) {
		d_fprintf(stderr, "Could not store HWMs\n");
		goto done;
	}

	result = NT_STATUS_OK;
 done:
	tdb_close(idmap_tdb);
	return result;
}
Beispiel #2
0
TDB_CONTEXT *elog_init_tdb( char *tdbfilename )
{
	TDB_CONTEXT *tdb;

	DEBUG(10,("elog_init_tdb: Initializing eventlog tdb (%s)\n",
		tdbfilename));

	tdb = tdb_open_log( tdbfilename, 0, TDB_DEFAULT,
		O_RDWR|O_CREAT|O_TRUNC, 0660 );

	if ( !tdb ) {
		DEBUG( 0, ( "Can't open tdb for [%s]\n", tdbfilename ) );
		return NULL;
	}

	/* initialize with defaults, copy real values in here from registry */

	tdb_store_int32( tdb, EVT_OLDEST_ENTRY, 1 );
	tdb_store_int32( tdb, EVT_NEXT_RECORD, 1 );
	tdb_store_int32( tdb, EVT_MAXSIZE, 0x80000 );
	tdb_store_int32( tdb, EVT_RETENTION, 0x93A80 );

	tdb_store_int32( tdb, EVT_VERSION, EVENTLOG_DATABASE_VERSION_V1 );

	return tdb;
}
Beispiel #3
0
BOOL share_info_db_init(void)
{
	const char *vstring = "INFO/version";
	int32 vers_id;
 
	if (share_tdb) {
		return True;
	}

	share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
	if (!share_tdb) {
		DEBUG(0,("Failed to open share info database %s (%s)\n",
			lock_path("share_info.tdb"), strerror(errno) ));
		return False;
	}
 
	/* handle a Samba upgrade */
	tdb_lock_bystring(share_tdb, vstring);

	/* Cope with byte-reversed older versions of the db. */
	vers_id = tdb_fetch_int32(share_tdb, vstring);
	if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
		/* Written on a bigendian machine with old fetch_int code. Save as le. */
		tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
		vers_id = SHARE_DATABASE_VERSION_V2;
	}

	if (vers_id != SHARE_DATABASE_VERSION_V2) {
		tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
		tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
	}
	tdb_unlock_bystring(share_tdb, vstring);

	return True;
}
Beispiel #4
0
static void set_printer_status(char *printer, int status)
{
	fstring keystr;
	int result;

	slprintf(keystr, sizeof(keystr) - 1, "STATUS/%s", printer);
	result = tdb_store_int32(tdb, keystr, status);
}
Beispiel #5
0
int32_t tdb_change_int32_atomic(struct tdb_context *tdb, const char *keystr, int32_t *oldval, int32_t change_val)
{
	int32_t val;
	int32_t ret = -1;

	if (tdb_lock_bystring(tdb, keystr) == -1)
		return -1;

	if ((val = tdb_fetch_int32(tdb, keystr)) == -1) {
		/* The lookup failed */
		if (tdb_error(tdb) != TDB_ERR_NOEXIST) {
			/* but not because it didn't exist */
			goto err_out;
		}
		
		/* Start with 'old' value */
		val = *oldval;

	} else {
		/* It worked, set return value (oldval) to tdb data */
		*oldval = val;
	}

	/* Increment value for storage and return next time */
	val += change_val;
		
	if (tdb_store_int32(tdb, keystr, val) == -1)
		goto err_out;

	ret = 0;

  err_out:

	tdb_unlock_bystring(tdb, keystr);
	return ret;
}
Beispiel #6
0
static int next_jobnum(char *printer)
{
	fstring keystr;
	int jobnum;

	slprintf(keystr, sizeof(keystr) - 1, "JOBNUM/%s", printer);

	tdb_lock_bystring(tdb, keystr);

	jobnum = tdb_fetch_int32(tdb, keystr);

	/* Create next job index if none exists */

	if (jobnum == -1) {
		jobnum = atoi(PRINT_FIRSTJOB);
	}

	jobnum++;
	tdb_store_int32(tdb, keystr, jobnum);

	tdb_unlock_bystring(tdb, keystr);

	return jobnum;
}
Beispiel #7
0
/* initialise the message translation subsystem. If the "lang" argument
   is NULL then get the language from the normal environment variables */
BOOL lang_tdb_init(const char *lang)
{
	char *path = NULL;
	char *msg_path = NULL;
	struct stat st;
	static int initialised;
	time_t loadtime;
	BOOL result = False;

	/* we only want to init once per process, unless given
	   an override */
	if (initialised && !lang) 
		return True;

	if (initialised) {
		/* we are re-initialising, free up any old init */
		if (tdb) {
			tdb_close(tdb);
			tdb = NULL;
		}
		SAFE_FREE(current_lang);
	}

	initialised = 1;

	if (!lang) {
		/* no lang given, use environment */
		lang = get_lang();
	}

	/* if no lang then we don't translate */
	if (!lang) 
		return True;

	asprintf(&msg_path, "%s.msg", lib_path((const char *)lang));
	if (stat(msg_path, &st) != 0) {
		/* the msg file isn't available */
		DEBUG(10, ("lang_tdb_init: %s: %s\n", msg_path, 
			   strerror(errno)));
		goto done;
	}
	
	asprintf(&path, "%s%s.tdb", lock_path("lang_"), lang);

	DEBUG(10, ("lang_tdb_init: loading %s\n", path));

	tdb = tdb_open_log(path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);
	if (!tdb) {
		tdb = tdb_open_log(path, 0, TDB_DEFAULT, O_RDONLY, 0);
		if (!tdb) {
			DEBUG(10, ("lang_tdb_init: %s: %s\n", path,
				   strerror(errno)));
			goto done;
		}
		current_lang = SMB_STRDUP(lang);
		result = True;
		goto done;
	}

	loadtime = tdb_fetch_int32(tdb, "/LOADTIME/");

	if (loadtime == -1 || loadtime < st.st_mtime) {
		load_msg(msg_path);
		tdb_store_int32(tdb, "/LOADTIME/", (int)time(NULL));
	}

	current_lang = SMB_STRDUP(lang);
	result = True;

 done:
	SAFE_FREE(msg_path);
	SAFE_FREE(path);

	return result;
}
Beispiel #8
0
NTSTATUS evlog_push_record_tdb(TALLOC_CTX *mem_ctx,
			       TDB_CONTEXT *tdb,
			       struct eventlog_Record_tdb *r,
			       uint32_t *record_number)
{
	TDB_DATA kbuf, ebuf;
	DATA_BLOB blob;
	enum ndr_err_code ndr_err;
	int ret;

	if (!r) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	if (!can_write_to_eventlog(tdb, r->size)) {
		return NT_STATUS_EVENTLOG_CANT_START;
	}

	/* need to read the record number and insert it into the entry here */

	/* lock */
	ret = tdb_lock_bystring_with_timeout(tdb, EVT_NEXT_RECORD, 1);
	if (ret == -1) {
		return NT_STATUS_LOCK_NOT_GRANTED;
	}

	/* read */
	r->record_number = tdb_fetch_int32(tdb, EVT_NEXT_RECORD);

	ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, r,
		      (ndr_push_flags_fn_t)ndr_push_eventlog_Record_tdb);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);
		return ndr_map_error2ntstatus(ndr_err);
	}

	/* increment the record count */

	kbuf.dsize = sizeof(int32_t);
	kbuf.dptr = (uint8_t *)&r->record_number;

	ebuf.dsize = blob.length;
	ebuf.dptr  = blob.data;

	ret = tdb_store(tdb, kbuf, ebuf, 0);
	if (ret == -1) {
		tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);
		return NT_STATUS_EVENTLOG_FILE_CORRUPT;
	}

	ret = tdb_store_int32(tdb, EVT_NEXT_RECORD, r->record_number + 1);
	if (ret == -1) {
		tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);
		return NT_STATUS_EVENTLOG_FILE_CORRUPT;
	}
	tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);

	if (record_number) {
		*record_number = r->record_number;
	}

	return NT_STATUS_OK;
}
Beispiel #9
0
static bool make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32_t needed,
				    bool whack_by_date )
{
	int32_t start_record, i, new_start;
	int32_t end_record;
	int32_t reclen, tresv1, trecnum, timegen, timewr;
	int nbytes, len, Retention, MaxSize;
	TDB_DATA key, ret;
	time_t current_time, exp_time;

	/* discard some eventlogs */

	/* read eventlogs from oldest_entry -- there can't be any discontinuity in recnos,
	   although records not necessarily guaranteed to have successive times */
	/* */

	/* lock */
	tdb_lock_bystring_with_timeout( the_tdb, EVT_NEXT_RECORD, 1 );
	/* read */
	end_record = tdb_fetch_int32( the_tdb, EVT_NEXT_RECORD );
	start_record = tdb_fetch_int32( the_tdb, EVT_OLDEST_ENTRY );
	Retention = tdb_fetch_int32( the_tdb, EVT_RETENTION );
	MaxSize = tdb_fetch_int32( the_tdb, EVT_MAXSIZE );

	time( &current_time );

	/* calculate ... */
	exp_time = current_time - Retention;	/* discard older than exp_time */

	/* todo - check for sanity in next_record */
	nbytes = 0;

	DEBUG( 3,
	       ( "MaxSize [%d] Retention [%d] Current Time [%u]  exp_time [%u]\n",
		 MaxSize, Retention, (unsigned int)current_time, (unsigned int)exp_time ) );
	DEBUG( 3,
	       ( "Start Record [%u] End Record [%u]\n",
		(unsigned int)start_record,
		(unsigned int)end_record ));

	for ( i = start_record; i < end_record; i++ ) {
		/* read a record, add the amt to nbytes */
		key.dsize = sizeof(int32_t);
		key.dptr = (unsigned char *)&i;
		ret = tdb_fetch( the_tdb, key );
		if ( ret.dsize == 0 ) {
			DEBUG( 8,
			       ( "Can't find a record for the key, record [%d]\n",
				 i ) );
			tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
			return False;
		}
		nbytes += ret.dsize;	/* note this includes overhead */

		len = tdb_unpack( ret.dptr, ret.dsize, "ddddd", &reclen,
				  &tresv1, &trecnum, &timegen, &timewr );
		if (len == -1) {
			DEBUG( 10,("make_way_for_eventlogs: tdb_unpack failed.\n"));
			tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
			SAFE_FREE( ret.dptr );
			return False;
		}

		DEBUG( 8,
		       ( "read record %u, record size is [%d], total so far [%d]\n",
			 (unsigned int)i, reclen, nbytes ) );

		SAFE_FREE( ret.dptr );

		/* note that other servers may just stop writing records when the size limit
		   is reached, and there are no records older than 'retention'. This doesn't
		   like a very useful thing to do, so instead we whack (as in sleeps with the
		   fishes) just enough records to fit the what we need.  This behavior could
		   be changed to 'match', if the need arises. */

		if ( !whack_by_date && ( nbytes >= needed ) )
			break;	/* done */
		if ( whack_by_date && ( timegen >= exp_time ) )
			break;	/* done */
	}

	DEBUG( 3,
	       ( "nbytes [%d] needed [%d] start_record is [%u], should be set to [%u]\n",
		 nbytes, needed, (unsigned int)start_record, (unsigned int)i ) );
	/* todo - remove eventlog entries here and set starting record to start_record... */
	new_start = i;
	if ( start_record != new_start ) {
		for ( i = start_record; i < new_start; i++ ) {
			key.dsize = sizeof(int32_t);
			key.dptr = (unsigned char *)&i;
			tdb_delete( the_tdb, key );
		}

		tdb_store_int32( the_tdb, EVT_OLDEST_ENTRY, new_start );
	}
	tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
	return True;
}
/****************************************************************************
 Open the group mapping tdb.
****************************************************************************/
static bool init_group_mapping(void)
{
	const char *ldb_path;

	if (db != NULL) {
		return true;
	}

	db = db_open(NULL, state_path("group_mapping.tdb"), 0,
		     TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
		     DBWRAP_LOCK_ORDER_1);
	if (db == NULL) {
		DEBUG(0, ("Failed to open group mapping database: %s\n",
			  strerror(errno)));
		return false;
	}

	ldb_path = state_path("group_mapping.ldb");
	if (file_exist(ldb_path) && !mapping_switch(ldb_path)) {
		unlink(state_path("group_mapping.tdb"));
		return false;

	} else {
		/* handle upgrade from old versions of the database */
#if 0 /* -- Needs conversion to dbwrap -- */
		const char *vstring = "INFO/version";
		int32 vers_id;
		GROUP_MAP *map_table = NULL;
		size_t num_entries = 0;

		/* handle a Samba upgrade */
		tdb_lock_bystring(tdb, vstring);

		/* Cope with byte-reversed older versions of the db. */
		vers_id = tdb_fetch_int32(tdb, vstring);
		if ((vers_id == DATABASE_VERSION_V1)
		    || (IREV(vers_id) == DATABASE_VERSION_V1)) {
			/*
			 * Written on a bigendian machine with old fetch_int
			 * code. Save as le.
			 */
			tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
			vers_id = DATABASE_VERSION_V2;
		}

		/* if its an unknown version we remove everthing in the db */

		if (vers_id != DATABASE_VERSION_V2) {
			tdb_wipe_all(tdb);
			tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
		}

		tdb_unlock_bystring(tdb, vstring);

		/* cleanup any map entries with a gid == -1 */

		if ( enum_group_mapping( NULL, SID_NAME_UNKNOWN, &map_table,
					 &num_entries, False ) ) {
			int i;

			for ( i=0; i<num_entries; i++ ) {
				if ( map_table[i].gid == -1 ) {
					group_map_remove( &map_table[i].sid );
				}
			}

			SAFE_FREE( map_table );
		}
#endif
	}
	return true;
}
Beispiel #11
0
/****************************************************************************
 Open the group mapping tdb.
****************************************************************************/
static bool init_group_mapping(void)
{
	if (db != NULL) {
		return true;
	}

	db = db_open_trans(NULL, state_path("group_mapping.tdb"), 0,
			   TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
	if (db == NULL) {
		DEBUG(0, ("Failed to open group mapping database: %s\n",
			  strerror(errno)));
		return false;
	}

#if 0
	/*
	 * This code was designed to handle a group mapping version
	 * upgrade. mapping_tdb is not active by default anymore, so ignore
	 * this here.
	 */
	{
		const char *vstring = "INFO/version";
		int32 vers_id;
		GROUP_MAP *map_table = NULL;
		size_t num_entries = 0;

		/* handle a Samba upgrade */
		tdb_lock_bystring(tdb, vstring);

		/* Cope with byte-reversed older versions of the db. */
		vers_id = tdb_fetch_int32(tdb, vstring);
		if ((vers_id == DATABASE_VERSION_V1)
		    || (IREV(vers_id) == DATABASE_VERSION_V1)) {
			/*
			 * Written on a bigendian machine with old fetch_int
			 * code. Save as le.
			 */
			tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
			vers_id = DATABASE_VERSION_V2;
		}

		/* if its an unknown version we remove everthing in the db */

		if (vers_id != DATABASE_VERSION_V2) {
			tdb_wipe_all(tdb);
			tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
		}

		tdb_unlock_bystring(tdb, vstring);

		/* cleanup any map entries with a gid == -1 */

		if ( enum_group_mapping( NULL, SID_NAME_UNKNOWN, &map_table,
					 &num_entries, False ) ) {
			int i;

			for ( i=0; i<num_entries; i++ ) {
				if ( map_table[i].gid == -1 ) {
					group_map_remove( &map_table[i].sid );
				}
			}

			SAFE_FREE( map_table );
		}
	}
#endif

	return true;
}
Beispiel #12
0
static bool sync_eventlog_params( EVENTLOG_INFO *info )
{
	char *path = NULL;
	uint32 uiMaxSize;
	uint32 uiRetention;
	struct registry_key *key;
	struct registry_value *value;
	WERROR wresult;
	char *elogname = info->logname;
	TALLOC_CTX *ctx = talloc_stackframe();
	bool ret = false;

	DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );

	if ( !info->etdb ) {
		DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) );
		goto done;
	}
	/* set resonable defaults.  512Kb on size and 1 week on time */

	uiMaxSize = 0x80000;
	uiRetention = 604800;

	/* the general idea is to internally open the registry
	   key and retrieve the values.  That way we can continue
	   to use the same fetch/store api that we use in
	   srv_reg_nt.c */

	path = talloc_asprintf(ctx, "%s/%s", KEY_EVENTLOG, elogname );
	if (!path) {
		goto done;
	}

	wresult = reg_open_path(ctx, path, REG_KEY_READ, get_root_nt_token(),
				&key);

	if ( !W_ERROR_IS_OK( wresult ) ) {
		DEBUG( 4,
		       ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
			 path, win_errstr( wresult ) ) );
		goto done;
	}

	wresult = reg_queryvalue(key, key, "Retention", &value);
	if (!W_ERROR_IS_OK(wresult)) {
		DEBUG(4, ("Failed to query value \"Retention\": %s\n",
			  win_errstr(wresult)));
		goto done;
	}
	uiRetention = value->v.dword;

	wresult = reg_queryvalue(key, key, "MaxSize", &value);
	if (!W_ERROR_IS_OK(wresult)) {
		DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
			  win_errstr(wresult)));
		goto done;
	}
	uiMaxSize = value->v.dword;

	tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize );
	tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention );

	ret = true;

done:
	TALLOC_FREE(ctx);
	return ret;
}
Beispiel #13
0
static bool sync_eventlog_params(TALLOC_CTX *mem_ctx,
				 struct messaging_context *msg_ctx,
				 EVENTLOG_INFO *info)
{
	struct dcerpc_binding_handle *h = NULL;
	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	struct policy_handle hive_hnd, key_hnd;
	uint32_t uiMaxSize = 0;
	uint32_t uiRetention = 0;
	char *path = NULL;
	NTSTATUS status;
	WERROR wresult = WERR_OK;
	char *elogname = info->logname;
	TALLOC_CTX *ctx;
	bool ret = false;

	ctx = talloc_stackframe();
	if (ctx == NULL) {
		return false;
	}

	DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );

	if ( !info->etdb ) {
		DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) );
		goto done;
	}
	/* set resonable defaults.  512Kb on size and 1 week on time */

	uiMaxSize = 0x80000;
	uiRetention = 604800;

	/* the general idea is to internally open the registry
	   key and retrieve the values.  That way we can continue
	   to use the same fetch/store api that we use in
	   srv_reg_nt.c */
	path = talloc_asprintf(ctx, "%s\\%s", TOP_LEVEL_EVENTLOG_KEY, elogname);
	if (!path) {
		goto done;
	}

	status = dcerpc_winreg_int_hklm_openkey(ctx,
						get_session_info_system(),
						msg_ctx,
						&h,
						path,
						false,
						access_mask,
						&hive_hnd,
						&key_hnd,
						&wresult);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(4,("sync_eventlog_params: Failed to open key [%s] (%s)\n",
			 path, nt_errstr(status)));
		goto done;
	}
	if ( !W_ERROR_IS_OK( wresult ) ) {
		DEBUG( 4,
		       ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
			 path, win_errstr( wresult ) ) );
		goto done;
	}

	status = dcerpc_winreg_query_dword(ctx,
					   h,
					   &key_hnd,
					   "Retention",
					   &uiRetention,
					   &wresult);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(4, ("Failed to query value \"Retention\": %s\n",
			  nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(wresult)) {
		DEBUG(4, ("Failed to query value \"Retention\": %s\n",
			  win_errstr(wresult)));
		goto done;
	}

	status = dcerpc_winreg_query_dword(ctx,
					   h,
					   &key_hnd,
					   "MaxSize",
					   &uiMaxSize,
					   &wresult);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(4, ("Failed to query value \"Retention\": %s\n",
			  nt_errstr(status)));
		goto done;
	}
	if (!W_ERROR_IS_OK(wresult)) {
		DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
			  win_errstr(wresult)));
		goto done;
	}

	tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize );
	tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention );

	ret = true;

done:
	if (h != NULL) {
		WERROR ignore;

		if (is_valid_policy_hnd(&key_hnd)) {
			dcerpc_winreg_CloseKey(h, ctx, &key_hnd, &ignore);
		}
		if (is_valid_policy_hnd(&hive_hnd)) {
			dcerpc_winreg_CloseKey(h, ctx, &hive_hnd, &ignore);
		}
	}

	TALLOC_FREE(ctx);
	return ret;
}
Beispiel #14
0
static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from) 
{
	const char * vstring = TDBSAM_VERSION_STRING;
	SAM_ACCOUNT *user = NULL;
	const char *prefix = USERPREFIX;
	TDB_DATA 	data, key, old_key;
	uint8		*buf = NULL;
	BOOL 		ret;

	if (pdb_tdb == NULL) {
		DEBUG(0,("tdbsam_convert: Bad TDB Context pointer.\n"));
		return False;
	}

	/* handle a Samba upgrade */
	tdb_lock_bystring(pdb_tdb, vstring, 0);
	
	if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
		DEBUG(0,("tdbsam_convert: cannot initialized a SAM_ACCOUNT.\n"));
		return False;
	}

	/* Enumerate all records and convert them */
	key = tdb_firstkey(pdb_tdb);

	while (key.dptr) {
	
		/* skip all non-USER entries (eg. RIDs) */
		while ((key.dsize != 0) && (strncmp(key.dptr, prefix, strlen (prefix)))) {
			old_key = key;
			/* increment to next in line */
			key = tdb_nextkey(pdb_tdb, key);
			SAFE_FREE(old_key.dptr);
		}
	
		if (key.dptr) {
			
			/* read from tdbsam */
			data = tdb_fetch(pdb_tdb, key);
			if (!data.dptr) {
				DEBUG(0,("tdbsam_convert: database entry not found: %s.\n",key.dptr));
				return False;
			}
	
			if (!NT_STATUS_IS_OK(pdb_reset_sam(user))) {
				DEBUG(0,("tdbsam_convert: cannot reset SAM_ACCOUNT.\n"));
				SAFE_FREE(data.dptr);
				return False;
			}
			
			/* unpack the buffer from the former format */
			DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) (version:%d)\n", key.dptr, from));
			switch (from) {
				case 0:
					ret = init_sam_from_buffer_v0(user, (uint8 *)data.dptr, data.dsize);
					break;
				case 1:
					ret = init_sam_from_buffer_v1(user, (uint8 *)data.dptr, data.dsize);
					break;
				default:
					/* unknown tdbsam version */
					ret = False;
			}
			if (!ret) {
				DEBUG(0,("tdbsam_convert: Bad SAM_ACCOUNT entry returned from TDB (key:%s) (version:%d)\n", key.dptr, from));
				SAFE_FREE(data.dptr);
				return False;
			}
	
			/* pack from the buffer into the new format */
			DEBUG(10,("tdbsam_convert: Try packing a record (key:%s) (version:%d)\n", key.dptr, from));
			if ((data.dsize=init_buffer_from_sam (&buf, user, False)) == -1) {
				DEBUG(0,("tdbsam_convert: cannot pack the SAM_ACCOUNT into the new format\n"));
				SAFE_FREE(data.dptr);
				return False;
			}
			data.dptr = (char *)buf;
			
			/* Store the buffer inside the TDBSAM */
			if (tdb_store(pdb_tdb, key, data, TDB_MODIFY) != TDB_SUCCESS) {
				DEBUG(0,("tdbsam_convert: cannot store the SAM_ACCOUNT (key:%s) in new format\n",key.dptr));
				SAFE_FREE(data.dptr);
				return False;
			}
			
			SAFE_FREE(data.dptr);
			
			/* increment to next in line */
			old_key = key;
			key = tdb_nextkey(pdb_tdb, key);
			SAFE_FREE(old_key.dptr);
		}
		
	}

	pdb_free_sam(&user);
	
	/* upgrade finished */
	tdb_store_int32(pdb_tdb, vstring, TDBSAM_VERSION);
	tdb_unlock_bystring(pdb_tdb, vstring);

	return(True);	
}