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:
parent
983f74c365
commit
8e2aa58abe
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user