summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/rpc_server/lsa/dcesrv_lsa.c124
1 files changed, 106 insertions, 18 deletions
diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c
index a4796f4356..606555ba50 100644
--- a/source4/rpc_server/lsa/dcesrv_lsa.c
+++ b/source4/rpc_server/lsa/dcesrv_lsa.c
@@ -26,6 +26,7 @@
#include "rpc_server/dcerpc_server.h"
#include "rpc_server/common/common.h"
#include "lib/ldb/include/ldb.h"
+#include "auth/auth.h"
/*
this type allows us to distinguish handle types
@@ -187,20 +188,13 @@ static NTSTATUS lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CT
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
-
-/*
- lsa_OpenPolicy2
-*/
-static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct lsa_OpenPolicy2 *r)
+static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct lsa_policy_state **_state)
{
struct lsa_policy_state *state;
- struct dcesrv_handle *handle;
const char *sid_str;
- ZERO_STRUCTP(r->out.handle);
-
- state = talloc_p(dce_call->conn, struct lsa_policy_state);
+ state = talloc_p(mem_ctx, struct lsa_policy_state);
if (!state) {
return NT_STATUS_NO_MEMORY;
}
@@ -261,15 +255,35 @@ static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *
talloc_free(state);
return NT_STATUS_NO_SUCH_DOMAIN;
}
-
+
+ *_state = state;
+
+ return NT_STATUS_OK;
+}
+
+/*
+ lsa_OpenPolicy2
+*/
+static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct lsa_OpenPolicy2 *r)
+{
+ NTSTATUS status;
+ struct lsa_policy_state *state;
+ struct dcesrv_handle *handle;
+
+ ZERO_STRUCTP(r->out.handle);
+
+ status = lsa_get_policy_state(dce_call, mem_ctx, &state);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
handle = dcesrv_handle_new(dce_call->conn, LSA_HANDLE_POLICY);
if (!handle) {
- talloc_free(state);
return NT_STATUS_NO_MEMORY;
}
- handle->data = state;
+ handle->data = talloc_reference(handle, state);
handle->destroy = lsa_Policy_destroy;
state->access_mask = r->in.access_mask;
@@ -599,17 +613,21 @@ static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_c
{
int ret;
struct ldb_message **res;
- const char * const attrs[] = { "sAMAccountName", "sAMAccountType", NULL};
+ const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
NTSTATUS status;
ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs,
"objectSid=%s", sid_str);
if (ret == 1) {
*name = ldb_msg_find_string(res[0], "sAMAccountName", NULL);
- if (*name == NULL) {
- return NT_STATUS_NO_MEMORY;
+ if (!*name) {
+ *name = ldb_msg_find_string(res[0], "name", NULL);
+ if (!*name) {
+ *name = talloc_strdup(mem_ctx, sid_str);
+ NTSTATUS_TALLOC_CHECK(*name);
+ }
}
-
+
*atype = samdb_result_uint(res[0], "sAMAccountType", 0);
return NT_STATUS_OK;
@@ -1482,7 +1500,77 @@ static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALL
static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct lsa_GetUserName *r)
{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ NTSTATUS status = NT_STATUS_OK;
+ struct lsa_policy_state *state;
+ uint32_t atype;
+ struct dom_sid *account_sid;
+ struct dom_sid *authority_sid;
+ const char *account_sid_str;
+ const char *account_name;
+ const char *authority_name;
+ struct lsa_String *_account_name;
+ struct lsa_StringPointer *_authority_name = NULL;
+
+ /* this is what w2k3 does */
+ r->out.account_name = r->in.account_name;
+ r->out.authority_name = r->in.authority_name;
+
+ if (r->in.account_name && r->in.account_name->string) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (r->in.authority_name &&
+ r->in.authority_name->string &&
+ r->in.authority_name->string->string) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* TODO: this check should go and we should rely on the calling code that this is valid */
+ if (!dce_call->conn->auth_state.session_info ||
+ !dce_call->conn->auth_state.session_info->security_token ||
+ !dce_call->conn->auth_state.session_info->security_token->user_sid) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ account_sid = dce_call->conn->auth_state.session_info->security_token->user_sid;
+
+ account_sid_str = dom_sid_string(mem_ctx, account_sid);
+ NTSTATUS_TALLOC_CHECK(account_sid_str);
+
+ status = lsa_get_policy_state(dce_call, mem_ctx, &state);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = lsa_lookup_sid(state, mem_ctx,
+ account_sid, account_sid_str,
+ &account_name, &atype);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ _account_name = talloc_p(mem_ctx, struct lsa_String);
+ NTSTATUS_TALLOC_CHECK(_account_name);
+ _account_name->string = account_name;
+
+ if (r->in.authority_name) {
+ status = lsa_authority_name(state, mem_ctx, account_sid,
+ &authority_name, &authority_sid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ _authority_name = talloc_p(mem_ctx, struct lsa_StringPointer);
+ NTSTATUS_TALLOC_CHECK(_authority_name);
+ _authority_name->string = talloc_p(mem_ctx, struct lsa_String);
+ NTSTATUS_TALLOC_CHECK(_authority_name->string);
+ _authority_name->string->string = authority_name;
+ }
+
+ r->out.account_name = _account_name;
+ r->out.authority_name = _authority_name;
+
+ return status;
}
/*