/* 
  lsa_LookupNames4

  Identical to LookupNames3, but doesn't take a policy handle
  
*/
NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
				 struct lsa_LookupNames4 *r)
{
	enum dcerpc_transport_t transport =
		dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
	struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info;
	struct lsa_policy_state *policy_state;
	struct lsa_LookupNames3 q;
	NTSTATUS status;

	if (transport != NCACN_IP_TCP) {
		DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
	}

	/*
	 * We don't have policy handles on this call. So this must be restricted
	 * to crypto connections only.
	 */
	if (auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
	    auth_info->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
		DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
	}

	status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &policy_state);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	ZERO_STRUCT(q);

	q.in.handle = NULL;
	q.in.num_names = r->in.num_names;
	q.in.names = r->in.names;
	q.in.level = r->in.level;
	q.in.sids = r->in.sids;
	q.in.count = r->in.count;
	q.in.lookup_options = r->in.lookup_options;
	q.in.client_revision = r->in.client_revision;

	q.out.count = r->out.count;
	q.out.sids = r->out.sids;
	q.out.domains = r->out.domains;

	status = dcesrv_lsa_LookupNames_common(dce_call,
					       mem_ctx,
					       policy_state,
					       &q);

	talloc_free(policy_state);

	r->out.count = q.out.count;
	r->out.sids = q.out.sids;
	r->out.domains = q.out.domains;

	return status;
}
/* 
  lsa_OpenPolicy2
*/
NTSTATUS dcesrv_lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
				struct lsa_OpenPolicy2 *r)
{
	enum dcerpc_transport_t transport =
		dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
	NTSTATUS status;
	struct lsa_policy_state *state;
	struct dcesrv_handle *handle;

	if (transport != NCACN_NP && transport != NCALRPC) {
		DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
	}

	ZERO_STRUCTP(r->out.handle);

	if (r->in.attr != NULL &&
	    r->in.attr->root_dir != NULL) {
		/* MS-LSAD 3.1.4.4.1 */
		return NT_STATUS_INVALID_PARAMETER;
	}

	status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
	if (!handle) {
		return NT_STATUS_NO_MEMORY;
	}

	handle->data = talloc_steal(handle, state);

	/* need to check the access mask against - need ACLs - fails
	   WSPP test */
	state->access_mask = r->in.access_mask;
	state->handle = handle;
	*r->out.handle = handle->wire_handle;

	/* note that we have completely ignored the attr element of
	   the OpenPolicy. As far as I can tell, this is what w2k3
	   does */

	return NT_STATUS_OK;
}
Exemple #3
0
/* 
  lsa_OpenPolicy2
*/
NTSTATUS dcesrv_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);

	if (r->in.attr != NULL &&
	    r->in.attr->root_dir != NULL) {
		/* MS-LSAD 3.1.4.4.1 */
		return NT_STATUS_INVALID_PARAMETER;
	}

	status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
	if (!handle) {
		return NT_STATUS_NO_MEMORY;
	}

	handle->data = talloc_steal(handle, state);

	/* need to check the access mask against - need ACLs - fails
	   WSPP test */
	state->access_mask = r->in.access_mask;
	state->handle = handle;
	*r->out.handle = handle->wire_handle;

	/* note that we have completely ignored the attr element of
	   the OpenPolicy. As far as I can tell, this is what w2k3
	   does */

	return NT_STATUS_OK;
}
Exemple #4
0
/*
  lsa_LookupSids2
*/
NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call,
                                TALLOC_CTX *mem_ctx,
                                struct lsa_LookupSids2 *r)
{
    struct lsa_policy_state *state;
    struct lsa_RefDomainList *domains = NULL;
    int i;
    NTSTATUS status = NT_STATUS_OK;

    if (r->in.level < LSA_LOOKUP_NAMES_ALL ||
            r->in.level > LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC) {
        return NT_STATUS_INVALID_PARAMETER;
    }

    *r->out.domains = NULL;

    /* NOTE: the WSPP test suite tries SIDs with invalid revision numbers,
       and expects NT_STATUS_INVALID_PARAMETER back - we just treat it as
       an unknown SID. We could add a SID validator here. (tridge)
       MS-DTYP 2.4.2
    */

    status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
    if (!NT_STATUS_IS_OK(status)) {
        return status;
    }

    domains = talloc_zero(r->out.domains,  struct lsa_RefDomainList);
    if (domains == NULL) {
        return NT_STATUS_NO_MEMORY;
    }
    *r->out.domains = domains;

    r->out.names = talloc_zero(mem_ctx,  struct lsa_TransNameArray2);
    if (r->out.names == NULL) {
        return NT_STATUS_NO_MEMORY;
    }

    *r->out.count = 0;

    r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
                                       r->in.sids->num_sids);
    if (r->out.names->names == NULL) {
        return NT_STATUS_NO_MEMORY;
    }

    for (i=0; i<r->in.sids->num_sids; i++) {
        struct dom_sid *sid = r->in.sids->sids[i].sid;
        char *sid_str = dom_sid_string(mem_ctx, sid);
        const char *name, *authority_name;
        enum lsa_SidType rtype;
        uint32_t sid_index;
        NTSTATUS status2;

        r->out.names->count++;

        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)";
            status = STATUS_SOME_UNMAPPED;
            continue;
        }

        status2 = dcesrv_lsa_lookup_sid(state, mem_ctx, sid, sid_str,
                                        &authority_name, &name, &rtype);
        if (!NT_STATUS_IS_OK(status2)) {
            status = STATUS_SOME_UNMAPPED;
            continue;
        }

        /* set up the authority table */
        status2 = dcesrv_lsa_authority_list(state, mem_ctx, rtype,
                                            authority_name, sid,
                                            domains, &sid_index);
        if (!NT_STATUS_IS_OK(status2)) {
            continue;
        }

        r->out.names->names[i].sid_type    = rtype;
        r->out.names->names[i].name.string = name;
        r->out.names->names[i].sid_index   = sid_index;
        r->out.names->names[i].unknown     = 0;

        (*r->out.count)++;
    }

    if (*r->out.count == 0) {
        return NT_STATUS_NONE_MAPPED;
    }
    if (*r->out.count != r->in.sids->num_sids) {
        return STATUS_SOME_UNMAPPED;
    }

    return NT_STATUS_OK;
}