static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids) { struct idmap_tdb_context *ctx; NTSTATUS ret; int i; struct idmap_tdb_sids_to_unixids_context state; /* initialize the status to avoid suprise */ for (i = 0; ids[i]; i++) { ids[i]->status = ID_UNKNOWN; } ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); state.dom = dom; state.ids = ids; state.allocate_unmapped = false; ret = idmap_tdb_sids_to_unixids_action(ctx->db, &state); if (NT_STATUS_EQUAL(ret, STATUS_SOME_UNMAPPED) && !dom->read_only) { state.allocate_unmapped = true; ret = dbwrap_trans_do(ctx->db, idmap_tdb_sids_to_unixids_action, &state); } return ret; }
NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key) { NTSTATUS status; status = dbwrap_trans_do(db, dbwrap_delete_action, &key); return status; }
static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_map *map) { struct idmap_tdb_context *ctx; NTSTATUS ret; char *ksidstr, *kidstr; struct idmap_tdb_set_mapping_context state; if (!map || !map->sid) { return NT_STATUS_INVALID_PARAMETER; } ksidstr = kidstr = NULL; /* TODO: should we filter a set_mapping using low/high filters ? */ ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); switch (map->xid.type) { case ID_TYPE_UID: kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id); break; case ID_TYPE_GID: kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id); break; default: DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type)); return NT_STATUS_INVALID_PARAMETER; } if (kidstr == NULL) { DEBUG(0, ("ERROR: Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } ksidstr = sid_string_talloc(ctx, map->sid); if (ksidstr == NULL) { DEBUG(0, ("Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } state.ksidstr = ksidstr; state.kidstr = kidstr; ret = dbwrap_trans_do(ctx->db, idmap_tdb_set_mapping_action, &state); done: talloc_free(ksidstr); talloc_free(kidstr); return ret; }
NTSTATUS dbwrap_trans_traverse(struct db_context *db, int (*f)(struct db_record*, void*), void *private_data) { struct dbwrap_trans_traverse_action_ctx ctx = { .f = f, .private_data = private_data, }; return dbwrap_trans_do(db, dbwrap_trans_traverse_action, &ctx); }
WERROR init_registry_data(void) { WERROR werr; TALLOC_CTX *frame = talloc_stackframe(); struct regval_ctr *values; int i; /* * First, check for the existence of the needed keys and values. * If all do already exist, we can save the writes. */ for (i=0; builtin_registry_paths[i] != NULL; i++) { if (!regdb_key_exists(regdb, builtin_registry_paths[i])) { goto do_init; } } for (i=0; builtin_registry_values[i].path != NULL; i++) { werr = regval_ctr_init(frame, &values); W_ERROR_NOT_OK_GOTO_DONE(werr); regdb_fetch_values_internal(regdb, builtin_registry_values[i].path, values); if (!regval_ctr_value_exists(values, builtin_registry_values[i].valuename)) { TALLOC_FREE(values); goto do_init; } TALLOC_FREE(values); } werr = WERR_OK; goto done; do_init: /* * There are potentially quite a few store operations which are all * indiviually wrapped in tdb transactions. Wrapping them in a single * transaction gives just a single transaction_commit() to actually do * its fsync()s. See tdb/common/transaction.c for info about nested * transaction behaviour. */ werr = ntstatus_to_werror(dbwrap_trans_do(regdb, init_registry_data_action, NULL)); done: TALLOC_FREE(frame); return werr; }
static NTSTATUS idmap_tdb_allocate_id(struct idmap_domain *dom, struct unixid *xid) { const char *hwmkey; const char *hwmtype; uint32_t high_hwm; uint32_t hwm = 0; NTSTATUS status; struct idmap_tdb_allocate_id_context state; struct idmap_tdb_context *ctx; ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); /* Get current high water mark */ switch (xid->type) { case ID_TYPE_UID: hwmkey = HWM_USER; hwmtype = "UID"; break; case ID_TYPE_GID: hwmkey = HWM_GROUP; hwmtype = "GID"; break; default: DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type)); return NT_STATUS_INVALID_PARAMETER; } high_hwm = dom->high_id; state.hwm = hwm; state.high_hwm = high_hwm; state.hwmtype = hwmtype; state.hwmkey = hwmkey; status = dbwrap_trans_do(ctx->db, idmap_tdb_allocate_id_action, &state); if (NT_STATUS_IS_OK(status)) { xid->id = state.hwm; DEBUG(10,("New %s = %d\n", hwmtype, state.hwm)); } else { DEBUG(1, ("Error allocating a new %s\n", hwmtype)); } return status; }
NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, int flag) { NTSTATUS status; struct dbwrap_store_context store_ctx; store_ctx.key = &key; store_ctx.dbuf = &dbuf; store_ctx.flag = flag; status = dbwrap_trans_do(db, dbwrap_store_action, &store_ctx); return status; }
/** * Initialize a key in the registry: * create each component key of the specified path, * wrapped in one db transaction. */ WERROR init_registry_key(const char *add_path) { struct init_registry_key_context init_ctx; if (regdb_key_exists(regdb, add_path)) { return WERR_OK; } init_ctx.add_path = add_path; return ntstatus_to_werror(dbwrap_trans_do(regdb, init_registry_key_action, &init_ctx)); }
static WERROR regdb_trans_do(struct db_context *db, NTSTATUS (*action)(struct db_context *, void *), void *private_data) { NTSTATUS status; struct regdb_trans_ctx ctx; ctx.action = action; ctx.private_data = private_data; status = dbwrap_trans_do(db, regdb_trans_do_action, &ctx); return ntstatus_to_werror(status); }
NTSTATUS dbwrap_trans_change_int32_atomic_bystring(struct db_context *db, const char *keystr, int32_t *oldval, int32_t change_val) { NTSTATUS ret; struct dbwrap_change_int32_atomic_context state; state.key = string_term_tdb_data(keystr); state.oldval = oldval; state.change_val = change_val; ret = dbwrap_trans_do(db, dbwrap_change_int32_atomic_action, &state); return ret; }
NTSTATUS dbwrap_trans_change_uint32_atomic(struct db_context *db, const char *keystr, uint32_t *oldval, uint32_t change_val) { NTSTATUS ret; struct dbwrap_change_uint32_atomic_context state; state.keystr = keystr; state.oldval = oldval; state.change_val = change_val; ret = dbwrap_trans_do(db, dbwrap_change_uint32_atomic_action, &state); return ret; }
NTSTATUS idmap_tdb_common_sids_to_unixids(struct idmap_domain * dom, struct id_map ** ids) { NTSTATUS ret; int i; struct idmap_tdb_common_sids_to_unixids_context state; struct idmap_tdb_common_context *ctx; ctx = talloc_get_type_abort(dom->private_data, struct idmap_tdb_common_context); /* initialize the status to avoid surprise */ for (i = 0; ids[i]; i++) { ids[i]->status = ID_UNKNOWN; } state.dom = dom; state.ids = ids; state.allocate_unmapped = false; if (ctx->sid_to_unixid_fn == NULL) { state.sid_to_unixid_fn = idmap_tdb_common_sid_to_unixid; } else { state.sid_to_unixid_fn = ctx->sid_to_unixid_fn; } ret = idmap_tdb_common_sids_to_unixids_action(ctx->db, &state); if ( (NT_STATUS_EQUAL(ret, STATUS_SOME_UNMAPPED) || NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) && !dom->read_only) { state.allocate_unmapped = true; ret = dbwrap_trans_do(ctx->db, idmap_tdb_common_sids_to_unixids_action, &state); } return ret; }