fixed a number of places in our LSA server where we should return the
[tprouty/samba.git] / source4 / rpc_server / lsa / lsa_lookup.c
index c6b9e3bd406c78eeca6147ab5da4418ae3feff7c..0ffb0572eec7c5643aaad41682090b5e6fec3d07 100644 (file)
@@ -43,6 +43,11 @@ static const struct {
                .sid = SID_CREATOR_GROUP,
                .rtype = SID_NAME_WKN_GRP,
        },
+       {
+               .name = "Owner Rights",
+               .sid = SID_OWNER_RIGHTS,
+               .rtype = SID_NAME_WKN_GRP,
+       },
        {
                .domain = "NT AUTHORITY",
                .name = "Dialup",
@@ -111,7 +116,7 @@ static const struct {
        },
        {
                .domain = "NT AUTHORITY",
-               .name = "Termainal Server User",
+               .name = "Terminal Server User",
                .sid = SID_NT_TERMINAL_SERVER_USERS,
                .rtype = SID_NAME_WKN_GRP,
        },
@@ -145,6 +150,42 @@ static const struct {
                .sid = SID_NT_NETWORK_SERVICE,
                .rtype = SID_NAME_WKN_GRP,
        },
+       {
+               .domain = "NT AUTHORITY",
+               .name = "Digest Authentication",
+               .sid = SID_NT_DIGEST_AUTHENTICATION,
+               .rtype = SID_NAME_WKN_GRP,
+       },
+       {
+               .domain = "NT AUTHORITY",
+               .name = "Enterprise Domain Controllers",
+               .sid = SID_NT_ENTERPRISE_DCS,
+               .rtype = SID_NAME_WKN_GRP,
+       },
+       {
+               .domain = "NT AUTHORITY",
+               .name = "NTLM Authentication",
+               .sid = SID_NT_NTLM_AUTHENTICATION,
+               .rtype = SID_NAME_WKN_GRP,
+       },
+       {
+               .domain = "NT AUTHORITY",
+               .name = "Other Organization",
+               .sid = SID_NT_OTHER_ORGANISATION,
+               .rtype = SID_NAME_WKN_GRP,
+       },
+       {
+               .domain = "NT AUTHORITY",
+               .name = "SChannel Authentication",
+               .sid = SID_NT_SCHANNEL_AUTHENTICATION,
+               .rtype = SID_NAME_WKN_GRP,
+       },
+       {
+               .domain = "NT AUTHORITY",
+               .name = "IUSR",
+               .sid = SID_NT_IUSR,
+               .rtype = SID_NAME_WKN_GRP,
+       },
        {
                .sid = NULL,
        }
@@ -195,7 +236,8 @@ static NTSTATUS lookup_well_known_sids(TALLOC_CTX *mem_ctx,
 /*
   lookup a SID for 1 name
 */
-static NTSTATUS dcesrv_lsa_lookup_name(struct loadparm_context *lp_ctx,
+static NTSTATUS dcesrv_lsa_lookup_name(struct event_context *ev_ctx, 
+                                      struct loadparm_context *lp_ctx,
                                       struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
                                const char *name, const char **authority_name, 
                                struct dom_sid **sid, enum lsa_SidType *rtype)
@@ -218,7 +260,7 @@ static NTSTATUS dcesrv_lsa_lookup_name(struct loadparm_context *lp_ctx,
                }
                username = p + 1;
        } else if (strchr_m(name, '@')) {
-               status = crack_name_to_nt4_name(mem_ctx, lp_ctx, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, name, &domain, &username);
+               status = crack_name_to_nt4_name(mem_ctx, ev_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;
@@ -265,7 +307,7 @@ static NTSTATUS dcesrv_lsa_lookup_name(struct loadparm_context *lp_ctx,
                if (!name) {
                        return NT_STATUS_NO_MEMORY;
                }
-               status = dcesrv_lsa_lookup_name(lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
+               status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
                if (NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -275,7 +317,7 @@ static NTSTATUS dcesrv_lsa_lookup_name(struct loadparm_context *lp_ctx,
                if (!name) {
                        return NT_STATUS_NO_MEMORY;
                }
-               status = dcesrv_lsa_lookup_name(lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
+               status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
                if (NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -285,7 +327,7 @@ static NTSTATUS dcesrv_lsa_lookup_name(struct loadparm_context *lp_ctx,
                if (!name) {
                        return NT_STATUS_NO_MEMORY;
                }
-               status = dcesrv_lsa_lookup_name(lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
+               status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
                if (NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -578,6 +620,8 @@ NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
        NTSTATUS status;
        struct dcesrv_handle *h;
 
+       ZERO_STRUCT(r2);
+       
        /* No policy handle on the wire, so make one up here */
        r2.in.handle = talloc(mem_ctx, struct policy_handle);
        if (!r2.in.handle) {
@@ -607,9 +651,6 @@ NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
        r2.out.names   = r->out.names;
 
        status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
-       if (dce_call->fault_code != 0) {
-               return status;
-       }
 
        r->out.domains = r2.out.domains;
        r->out.names   = r2.out.names;
@@ -629,6 +670,8 @@ NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
        NTSTATUS status;
        int i;
 
+       ZERO_STRUCT(r2);
+
        r2.in.handle   = r->in.handle;
        r2.in.sids     = r->in.sids;
        r2.in.names    = NULL;
@@ -640,7 +683,7 @@ NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
        r2.out.names   = NULL;
 
        status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
-       if (dce_call->fault_code != 0) {
+       if (NT_STATUS_IS_ERR(status)) {
                return status;
        }
 
@@ -719,9 +762,9 @@ NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
                r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
                r->out.sids->sids[i].sid         = NULL;
                r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
-               r->out.sids->sids[i].unknown     = 0;
+               r->out.sids->sids[i].flags       = 0;
 
-               status2 = dcesrv_lsa_lookup_name(lp_ctx, policy_state, mem_ctx, name, &authority_name, &sid, &rtype);
+               status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, policy_state, mem_ctx, name, &authority_name, &sid, &rtype);
                if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
                        continue;
                }
@@ -729,13 +772,13 @@ NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
                status2 = dcesrv_lsa_authority_list(policy_state, mem_ctx, rtype, authority_name, 
                                                    sid, r->out.domains, &sid_index);
                if (!NT_STATUS_IS_OK(status2)) {
-                       return status2;
+                       continue;
                }
 
                r->out.sids->sids[i].sid_type    = rtype;
                r->out.sids->sids[i].sid         = sid;
                r->out.sids->sids[i].sid_index   = sid_index;
-               r->out.sids->sids[i].unknown     = 0;
+               r->out.sids->sids[i].flags       = 0;
 
                (*r->out.count)++;
        }
@@ -764,6 +807,8 @@ NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX
        NTSTATUS status;
        struct dcesrv_handle *h;
 
+       ZERO_STRUCT(r2);
+
        /* No policy handle on the wire, so make one up here */
        r2.in.handle = talloc(mem_ctx, struct policy_handle);
        if (!r2.in.handle) {
@@ -794,9 +839,6 @@ NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX
        r2.out.count = r->out.count;
        
        status = dcesrv_lsa_LookupNames3(dce_call, mem_ctx, &r2);
-       if (dce_call->fault_code != 0) {
-               return status;
-       }
        
        r->out.domains = r2.out.domains;
        r->out.sids = r2.out.sids;
@@ -820,6 +862,11 @@ NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
 
        DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
 
+       if (r->in.level < LSA_LOOKUP_NAMES_ALL ||
+           r->in.level > LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
        state = h->data;
 
        r->out.domains = talloc_zero(mem_ctx,  struct lsa_RefDomainList);
@@ -850,11 +897,14 @@ NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
                r->out.sids->count++;
 
                r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
-               r->out.sids->sids[i].rid         = 0xFFFFFFFF;
+               /* MS-LSAT 3.1.4.7 - rid zero is considered equivalent
+                  to sid NULL - so we should return 0 rid for
+                  unmapped entries */
+               r->out.sids->sids[i].rid         = 0;
                r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
                r->out.sids->sids[i].unknown     = 0;
 
-               status2 = dcesrv_lsa_lookup_name(lp_ctx, state, mem_ctx, name, 
+               status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, state, mem_ctx, name, 
                                                 &authority_name, &sid, &rtype);
                if (!NT_STATUS_IS_OK(status2)) {
                        continue;
@@ -863,7 +913,7 @@ NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
                status2 = dcesrv_lsa_authority_list(state, mem_ctx, rtype, authority_name, 
                                                    sid, r->out.domains, &sid_index);
                if (!NT_STATUS_IS_OK(status2)) {
-                       return status2;
+                       continue;
                }
 
                r->out.sids->sids[i].sid_type    = rtype;
@@ -894,6 +944,8 @@ NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *
        NTSTATUS status;
        int i;
 
+       ZERO_STRUCT(r2);
+
        r2.in.handle    = r->in.handle;
        r2.in.num_names = r->in.num_names;
        r2.in.names     = r->in.names;
@@ -905,7 +957,7 @@ NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *
        r2.out.count    = r->out.count;
 
        status = dcesrv_lsa_LookupNames2(dce_call, mem_ctx, &r2);
-       if (dce_call->fault_code != 0) {
+       if (r2.out.sids == NULL) {
                return status;
        }