diff options
-rw-r--r-- | source4/lib/registry/reg_backend_rpc.c | 19 | ||||
-rw-r--r-- | source4/librpc/idl/winreg.idl | 32 | ||||
-rw-r--r-- | source4/rpc_server/winreg/rpc_winreg.c | 25 | ||||
-rw-r--r-- | source4/torture/rpc/winreg.c | 29 |
4 files changed, 69 insertions, 36 deletions
diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 5734b96770..44de3bcd77 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -29,14 +29,7 @@ static struct hive_operations reg_backend_rpc; static void init_winreg_String(struct winreg_String *name, const char *s) { - name->name = s; - if (s) { - name->name_len = 2 * (strlen_m(s) + 1); - name->name_size = name->name_len; - } else { - name->name_len = 0; - name->name_size = 0; - } + name->name = s; } @@ -255,14 +248,14 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, cons NTSTATUS status; struct winreg_CreateKey r; - init_winreg_String(&r.in.key, name); + init_winreg_String(&r.in.name, name); init_winreg_String(&r.in.class, NULL); r.in.handle = parent->backend_data; - r.out.handle = talloc(mem_ctx, struct policy_handle); + r.out.new_handle = talloc(mem_ctx, struct policy_handle); r.in.options = 0; - r.in.access_mask = access_mask; - r.in.sec_desc = NULL; + r.in.access_required = access_mask; + r.in.secdesc = NULL; status = dcerpc_winreg_CreateKey((struct dcerpc_pipe *)(parent->hive->backend_data), mem_ctx, &r); @@ -274,7 +267,7 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, cons if (W_ERROR_IS_OK(r.out.result)) { *key = talloc(mem_ctx, struct registry_key); (*key)->name = talloc_strdup(*key, name); - (*key)->backend_data = r.out.handle; + (*key)->backend_data = r.out.new_handle; } return r.out.result; diff --git a/source4/librpc/idl/winreg.idl b/source4/librpc/idl/winreg.idl index cfde8bfdbc..a6e2d53286 100644 --- a/source4/librpc/idl/winreg.idl +++ b/source4/librpc/idl/winreg.idl @@ -83,14 +83,28 @@ /******************/ /* Function: 0x06 */ + + typedef struct { + [size_is(size),length_is(len)] uint8 *data; + uint32 size; + uint32 len; + } KeySecurityData; + + typedef struct { + uint32 length; + KeySecurityData sd; + bool8 inherit; + } winreg_SecBuf; + WERROR winreg_CreateKey( - [in,out,ref] policy_handle *handle, - [in] winreg_String key, + [in,ref] policy_handle *handle, + [in] winreg_String name, [in] winreg_String class, [in] uint32 options, - [in] uint32 access_mask, - [in,out,ref] uint32 *action_taken, - [in] sec_desc_buf *sec_desc + [in] uint32 access_required, + [in,unique] winreg_SecBuf *secdesc, + [out,ref] policy_handle *new_handle, + [in,out,unique] uint32 *action_taken ); /******************/ @@ -143,18 +157,12 @@ [in,ref] policy_handle *handle ); - typedef struct { - [size_is(size),length_is(len)] uint8 *data; - uint32 size; - uint32 len; - } KeySecurityData; - /******************/ /* Function: 0x0c */ WERROR winreg_GetKeySecurity( [in,ref] policy_handle *handle, [in] uint32 access_mask, - [in,out,ref] KeySecurityData *data + [in,out,ref] KeySecurityData *sd ); /******************/ diff --git a/source4/rpc_server/winreg/rpc_winreg.c b/source4/rpc_server/winreg/rpc_winreg.c index e20d9aa6b6..f03ca2fa86 100644 --- a/source4/rpc_server/winreg/rpc_winreg.c +++ b/source4/rpc_server/winreg/rpc_winreg.c @@ -99,17 +99,34 @@ static WERROR winreg_CreateKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *m { struct dcesrv_handle *h, *newh; WERROR error; + struct security_descriptor sd; DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY); - error = reg_key_add_name(newh, (struct registry_key *)h->data, r->in.key.name, - r->in.access_mask, - r->in.sec_desc?r->in.sec_desc->sd:NULL, + /* the security descriptor is optional */ + if (r->in.secdesc != NULL) { + DATA_BLOB sdblob; + NTSTATUS status; + sdblob.data = r->in.secdesc->sd.data; + sdblob.length = r->in.secdesc->sd.len; + if (sdblob.data == NULL) { + return WERR_INVALID_PARAM; + } + status = ndr_pull_struct_blob_all(&sdblob, mem_ctx, &sd, + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); + if (!NT_STATUS_IS_OK(status)) { + return WERR_INVALID_PARAM; + } + } + + error = reg_key_add_name(newh, (struct registry_key *)h->data, r->in.name.name, + r->in.access_required, + r->in.secdesc?&sd:NULL, (struct registry_key **)&newh->data); if (W_ERROR_IS_OK(error)) { - r->out.handle = &newh->wire_handle; + r->out.new_handle = &newh->wire_handle; } else { talloc_free(newh); } diff --git a/source4/torture/rpc/winreg.c b/source4/torture/rpc/winreg.c index 7d40147a8d..2cf52a2686 100644 --- a/source4/torture/rpc/winreg.c +++ b/source4/torture/rpc/winreg.c @@ -108,13 +108,13 @@ static BOOL test_CreateKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, printf("\ntesting CreateKey\n"); r.in.handle = handle; - r.out.handle = &newhandle; - init_winreg_String(&r.in.key, name); + r.out.new_handle = &newhandle; + init_winreg_String(&r.in.name, name); init_winreg_String(&r.in.class, class); r.in.options = 0x0; - r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED; r.in.action_taken = r.out.action_taken = &action_taken; - r.in.sec_desc = NULL; + r.in.secdesc = NULL; status = dcerpc_winreg_CreateKey(p, mem_ctx, &r); @@ -136,14 +136,16 @@ static BOOL test_GetKeySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct winreg_GetKeySecurity r; + struct security_descriptor sd; + DATA_BLOB sdblob; printf("\ntesting GetKeySecurity\n"); ZERO_STRUCT(r); r.in.handle = handle; - r.in.data = r.out.data = talloc_zero(mem_ctx, struct KeySecurityData); - r.in.data->size = 0xffff; + r.in.sd = r.out.sd = talloc_zero(mem_ctx, struct KeySecurityData); + r.in.sd->size = 0xffff; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; status = dcerpc_winreg_GetKeySecurity(p, mem_ctx, &r); @@ -158,7 +160,20 @@ static BOOL test_GetKeySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return False; } - return False; + sdblob.data = r.out.sd->data; + sdblob.length = r.out.sd->len; + + status = ndr_pull_struct_blob_all(&sdblob, mem_ctx, &sd, + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); + if (!NT_STATUS_IS_OK(status)) { + printf("pull_security_descriptor failed - %s\n", nt_errstr(status)); + return False; + } + if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) { + NDR_PRINT_DEBUG(security_descriptor, &sd); + } + + return True; } static BOOL test_CloseKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, |