summaryrefslogtreecommitdiff
path: root/source4/rpc_server
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2008-03-28 00:44:14 +0100
committerJelmer Vernooij <jelmer@samba.org>2008-03-28 00:44:14 +0100
commit18d80bdf1fc5a281358aef29324230698eb434d4 (patch)
treee2515f11577052f42a227bc04541d572d7f2e1ff /source4/rpc_server
parentac604330871504e88e4bcd37433bbf3717d97a88 (diff)
parente15b35e3897e63b9e815a04101436439d4aebdef (diff)
downloadsamba-18d80bdf1fc5a281358aef29324230698eb434d4.tar.gz
samba-18d80bdf1fc5a281358aef29324230698eb434d4.tar.bz2
samba-18d80bdf1fc5a281358aef29324230698eb434d4.zip
Merge v4.0-test
(This used to be commit 977dbdeaf363c8905ed9fd0570eba4be80582833)
Diffstat (limited to 'source4/rpc_server')
-rw-r--r--source4/rpc_server/lsa/dcesrv_lsa.c71
-rw-r--r--source4/rpc_server/lsa/lsa_lookup.c1
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c138
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.h2
-rw-r--r--source4/rpc_server/winreg/rpc_winreg.c233
5 files changed, 302 insertions, 143 deletions
diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c
index 4375088e17..429c413b98 100644
--- a/source4/rpc_server/lsa/dcesrv_lsa.c
+++ b/source4/rpc_server/lsa/dcesrv_lsa.c
@@ -99,8 +99,21 @@ static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX
int ret;
DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
+
if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
struct lsa_secret_state *secret_state = h->data;
+
+ /* Ensure user is permitted to delete this... */
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ break;
+ default:
+ /* Users and annonymous are not allowed delete things */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
ret = ldb_delete(secret_state->sam_ldb,
secret_state->secret_dn);
talloc_free(h);
@@ -446,6 +459,8 @@ static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TAL
/*
lsa_CreateAccount
+
+ This call does not seem to have any long-term effects, hence no database operations
*/
static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct lsa_CreateAccount *r)
@@ -644,9 +659,26 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_cal
/* create the trusted_domain */
ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
- if (ret != LDB_SUCCESS) {
- DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
- ldb_dn_get_linearized(msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
+ switch (ret) {
+ case LDB_SUCCESS:
+ break;
+ case LDB_ERR_ENTRY_ALREADY_EXISTS:
+ ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
+ DEBUG(0,("Failed to create trusted domain record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(trusted_domain_state->policy->sam_ldb)));
+ return NT_STATUS_DOMAIN_EXISTS;
+ case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+ ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
+ DEBUG(0,("Failed to create trusted domain record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(trusted_domain_state->policy->sam_ldb)));
+ return NT_STATUS_ACCESS_DENIED;
+ default:
+ ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
+ DEBUG(0,("Failed to create user record %s: %s\n",
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(trusted_domain_state->policy->sam_ldb)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -1656,6 +1688,16 @@ static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALL
DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
ZERO_STRUCTP(r->out.sec_handle);
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ break;
+ default:
+ /* Users and annonymous are not allowed create secrets */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
policy_state = policy_handle->data;
if (!r->in.name.string) {
@@ -1802,6 +1844,16 @@ static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC
return NT_STATUS_INVALID_PARAMETER;
}
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ break;
+ default:
+ /* Users and annonymous are not allowed to access secrets */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
secret_state = talloc(mem_ctx, struct lsa_secret_state);
if (!secret_state) {
return NT_STATUS_NO_MEMORY;
@@ -1833,10 +1885,10 @@ static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC
}
} else {
+ secret_state->global = false;
secret_state->sam_ldb = talloc_reference(secret_state,
secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
- secret_state->global = false;
name = r->in.name.string;
if (strlen(name) < 1) {
return NT_STATUS_INVALID_PARAMETER;
@@ -2068,6 +2120,17 @@ static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLO
DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
+ /* Ensure user is permitted to read this... */
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ break;
+ default:
+ /* Users and annonymous are not allowed to read secrets */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
secret_state = h->data;
/* pull all the user attributes */
diff --git a/source4/rpc_server/lsa/lsa_lookup.c b/source4/rpc_server/lsa/lsa_lookup.c
index bcc2af97a7..e01efa8233 100644
--- a/source4/rpc_server/lsa/lsa_lookup.c
+++ b/source4/rpc_server/lsa/lsa_lookup.c
@@ -220,6 +220,7 @@ static NTSTATUS dcesrv_lsa_lookup_name(struct loadparm_context *lp_ctx,
} else if (strchr_m(name, '@')) {
status = crack_name_to_nt4_name(mem_ctx, lp_ctx, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, name, &domain, &username);
if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n", name, nt_errstr(status)));
return status;
}
} else {
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index 8193e0a882..0aa4d65d8c 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -324,11 +324,11 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
struct samr_connect_state *c_state;
struct dcesrv_handle *h;
struct samr_SamArray *array;
- int count, i, start_i;
+ int i, start_i, ret;
const char * const dom_attrs[] = { "cn", NULL};
const char * const ref_attrs[] = { "nETBIOSName", NULL};
- struct ldb_message **dom_msgs;
- struct ldb_message **ref_msgs;
+ struct ldb_result *dom_res;
+ struct ldb_result *ref_res;
struct ldb_dn *partitions_basedn;
*r->out.resume_handle = 0;
@@ -341,19 +341,18 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
partitions_basedn = samdb_partitions_dn(c_state->sam_ctx, mem_ctx);
- count = gendb_search(c_state->sam_ctx,
- mem_ctx, NULL, &dom_msgs, dom_attrs,
- "(objectClass=domain)");
- if (count == -1) {
- DEBUG(0,("samdb: no domains found in EnumDomains\n"));
+ ret = ldb_search_exp_fmt(c_state->sam_ctx, mem_ctx, &dom_res, ldb_get_default_basedn(c_state->sam_ctx),
+ LDB_SCOPE_SUBTREE, dom_attrs, "(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))");
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0,("samdb: unable to find domains: %s\n", ldb_errstring(c_state->sam_ctx)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- *r->out.resume_handle = count;
+ *r->out.resume_handle = dom_res->count;
start_i = *r->in.resume_handle;
- if (start_i >= count) {
+ if (start_i >= dom_res->count) {
/* search past end of list is not an error for this call */
return NT_STATUS_OK;
}
@@ -366,23 +365,27 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
array->count = 0;
array->entries = NULL;
- array->entries = talloc_array(mem_ctx, struct samr_SamEntry, count - start_i);
+ array->entries = talloc_array(mem_ctx, struct samr_SamEntry, dom_res->count - start_i);
if (array->entries == NULL) {
return NT_STATUS_NO_MEMORY;
}
- for (i=0;i<count-start_i;i++) {
- int ret;
+ for (i=0;i<dom_res->count-start_i;i++) {
array->entries[i].idx = start_i + i;
/* try and find the domain */
- ret = gendb_search(c_state->sam_ctx, mem_ctx, partitions_basedn,
- &ref_msgs, ref_attrs,
- "(&(objectClass=crossRef)(ncName=%s))",
- ldb_dn_get_linearized(dom_msgs[i]->dn));
- if (ret == 1) {
- array->entries[i].name.string = samdb_result_string(ref_msgs[0], "nETBIOSName", NULL);
+ ret = ldb_search_exp_fmt(c_state->sam_ctx, mem_ctx, &ref_res, partitions_basedn,
+ LDB_SCOPE_SUBTREE, ref_attrs, "(&(objectClass=crossRef)(ncName=%s))",
+ ldb_dn_get_linearized(dom_res->msgs[i]->dn));
+
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0,("samdb: unable to find domains: %s\n", ldb_errstring(c_state->sam_ctx)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ if (ref_res->count == 1) {
+ array->entries[i].name.string = samdb_result_string(ref_res->msgs[0], "nETBIOSName", NULL);
} else {
- array->entries[i].name.string = samdb_result_string(dom_msgs[i], "cn", NULL);
+ array->entries[i].name.string = samdb_result_string(dom_res->msgs[i], "cn", NULL);
}
}
@@ -425,7 +428,7 @@ static NTSTATUS dcesrv_samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLO
ret = gendb_search(c_state->sam_ctx,
mem_ctx, NULL, &dom_msgs, dom_attrs,
- "(&(objectSid=%s)(&(|(objectclass=domain)(objectClass=builtinDomain))))",
+ "(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))",
ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid));
if (ret == 0) {
return NT_STATUS_NO_SUCH_DOMAIN;
@@ -472,6 +475,14 @@ static NTSTATUS dcesrv_samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLO
}
d_state->access_mask = r->in.access_mask;
+ if (dom_sid_equal(d_state->domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
+ d_state->builtin = true;
+ } else {
+ d_state->builtin = false;
+ }
+
+ d_state->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
+
h_domain = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_DOMAIN);
if (!h_domain) {
talloc_free(d_state);
@@ -520,6 +531,10 @@ static NTSTATUS dcesrv_samr_info_DomInfo2(struct samr_domain_state *state,
string */
info->primary.string = samdb_result_fsmo_name(state->sam_ctx, mem_ctx, dom_msgs[0], "fSMORoleOwner");
+ if (!info->primary.string) {
+ info->primary.string = lp_netbios_name(state->lp_ctx);
+ }
+
info->force_logoff_time = ldb_msg_find_attr_as_uint64(dom_msgs[0], "forceLogoff",
0x8000000000000000LL);
@@ -614,6 +629,10 @@ static NTSTATUS dcesrv_samr_info_DomInfo6(struct samr_domain_state *state,
info->primary.string = samdb_result_fsmo_name(state->sam_ctx, mem_ctx,
dom_msgs[0], "fSMORoleOwner");
+ if (!info->primary.string) {
+ info->primary.string = lp_netbios_name(state->lp_ctx);
+ }
+
return NT_STATUS_OK;
}
@@ -1004,6 +1023,11 @@ static NTSTATUS dcesrv_samr_CreateDomainGroup(struct dcesrv_call_state *dce_call
d_state = h->data;
+ if (d_state->builtin) {
+ DEBUG(5, ("Cannot create a domain group in the BUILTIN domain"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
groupname = r->in.name->string;
if (groupname == NULL) {
@@ -1130,9 +1154,6 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
if (ldb_cnt == -1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- if (ldb_cnt == 0 || r->in.max_size == 0) {
- return NT_STATUS_OK;
- }
/* convert to SamEntry format */
entries = talloc_array(mem_ctx, struct samr_SamEntry, ldb_cnt);
@@ -1166,10 +1187,6 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
first<count && entries[first].idx <= *r->in.resume_handle;
first++) ;
- if (first == count) {
- return NT_STATUS_OK;
- }
-
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 54 */
r->out.num_entries = count - first;
@@ -1234,6 +1251,10 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
d_state = h->data;
+ if (d_state->builtin) {
+ DEBUG(5, ("Cannot create a user in the BUILTIN domain"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
account_name = r->in.account_name->string;
if (account_name == NULL) {
@@ -1318,15 +1339,16 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
/* create the user */
ret = ldb_add(d_state->sam_ctx, msg);
switch (ret) {
- case LDB_SUCCESS:
+ case LDB_SUCCESS:
break;
- case LDB_ERR_ENTRY_ALREADY_EXISTS:
+ case LDB_ERR_ENTRY_ALREADY_EXISTS:
ldb_transaction_cancel(d_state->sam_ctx);
DEBUG(0,("Failed to create user record %s: %s\n",
ldb_dn_get_linearized(msg->dn),
ldb_errstring(d_state->sam_ctx)));
return NT_STATUS_USER_EXISTS;
- case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+ case LDB_ERR_UNWILLING_TO_PERFORM:
+ case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
ldb_transaction_cancel(d_state->sam_ctx);
DEBUG(0,("Failed to create user record %s: %s\n",
ldb_dn_get_linearized(msg->dn),
@@ -1466,8 +1488,8 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
{
struct dcesrv_handle *h;
struct samr_domain_state *d_state;
- struct ldb_message **res;
- int count, num_filtered_entries, i, first;
+ struct ldb_result *res;
+ int ret, num_filtered_entries, i, first;
struct samr_SamEntry *entries;
const char * const attrs[] = { "objectSid", "sAMAccountName", "userAccountControl", NULL };
@@ -1479,32 +1501,30 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
d_state = h->data;
- /* search for all users in this domain. This could possibly be cached and
- resumed based on resume_key */
- count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs,
- "objectclass=user");
- if (count == -1) {
+ /* don't have to worry about users in the builtin domain, as there are none */
+ ret = ldb_search_exp_fmt(d_state->sam_ctx, mem_ctx, &res, d_state->domain_dn, LDB_SCOPE_SUBTREE, attrs, "objectClass=user");
+
+ if (ret != LDB_SUCCESS) {
+ DEBUG(3, ("Failed to search for Domain Users in %s: %s\n",
+ ldb_dn_get_linearized(d_state->domain_dn), ldb_errstring(d_state->sam_ctx)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- if (count == 0 || r->in.max_size == 0) {
- return NT_STATUS_OK;
- }
/* convert to SamEntry format */
- entries = talloc_array(mem_ctx, struct samr_SamEntry, count);
+ entries = talloc_array(mem_ctx, struct samr_SamEntry, res->count);
if (!entries) {
return NT_STATUS_NO_MEMORY;
}
num_filtered_entries = 0;
- for (i=0;i<count;i++) {
+ for (i=0;i<res->count;i++) {
/* Check if a mask has been requested */
if (r->in.acct_flags
- && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, res[i],
+ && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, res->msgs[i],
d_state->domain_dn) & r->in.acct_flags) == 0)) {
continue;
}
- entries[num_filtered_entries].idx = samdb_result_rid_from_sid(mem_ctx, res[i], "objectSid", 0);
- entries[num_filtered_entries].name.string = samdb_result_string(res[i], "sAMAccountName", "");
+ entries[num_filtered_entries].idx = samdb_result_rid_from_sid(mem_ctx, res->msgs[i], "objectSid", 0);
+ entries[num_filtered_entries].name.string = samdb_result_string(res->msgs[i], "sAMAccountName", "");
num_filtered_entries++;
}
@@ -1566,6 +1586,11 @@ static NTSTATUS dcesrv_samr_CreateDomAlias(struct dcesrv_call_state *dce_call, T
d_state = h->data;
+ if (d_state->builtin) {
+ DEBUG(5, ("Cannot create a domain alias in the BUILTIN domain"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
alias_name = r->in.alias_name->string;
if (alias_name == NULL) {
@@ -2073,7 +2098,8 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
{
struct dcesrv_handle *h;
struct samr_account_state *a_state;
- struct ldb_message *msg, **res;
+ struct ldb_message *msg;
+ struct ldb_result *res;
const char * const attrs[4] = { "sAMAccountName", "description",
"numMembers", NULL };
int ret;
@@ -2083,14 +2109,22 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
a_state = h->data;
+
+ ret = ldb_search_exp_fmt(a_state->sam_ctx, mem_ctx, &res, a_state->account_dn, LDB_SCOPE_SUBTREE, attrs, "objectClass=*");
+
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ return NT_STATUS_NO_SUCH_GROUP;
+ } else if (ret != LDB_SUCCESS) {
+ DEBUG(2, ("Error reading group info: %s\n", ldb_errstring(a_state->sam_ctx)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
- /* pull all the group attributes */
- ret = gendb_search_dn(a_state->sam_ctx, mem_ctx,
- a_state->account_dn, &res, attrs);
- if (ret != 1) {
+ if (res->count != 1) {
+ DEBUG(2, ("Error finding group info, got %d entries\n", res->count));
+
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- msg = res[0];
+ msg = res->msgs[0];
/* allocate the info structure */
r->out.info = talloc(mem_ctx, union samr_GroupInfo);
diff --git a/source4/rpc_server/samr/dcesrv_samr.h b/source4/rpc_server/samr/dcesrv_samr.h
index 7a6978344b..a28a4bec43 100644
--- a/source4/rpc_server/samr/dcesrv_samr.h
+++ b/source4/rpc_server/samr/dcesrv_samr.h
@@ -52,6 +52,8 @@ struct samr_domain_state {
const char *domain_name;
struct ldb_dn *domain_dn;
enum server_role role;
+ bool builtin;
+ struct loadparm_context *lp_ctx;
};
/*
diff --git a/source4/rpc_server/winreg/rpc_winreg.c b/source4/rpc_server/winreg/rpc_winreg.c
index 681e3b918f..9993dc14c1 100644
--- a/source4/rpc_server/winreg/rpc_winreg.c
+++ b/source4/rpc_server/winreg/rpc_winreg.c
@@ -26,6 +26,7 @@
#include "rpc_server/common/common.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "param/param.h"
+#include "libcli/security/security.h"
enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY };
@@ -120,32 +121,39 @@ static WERROR dcesrv_winreg_CreateKey(struct dcesrv_call_state *dce_call,
newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
- /* the security descriptor is optional */
- if (r->in.secdesc != NULL) {
- DATA_BLOB sdblob;
- enum ndr_err_code ndr_err;
- sdblob.data = r->in.secdesc->sd.data;
- sdblob.length = r->in.secdesc->sd.len;
- if (sdblob.data == NULL) {
- return WERR_INVALID_PARAM;
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ /* the security descriptor is optional */
+ if (r->in.secdesc != NULL) {
+ DATA_BLOB sdblob;
+ enum ndr_err_code ndr_err;
+ sdblob.data = r->in.secdesc->sd.data;
+ sdblob.length = r->in.secdesc->sd.len;
+ if (sdblob.data == NULL) {
+ return WERR_INVALID_PARAM;
+ }
+ ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, NULL, &sd,
+ (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return WERR_INVALID_PARAM;
+ }
}
- ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, NULL, &sd,
- (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- return WERR_INVALID_PARAM;
+
+ error = reg_key_add_name(newh, (struct registry_key *)h->data,
+ r->in.name.name, NULL, r->in.secdesc?&sd:NULL,
+ (struct registry_key **)&newh->data);
+ if (W_ERROR_IS_OK(error)) {
+ r->out.new_handle = &newh->wire_handle;
+ } else {
+ talloc_free(newh);
}
+
+ return error;
+ default:
+ return WERR_ACCESS_DENIED;
}
-
- error = reg_key_add_name(newh, (struct registry_key *)h->data,
- r->in.name.name, NULL, r->in.secdesc?&sd:NULL,
- (struct registry_key **)&newh->data);
- if (W_ERROR_IS_OK(error)) {
- r->out.new_handle = &newh->wire_handle;
- } else {
- talloc_free(newh);
- }
-
- return error;
}
@@ -160,7 +168,14 @@ static WERROR dcesrv_winreg_DeleteKey(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
- return reg_key_del((struct registry_key *)h->data, r->in.key.name);
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ return reg_key_del((struct registry_key *)h->data, r->in.key.name);
+ default:
+ return WERR_ACCESS_DENIED;
+ }
}
@@ -176,9 +191,16 @@ static WERROR dcesrv_winreg_DeleteValue(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
- key = h->data;
-
- return reg_del_value(key, r->in.value.name);
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ key = h->data;
+
+ return reg_del_value(key, r->in.value.name);
+ default:
+ return WERR_ACCESS_DENIED;
+ }
}
@@ -289,7 +311,14 @@ static WERROR dcesrv_winreg_FlushKey(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
- return reg_key_flush(h->data);
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ return reg_key_flush(h->data);
+ default:
+ return WERR_ACCESS_DENIED;
+ }
}
@@ -342,23 +371,31 @@ static WERROR dcesrv_winreg_OpenKey(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE_FAULT(h, r->in.parent_handle, HTYPE_REGKEY);
- if (r->in.keyname.name && strcmp(r->in.keyname.name, "") == 0) {
- newh = talloc_reference(dce_call->context, h);
- result = WERR_OK;
- } else {
- newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
- result = reg_open_key(newh, (struct registry_key *)h->data,
- r->in.keyname.name,
- (struct registry_key **)&newh->data);
- }
-
- if (W_ERROR_IS_OK(result)) {
- r->out.handle = &newh->wire_handle;
- } else {
- talloc_free(newh);
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ case SECURITY_USER:
+ if (r->in.keyname.name && strcmp(r->in.keyname.name, "") == 0) {
+ newh = talloc_reference(dce_call->context, h);
+ result = WERR_OK;
+ } else {
+ newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
+ result = reg_open_key(newh, (struct registry_key *)h->data,
+ r->in.keyname.name,
+ (struct registry_key **)&newh->data);
+ }
+
+ if (W_ERROR_IS_OK(result)) {
+ r->out.handle = &newh->wire_handle;
+ } else {
+ talloc_free(newh);
+ }
+ return result;
+ default:
+ return WERR_ACCESS_DENIED;
}
- return result;
}
@@ -376,17 +413,25 @@ static WERROR dcesrv_winreg_QueryInfoKey(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
- k = h->data;
-
- ret = reg_key_get_info(mem_ctx, k, &classname, r->out.num_subkeys,
- r->out.num_values, r->out.last_changed_time,
- r->out.max_subkeylen, r->out.max_valnamelen,
- r->out.max_valbufsize);
-
- if (r->out.classname != NULL)
- r->out.classname->name = classname;
-
- return ret;
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ case SECURITY_USER:
+ k = h->data;
+
+ ret = reg_key_get_info(mem_ctx, k, &classname, r->out.num_subkeys,
+ r->out.num_values, r->out.last_changed_time,
+ r->out.max_subkeylen, r->out.max_valnamelen,
+ r->out.max_valbufsize);
+
+ if (r->out.classname != NULL)
+ r->out.classname->name = classname;
+
+ return ret;
+ default:
+ return WERR_ACCESS_DENIED;
+ }
}
@@ -405,35 +450,43 @@ static WERROR dcesrv_winreg_QueryValue(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
- key = h->data;
-
- result = reg_key_get_value_by_name(mem_ctx, key, r->in.value_name.name,
- &value_type, &value_data);
-
- if (!W_ERROR_IS_OK(result)) {
- return result;
- }
-
- /* Just asking for the size of the buffer */
- r->out.type = talloc(mem_ctx, uint32_t);
- if (!r->out.type) {
- return WERR_NOMEM;
- }
- *r->out.type = value_type;
- r->out.length = talloc(mem_ctx, uint32_t);
- if (!r->out.length) {
- return WERR_NOMEM;
- }
- *r->out.length = value_data.length;
- if (r->in.data == NULL) {
- r->out.size = talloc(mem_ctx, uint32_t);
- *r->out.size = value_data.length;
- } else {
- r->out.size = r->in.size;
- r->out.data = value_data.data;
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ case SECURITY_USER:
+ key = h->data;
+
+ result = reg_key_get_value_by_name(mem_ctx, key, r->in.value_name.name,
+ &value_type, &value_data);
+
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+
+ /* Just asking for the size of the buffer */
+ r->out.type = talloc(mem_ctx, uint32_t);
+ if (!r->out.type) {
+ return WERR_NOMEM;
+ }
+ *r->out.type = value_type;
+ r->out.length = talloc(mem_ctx, uint32_t);
+ if (!r->out.length) {
+ return WERR_NOMEM;
+ }
+ *r->out.length = value_data.length;
+ if (r->in.data == NULL) {
+ r->out.size = talloc(mem_ctx, uint32_t);
+ *r->out.size = value_data.length;
+ } else {
+ r->out.size = r->in.size;
+ r->out.data = value_data.data;
+ }
+
+ return WERR_OK;
+ default:
+ return WERR_ACCESS_DENIED;
}
-
- return WERR_OK;
}
@@ -497,11 +550,17 @@ static WERROR dcesrv_winreg_SetValue(struct dcesrv_call_state *dce_call,
key = h->data;
- data.data = r->in.data;
- data.length = r->in.size;
- result = reg_val_set(key, r->in.name.name, r->in.type, data);
-
- return result;
+ switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+ {
+ case SECURITY_SYSTEM:
+ case SECURITY_ADMINISTRATOR:
+ data.data = r->in.data;
+ data.length = r->in.size;
+ result = reg_val_set(key, r->in.name.name, r->in.type, data);
+ return result;
+ default:
+ return WERR_ACCESS_DENIED;
+ }
}