diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-03-28 00:44:14 +0100 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-03-28 00:44:14 +0100 |
commit | 18d80bdf1fc5a281358aef29324230698eb434d4 (patch) | |
tree | e2515f11577052f42a227bc04541d572d7f2e1ff /source4/rpc_server | |
parent | ac604330871504e88e4bcd37433bbf3717d97a88 (diff) | |
parent | e15b35e3897e63b9e815a04101436439d4aebdef (diff) | |
download | samba-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.c | 71 | ||||
-rw-r--r-- | source4/rpc_server/lsa/lsa_lookup.c | 1 | ||||
-rw-r--r-- | source4/rpc_server/samr/dcesrv_samr.c | 138 | ||||
-rw-r--r-- | source4/rpc_server/samr/dcesrv_samr.h | 2 | ||||
-rw-r--r-- | source4/rpc_server/winreg/rpc_winreg.c | 233 |
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; + } } |