예제 #1
0
static NTSTATUS idmap_tdb_set_mapping_action(struct db_context *db,
					     void *private_data)
{
	NTSTATUS ret;
	struct idmap_tdb_set_mapping_context *state;

	state = (struct idmap_tdb_set_mapping_context *)private_data;

	DEBUG(10, ("Storing %s <-> %s map\n", state->ksidstr, state->kidstr));

	ret = dbwrap_store_bystring(db, state->ksidstr,
				    string_term_tdb_data(state->kidstr),
				    TDB_REPLACE);
	if (!NT_STATUS_IS_OK(ret)) {
		DEBUG(0, ("Error storing SID -> ID (%s -> %s): %s\n",
			  state->ksidstr, state->kidstr, nt_errstr(ret)));
		goto done;
	}

	ret = dbwrap_store_bystring(db, state->kidstr,
				    string_term_tdb_data(state->ksidstr),
				    TDB_REPLACE);
	if (!NT_STATUS_IS_OK(ret)) {
		DEBUG(0, ("Error storing ID -> SID (%s -> %s): %s\n",
			  state->kidstr, state->ksidstr, nt_errstr(ret)));
		goto done;
	}

	DEBUG(10,("Stored %s <-> %s\n", state->ksidstr, state->kidstr));
	ret = NT_STATUS_OK;

done:
	return ret;
}
예제 #2
0
파일: pdb_tdb.c 프로젝트: Alexander--/samba
/***************************************************************************
 Update the TDB SAM RID record only
 Assumes that the tdbsam is already open
****************************************************************************/
static bool tdb_update_ridrec_only( struct samu* newpwd, int flag )
{
	TDB_DATA 	data;
	fstring 	keystr;
	fstring		name;
	NTSTATUS status;

	fstrcpy(name, pdb_get_username(newpwd));
	if (!strlower_m(name)) {
		return false;
	}

	/* setup RID data */
	data = string_term_tdb_data(name);

	/* setup the RID index key */
	fstr_sprintf(keystr, "%s%.8x", RIDPREFIX, pdb_get_user_rid(newpwd));

	/* add the reference */
	status = dbwrap_store_bystring(db_sam, keystr, data, flag);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Unable to modify TDB passwd: %s!\n",
			  nt_errstr(status)));
		return false;
	}

	return true;

}
예제 #3
0
static int dbwrap_tool_store_string(struct db_context *db,
				    const char *keyname,
				    const char *data)
{
	NTSTATUS status;
	TDB_DATA tdbdata;

	tdbdata = string_term_tdb_data(data);

	if (dbwrap_is_persistent(db)) {
		status = dbwrap_trans_store_bystring(db, keyname,
						     tdbdata,
						     TDB_REPLACE);
	} else {
		status = dbwrap_store_bystring(db, keyname,
					      tdbdata,
					      TDB_REPLACE);
	}
	if (!NT_STATUS_IS_OK(status)) {
		d_fprintf(stderr,
			  "ERROR: could not store string key '%s': %s\n",
			  keyname, nt_errstr(status));
		return -1;
	}

	return 0;
}
예제 #4
0
static int regdb_normalize_keynames_fn(struct db_record *rec,
				       void *private_data)
{
	TALLOC_CTX *mem_ctx = talloc_tos();
	const char *keyname;
	NTSTATUS status;
	TDB_DATA key;
	TDB_DATA value;
	struct db_context *db = (struct db_context *)private_data;

	key = dbwrap_record_get_key(rec);
	if (key.dptr == NULL || key.dsize == 0) {
		return 0;
	}

	value = dbwrap_record_get_value(rec);

	if (db == NULL) {
		DEBUG(0, ("regdb_normalize_keynames_fn: ERROR: "
			  "NULL db context handed in via private_data\n"));
		return 1;
	}

	if (strncmp((const char *)key.dptr, REGDB_VERSION_KEYNAME,
	    strlen(REGDB_VERSION_KEYNAME)) == 0)
	{
		return 0;
	}

	keyname = strchr((const char *)key.dptr, '/');
	if (keyname) {
		keyname = talloc_string_sub(mem_ctx,
					    (const char *)key.dptr,
					    "/",
					    "\\");

		DEBUG(2, ("regdb_normalize_keynames_fn: Convert %s to %s\n",
			  (const char *)key.dptr,
			  keyname));

		/* Delete the original record and store the normalized key */
		status = dbwrap_record_delete(rec);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0,("regdb_normalize_keynames_fn: "
				 "tdb_delete for [%s] failed!\n",
				 (const char *)key.dptr));
			return 1;
		}

		status = dbwrap_store_bystring(db, keyname, value, TDB_REPLACE);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0,("regdb_normalize_keynames_fn: "
				 "failed to store new record for [%s]!\n",
				 keyname));
			return 1;
		}
	}

	return 0;
}
예제 #5
0
static bool set_privileges( const DOM_SID *sid, SE_PRIV *mask )
{
	struct db_context *db = get_account_pol_db();
	fstring tmp, keystr;
	TDB_DATA data;

	if ( !lp_enable_privileges() )
		return False;

	if ( db == NULL )
		return False;

	if ( !sid || (sid->num_auths == 0) ) {
		DEBUG(0,("set_privileges: Refusing to store empty SID!\n"));
		return False;
	}

	/* PRIV_<SID> (NULL terminated) as the key */

	fstr_sprintf(keystr, "%s%s", PRIVPREFIX, sid_to_fstring(tmp, sid));

	/* no packing.  static size structure, just write it out */

	data.dptr  = (uint8 *)mask;
	data.dsize = sizeof(SE_PRIV);

	return NT_STATUS_IS_OK(dbwrap_store_bystring(db, keystr, data,
						     TDB_REPLACE));
}
예제 #6
0
static NTSTATUS idmap_tdb_common_set_mapping_action(struct db_context *db,
						    void *private_data)
{
	TDB_DATA data;
	NTSTATUS ret;
	struct idmap_tdb_common_set_mapping_context *state;
	TALLOC_CTX *tmp_ctx = talloc_stackframe();

	state = (struct idmap_tdb_common_set_mapping_context *)private_data;

	DEBUG(10, ("Storing %s <-> %s map\n", state->ksidstr, state->kidstr));

	/* check whether sid mapping is already present in db */
	ret = dbwrap_fetch_bystring(db, tmp_ctx, state->ksidstr, &data);
	if (NT_STATUS_IS_OK(ret)) {
		ret = NT_STATUS_OBJECT_NAME_COLLISION;
		goto done;
	}

	ret = dbwrap_store_bystring(db, state->ksidstr,
				    string_term_tdb_data(state->kidstr),
				    TDB_INSERT);
	if (!NT_STATUS_IS_OK(ret)) {
		DEBUG(0, ("Error storing SID -> ID: %s\n", nt_errstr(ret)));
		goto done;
	}

	ret = dbwrap_store_bystring(db, state->kidstr,
				    string_term_tdb_data(state->ksidstr),
				    TDB_INSERT);
	if (!NT_STATUS_IS_OK(ret)) {
		DEBUG(0, ("Error storing ID -> SID: %s\n", nt_errstr(ret)));
		/* try to remove the previous stored SID -> ID map */
		dbwrap_delete_bystring(db, state->ksidstr);
		goto done;
	}

	DEBUG(10, ("Stored %s <-> %s\n", state->ksidstr, state->kidstr));

      done:
	talloc_free(tmp_ctx);
	return ret;
}
예제 #7
0
NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key,
				     TDB_DATA data, int flags)
{
	char *key_upper;
	NTSTATUS status;

	key_upper = talloc_strdup_upper(talloc_tos(), key);
	if (key_upper == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	status = dbwrap_store_bystring(db, key_upper, data, flags);

	talloc_free(key_upper);
	return status;
}
예제 #8
0
파일: pdb_tdb.c 프로젝트: Alexander--/samba
/***************************************************************************
 Update the TDB SAM account record only
 Assumes that the tdbsam is already open 
****************************************************************************/
static bool tdb_update_samacct_only( struct samu* newpwd, int flag )
{
	TDB_DATA 	data;
	uint8_t		*buf = NULL;
	fstring 	keystr;
	fstring		name;
	bool		ret = false;
	NTSTATUS status;

	/* copy the struct samu struct into a BYTE buffer for storage */

	if ( (data.dsize=init_buffer_from_samu(&buf, newpwd, False)) == -1 ) {
		DEBUG(0,("tdb_update_sam: ERROR - Unable to copy struct samu info BYTE buffer!\n"));
		goto done;
	}
	data.dptr = buf;

	fstrcpy(name, pdb_get_username(newpwd));
	if (!strlower_m(name)) {
		goto done;
	}

	DEBUG(5, ("Storing %saccount %s with RID %d\n",
		  flag == TDB_INSERT ? "(new) " : "", name,
		  pdb_get_user_rid(newpwd)));

  	/* setup the USER index key */
	fstr_sprintf(keystr, "%s%s", USERPREFIX, name);

	/* add the account */

	status = dbwrap_store_bystring(db_sam, keystr, data, flag);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Unable to modify passwd TDB: %s!",
			  nt_errstr(status)));
		goto done;
	}

	ret = true;

done:
	/* cleanup */
	SAFE_FREE(buf);
	return ret;
}
예제 #9
0
static int dbwrap_tool_store_hex(struct db_context *db,
				    const char *keyname,
				    const char *data)
{
	NTSTATUS status;
	DATA_BLOB datablob;
	TDB_DATA tdbdata;
	TALLOC_CTX *tmp_ctx = talloc_stackframe();

	datablob = strhex_to_data_blob(tmp_ctx, data);
	if(strlen(data) > 0 && datablob.length == 0) {
		d_fprintf(stderr,
			  "ERROR: could not convert hex string to data blob\n"
			  "       Not a valid hex string?\n");
		talloc_free(tmp_ctx);
		return -1;
	}

	tdbdata.dptr = (unsigned char *)datablob.data;
	tdbdata.dsize = datablob.length;

	if (dbwrap_is_persistent(db)) {
		status = dbwrap_trans_store_bystring(db, keyname,
						     tdbdata,
						     TDB_REPLACE);
	} else {
		status = dbwrap_store_bystring(db, keyname,
					       tdbdata,
					       TDB_REPLACE);
	}
	if (!NT_STATUS_IS_OK(status)) {
		d_fprintf(stderr,
			  "ERROR: could not store string key '%s': %s\n",
			  keyname, nt_errstr(status));
		talloc_free(tmp_ctx);
		return -1;
	}

	talloc_free(tmp_ctx);
	return 0;
}
예제 #10
0
NTSTATUS printer_list_mark_reload(void)
{
    struct db_context *db;
    TDB_DATA data;
    uint32_t time_h, time_l;
    time_t now = time_mono(NULL);
    NTSTATUS status;
    int len;

    db = get_printer_list_db();
    if (db == NULL) {
        return NT_STATUS_INTERNAL_DB_CORRUPTION;
    }

    time_l = ((uint64_t)now) & 0xFFFFFFFFL;
    time_h = ((uint64_t)now) >> 32;

    len = tdb_pack(NULL, 0, PL_TSTAMP_FORMAT, time_h, time_l);

    data.dptr = talloc_array(talloc_tos(), uint8_t, len);
    if (!data.dptr) {
        DEBUG(0, ("Failed to allocate tdb data buffer!\n"));
        status = NT_STATUS_NO_MEMORY;
        goto done;
    }
    data.dsize = len;

    len = tdb_pack(data.dptr, data.dsize,
                   PL_TSTAMP_FORMAT, time_h, time_l);

    status = dbwrap_store_bystring(db, PL_TIMESTAMP_KEY,
                                   data, TDB_REPLACE);

done:
    TALLOC_FREE(data.dptr);
    return status;
}
예제 #11
0
/*
  save the notify array
*/
static NTSTATUS notify_save(struct notify_context *notify)
{
	TDB_DATA dbuf;
	DATA_BLOB blob;
	enum ndr_err_code ndr_err;
	TALLOC_CTX *tmp_ctx;
	NTSTATUS status;

	/* if possible, remove some depth arrays */
	while (notify->array->num_depths > 0 &&
	       notify->array->depth[notify->array->num_depths-1].num_entries == 0) {
		notify->array->num_depths--;
	}

	/* we might just be able to delete the record */
	if (notify->array->num_depths == 0) {
		return dbwrap_delete_bystring(notify->db, NOTIFY_KEY);
	}

	tmp_ctx = talloc_new(notify);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, notify->array,
				       (ndr_push_flags_fn_t)ndr_push_notify_array);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		talloc_free(tmp_ctx);
		return ndr_map_error2ntstatus(ndr_err);
	}

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

	status = dbwrap_store_bystring(notify->db, NOTIFY_KEY, dbuf,
				       TDB_REPLACE);
	talloc_free(tmp_ctx);
	return status;
}
예제 #12
0
static bool upgrade_v2_to_v3_check_subkeylist(struct db_context *db,
					      const char *key,
					      const char *subkey)
{
	static uint32_t zero = 0;
	static TDB_DATA empty_subkey_list = {
		.dptr = (unsigned char*)&zero,
		.dsize = sizeof(uint32_t),
	};
	bool success = false;
	char *path = talloc_asprintf(talloc_tos(), "%s\\%s", key, subkey);
	strupper_m(path);

	if (!dbwrap_exists(db, string_term_tdb_data(path))) {
		NTSTATUS status;

		DEBUG(10, ("regdb_upgrade_v2_to_v3: writing subkey list [%s]\n",
			   path));

		status = dbwrap_store_bystring(db, path, empty_subkey_list,
					       TDB_INSERT);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("regdb_upgrade_v2_to_v3: writing subkey list "
				  "[%s] failed\n", path));
			goto done;
		}
	}
	success = true;
done:
	talloc_free(path);
	return success;
}

static bool upgrade_v2_to_v3_check_parent(struct db_context *db,
					  const char *key)
{
	const char *sep = strrchr_m(key, '\\');
	if (sep != NULL) {
		char *pkey = talloc_strndup(talloc_tos(), key, sep-key);
		if (!dbwrap_exists(db, string_term_tdb_data(pkey))) {
			DEBUG(0, ("regdb_upgrade_v2_to_v3: missing subkey list "
				  "[%s]\nrun \"net registry check\"\n", pkey));
		}
		talloc_free(pkey);
	}
	return true;
}


#define IS_EQUAL(d,s) (((d).dsize == strlen(s)+1) &&	\
		       (strcmp((char*)(d).dptr, (s)) == 0))
#define STARTS_WITH(d,s) (((d).dsize > strlen(s)) &&			\
			  (strncmp((char*)(d).dptr, (s), strlen(s)) == 0))
#define SSTR(d) (int)(d).dsize , (char*)(d).dptr


static int regdb_upgrade_v2_to_v3_fn(struct db_record *rec, void *private_data)
{
	struct db_context *db = (struct db_context *)private_data;
	TDB_DATA key = dbwrap_record_get_key(rec);
	TDB_DATA val = dbwrap_record_get_value(rec);

	if (tdb_data_is_empty(key)) {
		return 0;
	}

	if (db == NULL) {
		DEBUG(0, ("regdb_upgrade_v2_to_v3_fn: ERROR: "
			  "NULL db context handed in via private_data\n"));
		return 1;
	}

	if (IS_EQUAL(key, REGDB_VERSION_KEYNAME) ||
	    STARTS_WITH(key, REG_VALUE_PREFIX) ||
	    STARTS_WITH(key, REG_SECDESC_PREFIX))
	{
		DEBUG(10, ("regdb_upgrade_v2_to_v3: skipping [%.*s]\n",
			   SSTR(key)));
		return 0;
	}

	if (STARTS_WITH(key, REG_SORTED_SUBKEYS_PREFIX)) {
		NTSTATUS status;
		/* Delete the deprecated sorted subkeys cache. */

		DEBUG(10, ("regdb_upgrade_v2_to_v3: deleting [%.*s]\n",
			   SSTR(key)));

		status = dbwrap_record_delete(rec);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("regdb_upgrade_v2_to_v3: deleting [%.*s] "
				  "failed!\n", SSTR(key)));
			return 1;
		}

		return 0;
	}

	if ( tdb_data_is_cstr(key) &&
	     hive_info((char*)key.dptr) != NULL )
	{
		/*
		 * Found a regular subkey list record.
		 * Walk the list and create the list record for those
		 * subkeys that don't already have one.
		 */
		TDB_DATA pos = val;
		char *subkey, *path = (char*)key.dptr;
		uint32_t num_items, found_items = 0;


		DEBUG(10, ("regdb_upgrade_v2_to_v3: scanning subkeylist of "
			   "[%s]\n", path));

		if (!tdb_data_read_uint32(&pos, &num_items)) {
			/* invalid or empty - skip */
			return 0;
		}

		while (tdb_data_read_cstr(&pos, &subkey)) {
			found_items++;

			if (!upgrade_v2_to_v3_check_subkeylist(db, path, subkey))
			{
				return 1;
			}

			if (!upgrade_v2_to_v3_check_parent(db, path)) {
				return 1;
			}
		}
		if (found_items != num_items) {
			DEBUG(0, ("regdb_upgrade_v2_to_v3: inconsistent subkey "
				  "list [%s]\nrun \"net registry check\"\n",
				  path));
		}
	} else {
		DEBUG(10, ("regdb_upgrade_v2_to_v3: skipping invalid [%.*s]\n"
			   "run \"net registry check\"\n", SSTR(key)));
	}

	return 0;
}

static WERROR regdb_upgrade_v2_to_v3(struct db_context *db)
{
	NTSTATUS status;
	WERROR werr;

	status = dbwrap_traverse(db, regdb_upgrade_v2_to_v3_fn, db, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		werr = WERR_REG_IO_FAILURE;
		goto done;
	}

	werr = regdb_store_regdb_version(db, REGDB_VERSION_V3);

done:
	return werr;
}
예제 #13
0
static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
{
	NTSTATUS status;
	DOM_SID *sids;
	size_t i, num;
	bool found = False;
	char *member_string;
	char *key;
	fstring sid_string;

	if (db->transaction_start(db) != 0) {
		DEBUG(0, ("transaction_start failed\n"));
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	status = alias_memberships(member, 1, &sids, &num);

	if (!NT_STATUS_IS_OK(status)) {
		goto cancel;
	}

	for (i=0; i<num; i++) {
		if (sid_compare(&sids[i], alias) == 0) {
			found = True;
			break;
		}
	}

	if (!found) {
		TALLOC_FREE(sids);
		status = NT_STATUS_MEMBER_NOT_IN_ALIAS;
		goto cancel;
	}

	if (i < num)
		sids[i] = sids[num-1];

	num -= 1;

	sid_to_fstring(sid_string, member);

	key = talloc_asprintf(sids, "%s%s", MEMBEROF_PREFIX, sid_string);
	if (key == NULL) {
		TALLOC_FREE(sids);
		status = NT_STATUS_NO_MEMORY;
		goto cancel;
	}

	if (num == 0) {
		status = dbwrap_delete_bystring(db, key);
		TALLOC_FREE(sids);
		goto cancel;
	}

	member_string = talloc_strdup(sids, "");
	if (member_string == NULL) {
		TALLOC_FREE(sids);
		status = NT_STATUS_NO_MEMORY;
		goto cancel;
	}

	for (i=0; i<num; i++) {

		sid_to_fstring(sid_string, &sids[i]);

		member_string = talloc_asprintf_append_buffer(
			member_string, " %s", sid_string);

		if (member_string == NULL) {
			TALLOC_FREE(sids);
			status = NT_STATUS_NO_MEMORY;
			goto cancel;
		}
	}

	status = dbwrap_store_bystring(
		db, key, string_term_tdb_data(member_string), 0);

	TALLOC_FREE(sids);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10, ("dbwrap_store_bystring failed: %s\n",
			   nt_errstr(status)));
		goto cancel;
	}

	if (db->transaction_commit(db) != 0) {
		DEBUG(0, ("transaction_commit failed\n"));
		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
		goto cancel;
	}

	return NT_STATUS_OK;

 cancel:
	if (db->transaction_cancel(db) != 0) {
		smb_panic("transaction_cancel failed");
	}
	return status;
}