diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/ntvfs/common/sidmap.c | 61 | ||||
-rw-r--r-- | source4/rpc_server/lsa/dcesrv_lsa.c | 60 |
2 files changed, 104 insertions, 17 deletions
diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index 209982ec58..89ad2e2430 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -540,3 +540,64 @@ allocate_sid: return NT_STATUS_OK; } + +/* + check if a sid is in the range of auto-allocated SIDs from our primary domain, + and if it is, then return the name and atype +*/ +NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap, + TALLOC_CTX *mem_ctx, + const struct dom_sid *sid, + const char **name, + uint32_t *atype) +{ + NTSTATUS status; + struct dom_sid *domain_sid; + void *ctx = talloc(mem_ctx, 0); + uint32_t rid; + + status = sidmap_primary_domain_sid(sidmap, ctx, &domain_sid); + if (!NT_STATUS_IS_OK(status)) { + return NT_STATUS_NO_SUCH_DOMAIN; + } + + if (!dom_sid_in_domain(domain_sid, sid)) { + talloc_free(ctx); + return NT_STATUS_INVALID_SID; + } + + talloc_free(ctx); + + rid = sid->sub_auths[sid->num_auths-1]; + if (rid < SIDMAP_LOCAL_USER_BASE) { + return NT_STATUS_INVALID_SID; + } + + if (rid < SIDMAP_LOCAL_GROUP_BASE) { + struct passwd *pwd; + uid_t uid = rid - SIDMAP_LOCAL_USER_BASE; + *atype = ATYPE_NORMAL_ACCOUNT; + pwd = getpwuid(uid); + if (pwd == NULL) { + *name = talloc_asprintf(mem_ctx, "uid%u", uid); + } else { + *name = talloc_strdup(mem_ctx, pwd->pw_name); + } + } else { + struct group *grp; + gid_t gid = rid - SIDMAP_LOCAL_GROUP_BASE; + *atype = ATYPE_LOCAL_GROUP; + grp = getgrgid(gid); + if (grp == NULL) { + *name = talloc_asprintf(mem_ctx, "gid%u", gid); + } else { + *name = talloc_strdup(mem_ctx, grp->gr_name); + } + } + + if (*name == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index adfbda5504..4cebc3f5aa 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -42,6 +42,7 @@ enum lsa_handle { struct lsa_policy_state { int reference_count; void *sam_ctx; + struct sidmap_context *sidmap; uint32_t access_mask; const char *domain_dn; const char *domain_name; @@ -166,6 +167,12 @@ static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX * return NT_STATUS_INVALID_SYSTEM_SERVICE; } + state->sidmap = sidmap_open(state); + if (state->sidmap == NULL) { + talloc_free(state); + return NT_STATUS_INVALID_SYSTEM_SERVICE; + } + /* work out the domain_dn - useful for so many calls its worth fetching here */ state->domain_dn = samdb_search_string(state->sam_ctx, state, NULL, @@ -423,6 +430,9 @@ static NTSTATUS lsa_authority_name(struct lsa_policy_state *state, return NT_STATUS_OK; } +/* + add to the lsa_RefDomainList for LookupSids and LookupNames +*/ static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, struct dom_sid *sid, struct lsa_RefDomainList *domains) @@ -461,6 +471,36 @@ static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *m return NT_STATUS_OK; } +/* + lookup a name for 1 SID +*/ +static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, + struct dom_sid *sid, const char *sid_str, + const char **name, uint32_t *atype) +{ + int ret; + struct ldb_message **res; + const char * const attrs[] = { "sAMAccountName", "sAMAccountType", 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; + } + + *atype = samdb_result_uint(res[0], "sAMAccountType", 0); + + return NT_STATUS_OK; + } + + status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype); + + return status; +} + /* lsa_LookupSids2 @@ -499,11 +539,8 @@ static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call, } for (i=0;i<r->in.sids->num_sids;i++) { - const char * const attrs[] = { "sAMAccountName", "sAMAccountType", NULL}; struct dom_sid *sid = r->in.sids->sids[i].sid; char *sid_str = dom_sid_string(mem_ctx, sid); - int ret; - struct ldb_message **res; const char *name; uint32_t atype, rtype; NTSTATUS status2; @@ -528,20 +565,9 @@ static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call, return status2; } - ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, "objectSid=%s", sid_str); - if (ret != 1) { - status = STATUS_SOME_UNMAPPED; - continue; - } - - name = ldb_msg_find_string(res[0], "sAMAccountName", NULL); - if (name == NULL) { - status = STATUS_SOME_UNMAPPED; - continue; - } - - atype = samdb_result_uint(res[0], "sAMAccountType", 0); - if (atype == 0) { + status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str, + &name, &atype); + if (!NT_STATUS_IS_OK(status2)) { status = STATUS_SOME_UNMAPPED; continue; } |