1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r4204: Arguments to reg_del_key more like the RPC for more efficient usage

Fix small bug in regpatch
Fix segfault in regshell cmdline completion
Implement set_value and del_value in ldb backend
This commit is contained in:
Jelmer Vernooij 2004-12-14 20:49:18 +00:00 committed by Gerald (Jerry) Carter
parent 983f74c365
commit 8e2aa58abe
9 changed files with 175 additions and 198 deletions

View File

@ -131,11 +131,11 @@ struct hive_operations {
/* Key management */
WERROR (*add_key)(TALLOC_CTX *, struct registry_key *, const char *name, uint32_t access_mask, SEC_DESC *, struct registry_key **);
WERROR (*del_key)(struct registry_key *);
WERROR (*del_key)(struct registry_key *, const char *name);
WERROR (*flush_key) (struct registry_key *);
/* Value management */
WERROR (*set_value)(struct registry_key *, const char *name, int type, void *data, int len);
WERROR (*set_value)(struct registry_key *, const char *name, uint32 type, void *data, int len);
WERROR (*del_value)(struct registry_key *, const char *valname);
};

View File

@ -192,28 +192,6 @@ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *lo
return WERR_OK;
}
/* Open a key by name (including the predefined key name!) */
WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result)
{
struct registry_key *predef;
WERROR error;
int predeflength;
char *predefname;
if(strchr(name, '\\')) predeflength = strchr(name, '\\')-name;
else predeflength = strlen(name);
predefname = strndup(name, predeflength);
error = reg_get_predefined_key_by_name(handle, predefname, &predef);
SAFE_FREE(predefname);
if(!W_ERROR_IS_OK(error)) {
return error;
}
return reg_open_key(mem_ctx, predef, name, result);
}
/* Open a key
* First tries to use the open_key function from the backend
* then falls back to get_subkey_by_name and later get_subkey_by_index
@ -409,123 +387,21 @@ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key,
return WERR_OK;
}
WERROR reg_key_del(struct registry_key *key)
WERROR reg_key_del(struct registry_key *parent, const char *name)
{
WERROR error;
if(!key) return WERR_INVALID_PARAM;
if(!parent) return WERR_INVALID_PARAM;
if(!key->hive->functions->del_key)
if(!parent->hive->functions->del_key)
return WERR_NOT_SUPPORTED;
error = key->hive->functions->del_key(key);
error = parent->hive->functions->del_key(parent, name);
if(!W_ERROR_IS_OK(error)) return error;
return WERR_OK;
}
WERROR reg_key_del_recursive(struct registry_key *key)
{
WERROR error = WERR_OK;
int i;
TALLOC_CTX *mem_ctx = talloc_init("del_recursive");
/* Delete all values for specified key */
for(i = 0; W_ERROR_IS_OK(error); i++) {
struct registry_value *val;
error = reg_key_get_value_by_index(mem_ctx, key, i, &val);
if(!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS))
{
talloc_destroy(mem_ctx);
return error;
}
if(W_ERROR_IS_OK(error)) {
error = reg_del_value(key, val->name);
if(!W_ERROR_IS_OK(error)) {
talloc_destroy(mem_ctx);
return error;
}
}
}
error = WERR_OK;
/* Delete all keys below this one */
for(i = 0; W_ERROR_IS_OK(error); i++) {
struct registry_key *subkey;
error = reg_key_get_subkey_by_index(mem_ctx, key, i, &subkey);
if(!W_ERROR_IS_OK(error)) { talloc_destroy(mem_ctx); return error; }
error = reg_key_del_recursive(subkey);
if(!W_ERROR_IS_OK(error)) { talloc_destroy(mem_ctx); return error; }
}
talloc_destroy(mem_ctx);
return reg_key_del(key);
}
WERROR reg_key_add_name_recursive_abs(struct registry_context *handle, const char *name)
{
struct registry_key *hive;
WERROR error;
int hivelength;
char *hivename;
if(strchr(name, '\\')) hivelength = strchr(name, '\\')-name;
else hivelength = strlen(name);
hivename = strndup(name, hivelength);
error = reg_get_predefined_key_by_name(handle, hivename, &hive);
SAFE_FREE(hivename);
if(!W_ERROR_IS_OK(error)) return error;
return reg_key_add_name_recursive(hive, name);
}
WERROR reg_key_add_name_recursive(struct registry_key *parent, const char *path)
{
struct registry_key *cur, *prevcur = parent;
WERROR error = WERR_OK;
char *dups, *begin, *end;
TALLOC_CTX *mem_ctx = talloc_init("add_recursive");
begin = dups = strdup(path);
while(1) {
end = strchr(begin, '\\');
if(end) *end = '\0';
error = reg_key_get_subkey_by_name(mem_ctx, prevcur, begin, &cur);
/* Key is not there, add it */
if(W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) {
error = reg_key_add_name(mem_ctx, prevcur, begin, 0, NULL, &cur);
if(!W_ERROR_IS_OK(error)) break;
}
if(!W_ERROR_IS_OK(error)) {
if(end) *end = '\\';
break;
}
if(!end) {
error = WERR_OK;
break;
}
*end = '\\';
begin = end+1;
prevcur = cur;
}
SAFE_FREE(dups);
talloc_destroy(mem_ctx);
return error;
}
WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, SEC_DESC *desc, struct registry_key **newkey)
{
WERROR error;
@ -547,7 +423,7 @@ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, struct registry_key *parent, const
return WERR_OK;
}
WERROR reg_val_set(struct registry_key *key, const char *value, int type, void *data, int len)
WERROR reg_val_set(struct registry_key *key, const char *value, uint32 type, void *data, int len)
{
/* A 'real' set function has preference */
if (key->hive->functions->set_value)
@ -577,27 +453,6 @@ WERROR reg_save (struct registry_context *ctx, const char *location)
return WERR_NOT_SUPPORTED;
}
WERROR reg_key_get_parent(TALLOC_CTX *mem_ctx, struct registry_key *key, struct registry_key **parent)
{
char *parent_name;
char *last;
struct registry_key *root = NULL;
WERROR error;
parent_name = strdup(key->path);
last = strrchr(parent_name, '\\');
if(!last) {
SAFE_FREE(parent_name);
return WERR_FOOBAR;
}
*last = '\0';
error = reg_open_key(mem_ctx, root, parent_name, parent);
SAFE_FREE(parent_name);
return error;
}
WERROR reg_key_flush(struct registry_key *key)
{
if (!key) {

View File

@ -150,3 +150,90 @@ char *reg_path_unix2win(char *path)
}
return path;
}
/* Open a key by name (including the predefined key name!) */
WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result)
{
struct registry_key *predef;
WERROR error;
int predeflength;
char *predefname;
if(strchr(name, '\\')) predeflength = strchr(name, '\\')-name;
else predeflength = strlen(name);
predefname = strndup(name, predeflength);
error = reg_get_predefined_key_by_name(handle, predefname, &predef);
SAFE_FREE(predefname);
if(!W_ERROR_IS_OK(error)) {
return error;
}
if (strchr(name, '\\')) {
return reg_open_key(mem_ctx, predef, strchr(name, '\\')+1, result);
} else {
*result = predef;
return WERR_OK;
}
}
static WERROR get_abs_parent(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, struct registry_key **parent, const char **name)
{
char *parent_name;
WERROR error;
if (strchr(path, '\\') == NULL) {
return WERR_FOOBAR;
}
parent_name = talloc_strndup(mem_ctx, path, strrchr(path, '\\')-1-path);
error = reg_open_key_abs(mem_ctx, ctx, parent_name, parent);
if (!W_ERROR_IS_OK(error)) {
return error;
}
*name = talloc_strdup(mem_ctx, strchr(path, '\\')+1);
return WERR_OK;
}
WERROR reg_key_del_abs(struct registry_context *ctx, const char *path)
{
struct registry_key *parent;
const char *n;
TALLOC_CTX *mem_ctx = talloc_init("reg_key_del_abs");
WERROR error;
if (!strchr(path, '\\')) {
return WERR_FOOBAR;
}
error = get_abs_parent(mem_ctx, ctx, path, &parent, &n);
if (W_ERROR_IS_OK(error)) {
error = reg_key_del(parent, n);
}
talloc_destroy(mem_ctx);
return error;
}
WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, uint32 access_mask, SEC_DESC *sec_desc, struct registry_key **result)
{
struct registry_key *parent;
const char *n;
WERROR error;
if (!strchr(path, '\\')) {
return WERR_FOOBAR;
}
error = get_abs_parent(mem_ctx, ctx, path, &parent, &n);
if (W_ERROR_IS_OK(error)) {
error = reg_key_add_name(mem_ctx, parent, n, access_mask, sec_desc, result);
}
return error;
}

View File

@ -34,9 +34,16 @@ static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent,
return WERR_INVALID_PARAM;
}
static WERROR reg_dir_del_key(struct registry_key *k)
static WERROR reg_dir_del_key(struct registry_key *k, const char *name)
{
return (rmdir((char *)k->backend_data) == 0)?WERR_OK:WERR_GENERAL_FAILURE;
char *child = talloc_asprintf(NULL, "%s/%s", (char *)k->backend_data, name);
WERROR ret;
if (rmdir(child) == 0) ret = WERR_OK; else ret = WERR_GENERAL_FAILURE;
talloc_destroy(child);
return ret;
}
static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, struct registry_key *p, const char *name, struct registry_key **subkey)

View File

@ -235,12 +235,15 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, struct registry_key *parent, con
return WERR_OK;
}
static WERROR ldb_del_key (struct registry_key *key)
static WERROR ldb_del_key (struct registry_key *key, const char *child)
{
int ret;
struct ldb_key_data *kd = key->backend_data;
char *childdn = talloc_asprintf(NULL, "key=%s,%s", child, kd->dn);
ret = ldb_delete(key->hive->backend_data, kd->dn);
ret = ldb_delete(key->hive->backend_data, childdn);
talloc_destroy(childdn);
if (ret < 0) {
DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(key->hive->backend_data)));
@ -250,6 +253,59 @@ static WERROR ldb_del_key (struct registry_key *key)
return WERR_OK;
}
static WERROR ldb_del_value (struct registry_key *key, const char *child)
{
int ret;
struct ldb_key_data *kd = key->backend_data;
char *childdn = talloc_asprintf(NULL, "value=%s,%s", child, kd->dn);
ret = ldb_delete(key->hive->backend_data, childdn);
talloc_destroy(childdn);
if (ret < 0) {
DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(key->hive->backend_data)));
return WERR_FOOBAR;
}
return WERR_OK;
}
static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint32 type, void *data, int len)
{
struct ldb_context *ctx = parent->hive->backend_data;
struct ldb_message msg;
struct ldb_val val;
int ret;
char *type_s;
TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value");
ZERO_STRUCT(msg);
msg.dn = reg_path_to_ldb(mem_ctx, parent->path, talloc_asprintf(mem_ctx, "value=%s,", name));
ldb_msg_add_string(ctx, &msg, "value", talloc_strdup(mem_ctx, name));
val.length = len;
val.data = data;
ldb_msg_add_value(ctx, &msg, "data", &val);
type_s = talloc_asprintf(mem_ctx, "%u", type);
ldb_msg_add_string(ctx, &msg, "type", type_s);
ret = ldb_add(ctx, &msg);
if (ret < 0) {
ret = ldb_modify(ctx, &msg);
if (ret < 0) {
DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parent->hive->backend_data)));
talloc_destroy(mem_ctx);
return WERR_FOOBAR;
}
}
talloc_destroy(mem_ctx);
return WERR_OK;
}
static struct hive_operations reg_backend_ldb = {
.name = "ldb",
.add_key = ldb_add_key,
@ -258,6 +314,8 @@ static struct hive_operations reg_backend_ldb = {
.open_key = ldb_open_key,
.get_value_by_index = ldb_get_value_by_id,
.get_subkey_by_index = ldb_get_subkey_by_id,
.set_value = ldb_set_value,
.del_value = ldb_del_value,
};
NTSTATUS registry_ldb_init(void)

View File

@ -315,27 +315,17 @@ static WERROR rpc_query_key(struct registry_key *k)
return r.out.result;
}
static WERROR rpc_del_key(struct registry_key *k)
static WERROR rpc_del_key(struct registry_key *parent, const char *name)
{
NTSTATUS status;
struct rpc_key_data *mykeydata = k->backend_data;
struct rpc_key_data *mykeydata = parent->backend_data;
struct winreg_DeleteKey r;
struct registry_key *parent;
WERROR error;
TALLOC_CTX *mem_ctx = talloc_init("del_key");
error = reg_key_get_parent(mem_ctx, k, &parent);
if(!W_ERROR_IS_OK(error)) {
talloc_destroy(mem_ctx);
return error;
}
mykeydata = parent->backend_data;
r.in.handle = &mykeydata->pol;
init_winreg_String(&r.in.key, k->name);
init_winreg_String(&r.in.key, name);
status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r);
status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r);
talloc_destroy(mem_ctx);

View File

@ -686,13 +686,7 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd
/* If we found it, apply the other bits, else create such a key */
if (W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) {
if(W_ERROR_IS_OK(reg_key_add_name_recursive_abs(r, cmd->key))) {
error = reg_open_key_abs(mem_ctx, r, cmd->key, &tmp);
if(!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Error finding new key '%s' after it has been added\n", cmd->key));
continue;
}
} else {
if(!W_ERROR_IS_OK(reg_key_add_abs(mem_ctx, r, cmd->key, 0, NULL, &tmp))) {
DEBUG(0, ("Error adding new key '%s'\n", cmd->key));
continue;
}
@ -730,13 +724,7 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd
* Find the key if it exists, and delete it ...
*/
error = reg_open_key_abs(mem_ctx, r, cmd->key, &tmp);
if(!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Unable to open key '%s'\n", cmd->key));
continue;
}
error = reg_key_del_recursive(tmp);
error = reg_key_del_abs(r, cmd->key);
if(!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Unable to delete key '%s'\n", cmd->key));
continue;

View File

@ -120,18 +120,12 @@ static struct registry_key *cmd_mkkey(TALLOC_CTX *mem_ctx, struct registry_key *
static struct registry_key *cmd_rmkey(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv)
{
struct registry_key *key;
if(argc < 2) {
fprintf(stderr, "Usage: rmkey <name>\n");
return NULL;
}
if(!W_ERROR_IS_OK(reg_open_key(mem_ctx, cur, argv[1], &key))) {
fprintf(stderr, "No such subkey '%s'\n", argv[1]);
return NULL;
}
if(!W_ERROR_IS_OK(reg_key_del(key))) {
if(!W_ERROR_IS_OK(reg_key_del(cur, argv[1]))) {
fprintf(stderr, "Error deleting '%s'\n", argv[1]);
} else {
fprintf(stderr, "Successfully deleted '%s'\n", argv[1]);
@ -259,9 +253,10 @@ static char **reg_complete_command(const char *text, int end)
return matches;
cleanup:
while (i >= 0) {
free(matches[i]);
i--;
count--;
while (count >= 0) {
free(matches[count]);
count--;
}
free(matches);
return NULL;

View File

@ -126,16 +126,13 @@ static WERROR winreg_DeleteKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
struct winreg_DeleteKey *r)
{
struct dcesrv_handle *h;
struct registry_key *key;
WERROR result;
h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
DCESRV_CHECK_HANDLE(h);
result = reg_open_key(mem_ctx, (struct registry_key *)h->data, r->in.key.name, &key);
if (W_ERROR_IS_OK(result)) {
return reg_key_del(key);
return reg_key_del((struct registry_key *)h->data, r->in.key.name);
}
return result;