Beispiel #1
0
/* read a entry from the secrets database - the caller must free the result
   if size is non-null then the size of the entry is put in there
 */
void *secrets_fetch(const char *key, size_t *size)
{
	TDB_DATA dbuf;
	void *result;

	if (!secrets_init()) {
		return NULL;
	}

	if (db_ctx->fetch(db_ctx, talloc_tos(), string_tdb_data(key),
			  &dbuf) != 0) {
		return NULL;
	}

	result = memdup(dbuf.dptr, dbuf.dsize);
	if (result == NULL) {
		return NULL;
	}
	TALLOC_FREE(dbuf.dptr);

	if (size) {
		*size = dbuf.dsize;
	}

	return result;
}
Beispiel #2
0
/* read a entry from the secrets database - the caller must free the result
   if size is non-null then the size of the entry is put in there
 */
void *secrets_fetch(const char *key, size_t *size)
{
	TDB_DATA dbuf;
	void *result;
	NTSTATUS status;

	if (!secrets_init()) {
		return NULL;
	}

	status = dbwrap_fetch(db_ctx, talloc_tos(), string_tdb_data(key),
			      &dbuf);
	if (!NT_STATUS_IS_OK(status)) {
		return NULL;
	}

	result = memdup(dbuf.dptr, dbuf.dsize);
	if (result == NULL) {
		return NULL;
	}
	TALLOC_FREE(dbuf.dptr);

	if (size) {
		*size = dbuf.dsize;
	}

	return result;
}
Beispiel #3
0
static uint32_t _reg_perfcount_multi_sz_from_tdb(TDB_CONTEXT *tdb,
					       int keyval,
					       char **retbuf,
					       uint32_t buffer_size)
{
	TDB_DATA kbuf, dbuf;
	char temp[PERFCOUNT_MAX_LEN] = {0};
	char *buf1 = *retbuf;
	uint32_t working_size = 0;
	DATA_BLOB name_index, name;
	bool ok;

	snprintf(temp, sizeof(temp), "%d", keyval);
	kbuf = string_tdb_data(temp);
	dbuf = tdb_fetch(tdb, kbuf);
	if(dbuf.dptr == NULL)
	{
		/* If a key isn't there, just bypass it -- this really shouldn't 
		   happen unless someone's mucking around with the tdb */
		DEBUG(3, ("_reg_perfcount_multi_sz_from_tdb: failed to find key [%s] in [%s].\n",
			  temp, tdb_name(tdb)));
		return buffer_size;
	}
	/* First encode the name_index */
	working_size = (kbuf.dsize + 1)*sizeof(uint16_t);
	buf1 = (char *)SMB_REALLOC(buf1, buffer_size + working_size);
	if(!buf1) {
		buffer_size = 0;
		return buffer_size;
	}
	ok = push_reg_sz(talloc_tos(), &name_index, (const char *)kbuf.dptr);
	if (!ok) {
		buffer_size = 0;
		return buffer_size;
	}
	memcpy(buf1+buffer_size, (char *)name_index.data, working_size);
	buffer_size += working_size;
	/* Now encode the actual name */
	working_size = (dbuf.dsize + 1)*sizeof(uint16_t);
	buf1 = (char *)SMB_REALLOC(buf1, buffer_size + working_size);
	if(!buf1) {
		buffer_size = 0;
		return buffer_size;
	}
	memset(temp, 0, sizeof(temp));
	memcpy(temp, dbuf.dptr, dbuf.dsize);
	SAFE_FREE(dbuf.dptr);
	ok = push_reg_sz(talloc_tos(), &name, temp);
	if (!ok) {
		buffer_size = 0;
		return buffer_size;
	}
	memcpy(buf1+buffer_size, (char *)name.data, working_size);
	buffer_size += working_size;

	*retbuf = buf1;

	return buffer_size;
}
Beispiel #4
0
/* delete a secets database entry
 */
bool secrets_delete(const char *key)
{
	NTSTATUS status;
	if (!secrets_init()) {
		return false;
	}

	status = dbwrap_trans_delete(db_ctx, string_tdb_data(key));

	return NT_STATUS_IS_OK(status);
}
Beispiel #5
0
uint32_t reg_perfcount_get_base_index(void)
{
	char *fname;
	TDB_CONTEXT *names;
	TDB_DATA kbuf, dbuf;
	char key[] = "1";
	uint32_t retval = 0;
	char buf[PERFCOUNT_MAX_LEN];

	fname = counters_directory(NAMES_DB);
	if (fname == NULL) {
		return 0;
	}

	names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);

	if ( !names ) {
		DEBUG(2, ("reg_perfcount_get_base_index: unable to open [%s].\n", fname));
		TALLOC_FREE(fname);
		return 0;
	}
	/* needs to read the value of key "1" from the counter_names.tdb file, as that is
	   where the total number of counters is stored. We're assuming no holes in the
	   enumeration.
	   The format for the counter_names.tdb file is:
	   key        value
	   1          num_counters
	   2          perf_counter1
	   3          perf_counter1_help
	   4          perf_counter2
	   5          perf_counter2_help
	   even_num   perf_counter<even_num>
	   even_num+1 perf_counter<even_num>_help
	   and so on.
	   So last_counter becomes num_counters*2, and last_help will be last_counter+1 */
	kbuf = string_tdb_data(key);
	dbuf = tdb_fetch(names, kbuf);
	if(dbuf.dptr == NULL)
	{
		DEBUG(1, ("reg_perfcount_get_base_index: failed to find key \'1\' in [%s].\n", fname));
		tdb_close(names);
		TALLOC_FREE(fname);
		return 0;
	}

	tdb_close(names);
	TALLOC_FREE(fname);
	memset(buf, 0, PERFCOUNT_MAX_LEN);
	memcpy(buf, dbuf.dptr, dbuf.dsize);
	retval = (uint32_t)atoi(buf);
	SAFE_FREE(dbuf.dptr);
	return retval;
}
Beispiel #6
0
/* store a secrets entry
 */
bool secrets_store(const char *key, const void *data, size_t size)
{
	NTSTATUS status;

	if (!secrets_init()) {
		return false;
	}

	status = dbwrap_trans_store(db_ctx, string_tdb_data(key),
				    make_tdb_data((const uint8 *)data, size),
				    TDB_REPLACE);
	return NT_STATUS_IS_OK(status);
}
Beispiel #7
0
/*
 * Deletes the key if it exists.
 */
bool secrets_delete(const char *key)
{
	bool exists;

	if (!secrets_init()) {
		return false;
	}

	exists = dbwrap_exists(db_ctx, string_tdb_data(key));
	if (!exists) {
		return true;
	}

	return secrets_delete_entry(key);
}
Beispiel #8
0
static void _reg_perfcount_make_key(TDB_DATA *key,
				    char *buf,
				    int buflen,
				    int key_part1,
				    const char *key_part2)
{
	memset(buf, 0, buflen);
	if(key_part2 != NULL)
		snprintf(buf, buflen,"%d%s", key_part1, key_part2);
	else 
		snprintf(buf, buflen, "%d", key_part1);

	*key = string_tdb_data(buf);

	return;
}
/**
 * Fill in credentials for the machine trust account, from the
 * secrets.ldb or passed in handle to secrets.tdb (perhaps in CTDB).
 *
 * This version is used in parts of the code that can link in the
 * CTDB dbwrap backend, by passing down the already open handle.
 *
 * @param cred Credentials structure to fill in
 * @param db_ctx dbwrap context for secrets.tdb
 * @retval NTSTATUS error detailing any failure
 */
_PUBLIC_ NTSTATUS cli_credentials_set_machine_account_db_ctx(struct cli_credentials *cred,
							     struct loadparm_context *lp_ctx,
							     struct db_context *db_ctx)
{
	NTSTATUS status;
	char *filter;
	char *error_string = NULL;
	const char *domain;
	bool secrets_tdb_password_more_recent;
	time_t secrets_tdb_lct = 0;
	char *secrets_tdb_password = NULL;
	char *secrets_tdb_old_password = NULL;
	uint32_t secrets_tdb_secure_channel_type = SEC_CHAN_NULL;
	char *keystr;
	char *keystr_upper = NULL;
	TALLOC_CTX *tmp_ctx = talloc_named(cred, 0, "cli_credentials_set_secrets from ldb");
	if (!tmp_ctx) {
		return NT_STATUS_NO_MEMORY;
	}

	/* Bleh, nasty recursion issues: We are setting a machine
	 * account here, so we don't want the 'pending' flag around
	 * any more */
	cred->machine_account_pending = false;

	/* We have to do this, as the fallback in
	 * cli_credentials_set_secrets is to run as anonymous, so the domain is wiped */
	domain = cli_credentials_get_domain(cred);

	if (db_ctx) {
		TDB_DATA dbuf;
		keystr = talloc_asprintf(tmp_ctx, "%s/%s",
					 SECRETS_MACHINE_LAST_CHANGE_TIME,
					 domain);
		keystr_upper = strupper_talloc(tmp_ctx, keystr);
		status = dbwrap_fetch(db_ctx, tmp_ctx, string_tdb_data(keystr_upper),
				      &dbuf);
		if (NT_STATUS_IS_OK(status) && dbuf.dsize == 4) {
			secrets_tdb_lct = IVAL(dbuf.dptr,0);
		}

		keystr = talloc_asprintf(tmp_ctx, "%s/%s",
					 SECRETS_MACHINE_PASSWORD,
					 domain);
		keystr_upper = strupper_talloc(tmp_ctx, keystr);
		status = dbwrap_fetch(db_ctx, tmp_ctx, string_tdb_data(keystr_upper),
				      &dbuf);
		if (NT_STATUS_IS_OK(status)) {
			secrets_tdb_password = (char *)dbuf.dptr;
		}

		keystr = talloc_asprintf(tmp_ctx, "%s/%s",
					 SECRETS_MACHINE_PASSWORD_PREV,
					 domain);
		keystr_upper = strupper_talloc(tmp_ctx, keystr);
		status = dbwrap_fetch(db_ctx, tmp_ctx, string_tdb_data(keystr_upper),
				      &dbuf);
		if (NT_STATUS_IS_OK(status)) {
			secrets_tdb_old_password = (char *)dbuf.dptr;
		}

		keystr = talloc_asprintf(tmp_ctx, "%s/%s",
					 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
					 domain);
		keystr_upper = strupper_talloc(tmp_ctx, keystr);
		status = dbwrap_fetch(db_ctx, tmp_ctx, string_tdb_data(keystr_upper),
				      &dbuf);
		if (NT_STATUS_IS_OK(status) && dbuf.dsize == 4) {
			secrets_tdb_secure_channel_type = IVAL(dbuf.dptr,0);
		}
	}

	filter = talloc_asprintf(cred, SECRETS_PRIMARY_DOMAIN_FILTER, 
				 domain);
	status = cli_credentials_set_secrets_lct(cred, lp_ctx, NULL,
						 SECRETS_PRIMARY_DOMAIN_DN,
						 filter, secrets_tdb_lct, secrets_tdb_password, &error_string);
	if (secrets_tdb_password == NULL) {
		secrets_tdb_password_more_recent = false;
	} else if (NT_STATUS_EQUAL(NT_STATUS_CANT_ACCESS_DOMAIN_INFO, status)
	    || NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, status)) {
		secrets_tdb_password_more_recent = true;
	} else if (secrets_tdb_lct > cli_credentials_get_password_last_changed_time(cred)) {
		secrets_tdb_password_more_recent = true;
	} else if (secrets_tdb_lct == cli_credentials_get_password_last_changed_time(cred)) {
		secrets_tdb_password_more_recent = strcmp(secrets_tdb_password, cli_credentials_get_password(cred)) != 0;
	} else {
		secrets_tdb_password_more_recent = false;
	}

	if (secrets_tdb_password_more_recent) {
		char *machine_account = talloc_asprintf(tmp_ctx, "%s$", lpcfg_netbios_name(lp_ctx));
		cli_credentials_set_password(cred, secrets_tdb_password, CRED_SPECIFIED);
		cli_credentials_set_old_password(cred, secrets_tdb_old_password, CRED_SPECIFIED);
		cli_credentials_set_domain(cred, domain, CRED_SPECIFIED);
		if (strequal(domain, lpcfg_workgroup(lp_ctx))) {
			cli_credentials_set_realm(cred, lpcfg_realm(lp_ctx), CRED_SPECIFIED);
		}
		cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED);
		cli_credentials_set_password_last_changed_time(cred, secrets_tdb_lct);
		cli_credentials_set_secure_channel_type(cred, secrets_tdb_secure_channel_type);
		status = NT_STATUS_OK;
	} else if (!NT_STATUS_IS_OK(status)) {
		if (db_ctx) {
			error_string
				= talloc_asprintf(cred,
						  "Failed to fetch machine account password for %s from both "
						  "secrets.ldb (%s) and from %s",
						  domain,
						  error_string == NULL ? "error" : error_string,
						  dbwrap_name(db_ctx));
		} else {
			char *secrets_tdb_path;

			secrets_tdb_path = lpcfg_private_db_path(tmp_ctx,
								 lp_ctx,
								 "secrets");
			if (secrets_tdb_path == NULL) {
				return NT_STATUS_NO_MEMORY;
			}

			error_string = talloc_asprintf(cred,
						       "Failed to fetch machine account password from "
						       "secrets.ldb: %s and failed to open %s",
						       error_string == NULL ? "error" : error_string,
						       secrets_tdb_path);
		}
		DEBUG(1, ("Could not find machine account in secrets database: %s: %s\n",
			  error_string == NULL ? "error" : error_string,
			  nt_errstr(status)));
		/* set anonymous as the fallback, if the machine account won't work */
		cli_credentials_set_anonymous(cred);
	}

	TALLOC_FREE(tmp_ctx);
	return status;
}