/* 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; }
/* 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; }
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; }
/* 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); }
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; }
/* 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); }
/* * 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); }
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; }