summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/security/dom_sid.c26
-rw-r--r--source4/rpc_server/lsa/dcesrv_lsa.c143
2 files changed, 136 insertions, 33 deletions
diff --git a/source4/libcli/security/dom_sid.c b/source4/libcli/security/dom_sid.c
index 001618bb07..dbd03108e4 100644
--- a/source4/libcli/security/dom_sid.c
+++ b/source4/libcli/security/dom_sid.c
@@ -239,3 +239,29 @@ struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx,
sid->num_auths++;
return sid;
}
+
+
+/*
+ return True if the 2nd sid is in the domain given by the first sid
+*/
+BOOL dom_sid_in_domain(const struct dom_sid *domain_sid,
+ const struct dom_sid *sid)
+{
+ int i;
+
+ if (!domain_sid || !sid) {
+ return False;
+ }
+
+ if (domain_sid->num_auths > sid->num_auths) {
+ return False;
+ }
+
+ for (i = domain_sid->num_auths-1; i >= 0; --i) {
+ if (domain_sid->sub_auths[i] != sid->sub_auths[i]) {
+ return False;
+ }
+ }
+
+ return dom_sid_compare_auth(domain_sid, sid) == 0;
+}
diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c
index 78b5e41398..8dee8f189d 100644
--- a/source4/rpc_server/lsa/dcesrv_lsa.c
+++ b/source4/rpc_server/lsa/dcesrv_lsa.c
@@ -44,6 +44,8 @@ struct lsa_policy_state {
void *sam_ctx;
uint32_t access_mask;
const char *domain_dn;
+ const char *domain_name;
+ struct dom_sid *domain_sid;
};
@@ -148,6 +150,7 @@ static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *
{
struct lsa_policy_state *state;
struct dcesrv_handle *handle;
+ const char *sid_str;
ZERO_STRUCTP(r->out.handle);
@@ -172,6 +175,27 @@ static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *
return NT_STATUS_NO_SUCH_DOMAIN;
}
+ sid_str = samdb_search_string(state->sam_ctx, state, NULL,
+ "objectSid", "dn=%s", state->domain_dn);
+ if (!sid_str) {
+ talloc_free(state);
+ return NT_STATUS_NO_SUCH_DOMAIN;
+ }
+
+ state->domain_sid = dom_sid_parse_talloc(state, sid_str);
+ if (!state->domain_sid) {
+ talloc_free(state);
+ return NT_STATUS_NO_SUCH_DOMAIN;
+ }
+
+ state->domain_name = samdb_search_string(state->sam_ctx, state, NULL,
+ "name", "dn=%s", state->domain_dn);
+ if (!state->domain_name) {
+ talloc_free(state);
+ return NT_STATUS_NO_SUCH_DOMAIN;
+ }
+
+
handle = dcesrv_handle_new(dce_call->conn, LSA_HANDLE_POLICY);
if (!handle) {
talloc_free(state);
@@ -382,11 +406,39 @@ static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *
}
-/*
- lsa_LookupSids
+/*
+ return the authority name and authority sid, given a sid
*/
-static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct lsa_LookupSids *r)
+static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
+ TALLOC_CTX *mem_ctx, struct dom_sid *sid,
+ const char **authority_name,
+ struct dom_sid **authority_sid)
+{
+ if (dom_sid_in_domain(state->domain_sid, sid)) {
+ *authority_name = state->domain_name;
+ *authority_sid = state->domain_sid;
+ return NT_STATUS_OK;
+ }
+
+ *authority_sid = dom_sid_dup(mem_ctx, sid);
+ if (*authority_sid == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ (*authority_sid)->num_auths = 0;
+ *authority_name = dom_sid_string(mem_ctx, *authority_sid);
+ if (*authority_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ lsa_LookupSids2
+*/
+static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
+ TALLOC_CTX *mem_ctx,
+ struct lsa_LookupSids2 *r)
{
struct lsa_policy_state *state;
struct dcesrv_handle *h;
@@ -404,14 +456,14 @@ static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
return NT_STATUS_NO_MEMORY;
}
- r->out.names = talloc_zero_p(mem_ctx, struct lsa_TransNameArray);
+ r->out.names = talloc_zero_p(mem_ctx, struct lsa_TransNameArray2);
if (r->out.domains == NULL) {
return NT_STATUS_NO_MEMORY;
}
*r->out.count = 0;
- r->out.names->names = talloc_array_p(r->out.names, struct lsa_TranslatedName,
+ r->out.names->names = talloc_array_p(r->out.names, struct lsa_TranslatedName2,
r->in.sids->num_sids);
if (r->out.names->names == NULL) {
return NT_STATUS_NO_MEMORY;
@@ -426,12 +478,7 @@ static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
const char *name, *authority_name;
struct dom_sid *authority_sid;
uint32_t atype, rtype;
- const struct {
- const char *sid_prefix;
- const char *authority_name;
- } authority_names[] = {
- { "S-1-5", "NT AUTHORITY" }
- };
+ NTSTATUS status2;
r->out.names->count++;
(*r->out.count)++;
@@ -439,6 +486,7 @@ static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
r->out.names->names[i].name.string = sid_str;
r->out.names->names[i].sid_index = 0xFFFFFFFF;
+ r->out.names->names[i].unknown = 0;
if (sid_str == NULL) {
r->out.names->names[i].name.string = "(SIDERROR)";
@@ -447,17 +495,10 @@ static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
}
/* work out the authority name */
- authority_name = talloc_strndup(mem_ctx, sid_str, 5);
- authority_sid = dom_sid_parse_talloc(mem_ctx, authority_name);
- if (!authority_name || !authority_sid) {
- return NT_STATUS_NO_MEMORY;
- }
- for (j=0;j<ARRAY_SIZE(authority_names);j++) {
- if (strncmp(sid_str, authority_names[j].sid_prefix,
- strlen(authority_names[j].sid_prefix)) == 0) {
- authority_name = authority_names[j].authority_name;
- break;
- }
+ status2 = lsa_authority_name(state, mem_ctx, sid,
+ &authority_name, &authority_sid);
+ if (!NT_STATUS_IS_OK(status2)) {
+ return status2;
}
/* see if we've already done this authority name */
@@ -506,6 +547,7 @@ static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
r->out.names->names[i].sid_type = rtype;
r->out.names->names[i].name.string = name;
r->out.names->names[i].sid_index = 0;
+ r->out.names->names[i].unknown = 0;
}
return status;
@@ -513,6 +555,51 @@ static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
/*
+ lsa_LookupSids
+*/
+static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct lsa_LookupSids *r)
+{
+ struct lsa_LookupSids2 r2;
+ NTSTATUS status;
+ int i;
+
+ r2.in.handle = r->in.handle;
+ r2.in.sids = r->in.sids;
+ r2.in.names = NULL;
+ r2.in.level = r->in.level;
+ r2.in.count = r->in.count;
+ r2.in.unknown1 = 0;
+ r2.in.unknown2 = 0;
+ r2.out.count = r->out.count;
+
+ status = lsa_LookupSids2(dce_call, mem_ctx, &r2);
+ if (dce_call->fault_code != 0) {
+ return status;
+ }
+
+ r->out.domains = r2.out.domains;
+ r->out.names = talloc_p(mem_ctx, struct lsa_TransNameArray);
+ if (r->out.names == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ r->out.names->count = r2.out.names->count;
+ r->out.names->names = talloc_array_p(r->out.names, struct lsa_TranslatedName,
+ r->out.names->count);
+ if (r->out.names->names == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ for (i=0;i<r->out.names->count;i++) {
+ r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type;
+ r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
+ r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index;
+ }
+
+ return status;
+}
+
+
+/*
lsa_CreateSecret
*/
static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
@@ -902,16 +989,6 @@ static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
}
/*
- lsa_LookupSids2
-*/
-static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
- TALLOC_CTX *mem_ctx,
- struct lsa_LookupSids2 *r)
-{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
-}
-
-/*
lsa_LookupNames2
*/
static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,