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