Beispiel #1
0
static struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
			       struct ldb_dn *dn,
			       struct security_token *token,
			       struct ldb_context *ldb)
{
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
	struct dom_sid *da_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
	struct dom_sid *ea_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS);
	struct dom_sid *sa_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_SCHEMA_ADMINS);
	struct dom_sid *dag_sid;
	struct ldb_dn *nc_root;
	int ret;

	ret = dsdb_find_nc_root(ldb, tmp_ctx, dn, &nc_root);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return NULL;
	}

	if (ldb_dn_compare(nc_root, ldb_get_schema_basedn(ldb)) == 0) {
		if (security_token_has_sid(token, sa_sid)) {
			dag_sid = dom_sid_dup(mem_ctx, sa_sid);
		} else if (security_token_has_sid(token, ea_sid)) {
			dag_sid = dom_sid_dup(mem_ctx, ea_sid);
		} else if (security_token_has_sid(token, da_sid)) {
			dag_sid = dom_sid_dup(mem_ctx, da_sid);
		} else if (security_token_is_system(token)) {
			dag_sid = dom_sid_dup(mem_ctx, sa_sid);
		} else {
			dag_sid = NULL;
		}
	} else if (ldb_dn_compare(nc_root, ldb_get_config_basedn(ldb)) == 0) {
		if (security_token_has_sid(token, ea_sid)) {
			dag_sid = dom_sid_dup(mem_ctx, ea_sid);
		} else if (security_token_has_sid(token, da_sid)) {
			dag_sid = dom_sid_dup(mem_ctx, da_sid);
		} else if (security_token_is_system(token)) {
			dag_sid = dom_sid_dup(mem_ctx, ea_sid);
		} else {
			dag_sid = NULL;
		}
	} else if (ldb_dn_compare(nc_root, ldb_get_default_basedn(ldb)) == 0) {
		if (security_token_has_sid(token, da_sid)) {
			dag_sid = dom_sid_dup(mem_ctx, da_sid);
		} else if (security_token_has_sid(token, ea_sid)) {
				dag_sid = dom_sid_dup(mem_ctx, ea_sid);
		} else if (security_token_is_system(token)) {
			dag_sid = dom_sid_dup(mem_ctx, da_sid);
		} else {
			dag_sid = NULL;
		}
	} else {
		dag_sid = NULL;
	}

	talloc_free(tmp_ctx);
	return dag_sid;
}
Beispiel #2
0
/*
  allocate a new rpc handle
*/
_PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_context *context, 
						 uint8_t handle_type)
{
	struct dcesrv_handle *h;
	struct dom_sid *sid;

	sid = context->conn->auth_state.session_info->security_token->user_sid;

	h = talloc(context->assoc_group, struct dcesrv_handle);
	if (!h) {
		return NULL;
	}
	h->data = NULL;
	h->sid = dom_sid_dup(h, sid);
	if (h->sid == NULL) {
		talloc_free(h);
		return NULL;
	}
	h->assoc_group = context->assoc_group;
	h->iface = context->iface;
	h->wire_handle.handle_type = handle_type;
	h->wire_handle.uuid = GUID_random();
	
	DLIST_ADD(context->assoc_group->handles, h);

	talloc_set_destructor(h, dcesrv_handle_destructor);

	return h;
}
Beispiel #3
0
struct netr_SamInfo3 *copy_netr_SamInfo3(TALLOC_CTX *mem_ctx,
					 struct netr_SamInfo3 *orig)
{
	struct netr_SamInfo3 *info3;
	unsigned int i;
	NTSTATUS status;

	info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
	if (!info3) return NULL;

	status = copy_netr_SamBaseInfo(info3, &orig->base, &info3->base);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(info3);
		return NULL;
	}

	if (orig->sidcount) {
		info3->sidcount = orig->sidcount;
		info3->sids = talloc_array(info3, struct netr_SidAttr,
					   orig->sidcount);
		RET_NOMEM(info3->sids);
		for (i = 0; i < orig->sidcount; i++) {
			info3->sids[i].sid = dom_sid_dup(info3->sids,
							    orig->sids[i].sid);
			RET_NOMEM(info3->sids[i].sid);
			info3->sids[i].attributes =
				orig->sids[i].attributes;
		}
	}
Beispiel #4
0
NTSTATUS copy_netr_SamBaseInfo(TALLOC_CTX *mem_ctx,
			       const struct netr_SamBaseInfo *in,
			       struct netr_SamBaseInfo *out)
{
	/* first copy all, then realloc pointers */
	*out = *in;

	COPY_LSA_STRING(mem_ctx, in, out, account_name);
	COPY_LSA_STRING(mem_ctx, in, out, full_name);
	COPY_LSA_STRING(mem_ctx, in, out, logon_script);
	COPY_LSA_STRING(mem_ctx, in, out, profile_path);
	COPY_LSA_STRING(mem_ctx, in, out, home_directory);
	COPY_LSA_STRING(mem_ctx, in, out, home_drive);

	if (in->groups.count) {
		out->groups.rids = (struct samr_RidWithAttribute *)
			talloc_memdup(mem_ctx, in->groups.rids,
				(sizeof(struct samr_RidWithAttribute) *
					in->groups.count));
		NT_STATUS_HAVE_NO_MEMORY(out->groups.rids);
	}

	COPY_LSA_STRING(mem_ctx, in, out, logon_server);
	COPY_LSA_STRING(mem_ctx, in, out, logon_domain);

	if (in->domain_sid) {
		out->domain_sid = dom_sid_dup(mem_ctx, in->domain_sid);
		NT_STATUS_HAVE_NO_MEMORY(out->domain_sid);
	}

	return NT_STATUS_OK;
}
Beispiel #5
0
static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
				struct netr_SamInfo3 *info3)
{
	const char *guest_account = lp_guestaccount();
	struct dom_sid domain_sid;
	struct passwd *pwd;
	const char *tmp;

	pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
	if (pwd == NULL) {
		DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
			 "account [%s]!\n", guest_account));
		return NT_STATUS_NO_SUCH_USER;
	}

	/* Set account name */
	tmp = talloc_strdup(mem_ctx, pwd->pw_name);
	if (tmp == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	init_lsa_String(&info3->base.account_name, tmp);

	/* Set domain name */
	tmp = talloc_strdup(mem_ctx, get_global_sam_name());
	if (tmp == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	init_lsa_StringLarge(&info3->base.logon_domain, tmp);

	/* Domain sid */
	sid_copy(&domain_sid, get_global_sam_sid());

	info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
	if (info3->base.domain_sid == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	/* Guest rid */
	info3->base.rid = DOMAIN_RID_GUEST;

	/* Primary gid */
	info3->base.primary_gid = DOMAIN_RID_GUESTS;

	/* Set as guest */
	info3->base.user_flags = NETLOGON_GUEST;

	TALLOC_FREE(pwd);
	return NT_STATUS_OK;
}
Beispiel #6
0
/*
  add a rid to a domain dom_sid to make a full dom_sid. This function
  returns a new sid in the supplied memory context
*/
struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx,
				const struct dom_sid *domain_sid,
				uint32_t rid)
{
	struct dom_sid *sid;

	sid = dom_sid_dup(mem_ctx, domain_sid);
	if (!sid) return NULL;

	if (!sid_append_rid(sid, rid)) {
		talloc_free(sid);
		return NULL;
	}

	return sid;
}
Beispiel #7
0
/*
  add to the lsa_RefDomainList for LookupSids and LookupNames
*/
static NTSTATUS dcesrv_lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
        enum lsa_SidType rtype,
        const char *authority_name,
        struct dom_sid *sid,
        struct lsa_RefDomainList *domains,
        uint32_t *sid_index)
{
    struct dom_sid *authority_sid;
    int i;

    if (rtype != SID_NAME_DOMAIN) {
        authority_sid = dom_sid_dup(mem_ctx, sid);
        if (authority_sid == NULL) {
            return NT_STATUS_NO_MEMORY;
        }
        authority_sid->num_auths--;
    } else {
        authority_sid = sid;
    }

    /* see if we've already done this authority name */
    for (i=0; i<domains->count; i++) {
        if (strcasecmp_m(authority_name, domains->domains[i].name.string) == 0) {
            *sid_index = i;
            return NT_STATUS_OK;
        }
    }

    domains->domains = talloc_realloc(domains,
                                      domains->domains,
                                      struct lsa_DomainInfo,
                                      domains->count+1);
    if (domains->domains == NULL) {
        return NT_STATUS_NO_MEMORY;
    }
    domains->domains[i].name.string = authority_name;
    domains->domains[i].sid         = authority_sid;
    domains->count++;
    domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
    *sid_index = i;

    return NT_STATUS_OK;
}
static NTSTATUS get_domain_info(TALLOC_CTX *mem_ctx,
				struct dcerpc_binding_handle *bind_hdn,
				struct policy_handle *pol_hnd,
				struct dom_data *dom_data)
{
	NTSTATUS status;
	struct lsa_QueryInfoPolicy2 qr;

	qr.in.handle = pol_hnd;
	qr.in.level = LSA_POLICY_INFO_DNS;

	status = dcerpc_lsa_QueryInfoPolicy2_r(bind_hdn, mem_ctx, &qr);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("dcerpc_lsa_QueryInfoPolicy2_r failed "
			  "with error [%s].\n", nt_errstr(status)));
		return status;
	}

	if (!NT_STATUS_IS_OK(qr.out.result)) {
		DEBUG(0, ("QueryInfoPolicy2 returned [%s].\n",
			  nt_errstr(qr.out.result)));
		return qr.out.result;
	}

	dom_data->domain_name = talloc_strdup(mem_ctx,
					      (*qr.out.info)->dns.name.string);
	dom_data->dns_domain_name = talloc_strdup(mem_ctx,
					 (*qr.out.info)->dns.dns_domain.string);
	dom_data->domsid = dom_sid_dup(mem_ctx, (*qr.out.info)->dns.sid);
	if (dom_data->domain_name == NULL ||
	    dom_data->dns_domain_name == NULL ||
	    dom_data->domsid == NULL) {
		DEBUG(0, ("Copying domain data failed.\n"));
		return NT_STATUS_NO_MEMORY;
	}

	DEBUG(0, ("Got the following domain info [%s][%s][%s].\n",
		  dom_data->domain_name, dom_data->dns_domain_name,
		  sid_string_talloc(mem_ctx, dom_data->domsid)));

	return NT_STATUS_OK;
}
Beispiel #9
0
static NTSTATUS wbcsids_to_netr_SidAttrArray(
				const struct dom_sid *domain_sid,
				const struct wbcSidWithAttr *sids,
				size_t num_sids,
				TALLOC_CTX *mem_ctx,
				struct netr_SidAttr **_info3_sids,
				uint32_t *info3_num_sids)
{
	unsigned int i, j = 0;
	struct netr_SidAttr *info3_sids;

	info3_sids = talloc_array(mem_ctx, struct netr_SidAttr, num_sids);
	if (info3_sids == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	/* a wbcDomainSid is the same as a dom_sid */
	for (i = 0; i < num_sids; i++) {
		const struct dom_sid *sid;

		sid = (const struct dom_sid *)&sids[i].sid;

		if (dom_sid_in_domain(domain_sid, sid)) {
			continue;
		}

		info3_sids[j].sid = dom_sid_dup(info3_sids, sid);
		if (info3_sids[j].sid == NULL) {
			talloc_free(info3_sids);
			return NT_STATUS_NO_MEMORY;
		}
		info3_sids[j].attributes = SE_GROUP_MANDATORY |
					   SE_GROUP_ENABLED_BY_DEFAULT |
					   SE_GROUP_ENABLED;
		j++;
	}

	*info3_num_sids = j;
	*_info3_sids = info3_sids;
	return NT_STATUS_OK;
}
Beispiel #10
0
/*
  Split up a SID into its domain and RID part
*/
NTSTATUS dom_sid_split_rid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
			   struct dom_sid **domain, uint32_t *rid)
{
	if (sid->num_auths == 0) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	if (domain) {
		if (!(*domain = dom_sid_dup(mem_ctx, sid))) {
			return NT_STATUS_NO_MEMORY;
		}

		(*domain)->num_auths -= 1;
	}

	if (rid) {
		*rid = sid->sub_auths[sid->num_auths - 1];
	}

	return NT_STATUS_OK;
}
Beispiel #11
0
static NTSTATUS append_netr_SidAttr(TALLOC_CTX *mem_ctx,
				    struct netr_SidAttr **sids,
				    uint32_t *count,
				    const struct dom_sid2 *asid,
				    uint32_t attributes)
{
	uint32_t t = *count;

	*sids = talloc_realloc(mem_ctx, *sids, struct netr_SidAttr, t + 1);
	if (*sids == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	(*sids)[t].sid = dom_sid_dup(*sids, asid);
	if ((*sids)[t].sid == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	(*sids)[t].attributes = attributes;
	*count = t + 1;

	return NT_STATUS_OK;
}
Beispiel #12
0
struct netlogon_creds_CredentialState *netlogon_creds_copy(TALLOC_CTX *mem_ctx,
							   struct netlogon_creds_CredentialState *creds_in)
{
	struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState);

	if (!creds) {
		return NULL;
	}

	creds->sequence			= creds_in->sequence;
	creds->negotiate_flags		= creds_in->negotiate_flags;
	creds->secure_channel_type	= creds_in->secure_channel_type;

	creds->computer_name = talloc_strdup(creds, creds_in->computer_name);
	if (!creds->computer_name) {
		talloc_free(creds);
		return NULL;
	}
	creds->account_name = talloc_strdup(creds, creds_in->account_name);
	if (!creds->account_name) {
		talloc_free(creds);
		return NULL;
	}

	if (creds_in->sid) {
		creds->sid = dom_sid_dup(creds, creds_in->sid);
		if (!creds->sid) {
			talloc_free(creds);
			return NULL;
		}
	}

	memcpy(creds->session_key, creds_in->session_key, sizeof(creds->session_key));
	memcpy(creds->seed.data, creds_in->seed.data, sizeof(creds->seed.data));
	memcpy(creds->client.data, creds_in->client.data, sizeof(creds->client.data));
	memcpy(creds->server.data, creds_in->server.data, sizeof(creds->server.data));

	return creds;
}
Beispiel #13
0
/* Recv the SAMR details (SamrConnect and SamrOpenDomain handle) and
 * open an LDAP connection */
static void init_domain_recv_samr(struct composite_context *ctx)
{
	struct init_domain_state *state =
		talloc_get_type(ctx->async.private_data,
				struct init_domain_state);

	state->ctx->status = wb_connect_samr_recv(
		ctx, state->domain,
		&state->domain->libnet_ctx->samr.pipe,
		&state->domain->libnet_ctx->samr.connect_handle,
		&state->domain->libnet_ctx->samr.handle);
	if (!composite_is_ok(state->ctx)) return;

	talloc_reparent(state, state->domain->libnet_ctx->samr.pipe, state->domain->samr_binding);
	state->domain->libnet_ctx->samr.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	state->domain->libnet_ctx->samr.name = state->domain->info->name;
	state->domain->libnet_ctx->samr.sid = dom_sid_dup(
						state->domain->libnet_ctx,
						state->domain->info->sid);

	composite_done(state->ctx);
}
Beispiel #14
0
static NTSTATUS get_system_info3(TALLOC_CTX *mem_ctx,
				 struct passwd *pwd,
				 struct netr_SamInfo3 *info3)
{
	struct dom_sid domain_sid;
	const char *tmp;

	/* Set account name */
	tmp = talloc_strdup(mem_ctx, pwd->pw_name);
	if (tmp == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	init_lsa_String(&info3->base.account_name, tmp);

	/* Set domain name */
	tmp = talloc_strdup(mem_ctx, get_global_sam_name());
	if (tmp == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	init_lsa_StringLarge(&info3->base.domain, tmp);

	/* Domain sid */
	sid_copy(&domain_sid, get_global_sam_sid());

	info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
	if (info3->base.domain_sid == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	/* Admin rid */
	info3->base.rid = DOMAIN_RID_ADMINISTRATOR;

	/* Primary gid */
	info3->base.primary_gid = BUILTIN_RID_ADMINISTRATORS;

	return NT_STATUS_OK;
}
Beispiel #15
0
bool torture_rpc_lsa_lookup(struct torture_context *torture)
{
        NTSTATUS status;
        struct dcerpc_pipe *p;
	bool ret = true;
	struct policy_handle *handle;
	struct dom_sid *dom_sid = NULL;
	struct dom_sid *trusted_sid = NULL;
	struct dom_sid *sids[NUM_SIDS];
	struct dcerpc_binding_handle *b;

	status = torture_rpc_connection(torture, &p, &ndr_table_lsarpc);
	if (!NT_STATUS_IS_OK(status)) {
		torture_fail(torture, "unable to connect to table");
	}
	b = p->binding_handle;

	if (p->binding->transport != NCACN_NP &&
	    p->binding->transport != NCALRPC) {
		torture_comment(torture,
				"torture_rpc_lsa_lookup is only available "
				"over NCACN_NP or NCALRPC");
		return true;
	}

	ret &= open_policy(torture, b, &handle);
	if (!ret) return false;

	ret &= get_domainsid(torture, b, handle, &dom_sid);
	if (!ret) return false;

	ret &= get_downleveltrust(torture, b, handle, &trusted_sid);
	if (!ret) return false;

	torture_comment(torture, "domain sid: %s\n", 
					dom_sid_string(torture, dom_sid));

	sids[0] = dom_sid_parse_talloc(torture, "S-1-1-0");
	sids[1] = dom_sid_parse_talloc(torture, "S-1-5-4");
	sids[2] = dom_sid_parse_talloc(torture, "S-1-5-32");
	sids[3] = dom_sid_parse_talloc(torture, "S-1-5-32-545");
	sids[4] = dom_sid_dup(torture, dom_sid);
	sids[5] = dom_sid_add_rid(torture, dom_sid, 512);
	sids[6] = dom_sid_dup(torture, trusted_sid);
	sids[7] = dom_sid_add_rid(torture, trusted_sid, 512);

	ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 0,
			       NT_STATUS_INVALID_PARAMETER, NULL);

	{
		enum lsa_SidType types[NUM_SIDS] =
			{ SID_NAME_WKN_GRP, SID_NAME_WKN_GRP, SID_NAME_DOMAIN,
			  SID_NAME_ALIAS, SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
			  SID_NAME_DOMAIN, SID_NAME_DOM_GRP };

		ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 1,
				       NT_STATUS_OK, types);
	}

	{
		enum lsa_SidType types[NUM_SIDS] =
			{ SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
			  SID_NAME_DOMAIN, SID_NAME_DOM_GRP };
		ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 2,
				       STATUS_SOME_UNMAPPED, types);
	}

	{
		enum lsa_SidType types[NUM_SIDS] =
			{ SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
		ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 3,
				       STATUS_SOME_UNMAPPED, types);
	}

	{
		enum lsa_SidType types[NUM_SIDS] =
			{ SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
		ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 4,
				       STATUS_SOME_UNMAPPED, types);
	}

	ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 5,
			       NT_STATUS_NONE_MAPPED, NULL);

	{
		enum lsa_SidType types[NUM_SIDS] =
			{ SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
		ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 6,
				       STATUS_SOME_UNMAPPED, types);
	}

	ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 7,
			       NT_STATUS_INVALID_PARAMETER, NULL);
	ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 8,
			       NT_STATUS_INVALID_PARAMETER, NULL);
	ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 9,
			       NT_STATUS_INVALID_PARAMETER, NULL);
	ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 10,
			       NT_STATUS_INVALID_PARAMETER, NULL);

	return ret;
}
Beispiel #16
0
NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx,
			  struct samu *samu,
			  const char *login_server,
			  struct netr_SamInfo3 **_info3,
			  struct extra_auth_info *extra)
{
	struct netr_SamInfo3 *info3;
	const struct dom_sid *user_sid;
	const struct dom_sid *group_sid;
	struct dom_sid domain_sid;
	struct dom_sid *group_sids;
	uint32_t num_group_sids = 0;
	const char *tmp;
	gid_t *gids;
	NTSTATUS status;

	user_sid = pdb_get_user_sid(samu);
	group_sid = pdb_get_group_sid(samu);

	if (!user_sid || !group_sid) {
		DEBUG(1, ("Sam account is missing sids!\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}

	info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
	if (!info3) {
		return NT_STATUS_NO_MEMORY;
	}

	ZERO_STRUCT(domain_sid);

	status = SamInfo3_handle_sids(pdb_get_username(samu),
				user_sid,
				group_sid,
				info3,
				&domain_sid,
				extra);

	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(info3);
		return status;
	}

	unix_to_nt_time(&info3->base.logon_time, pdb_get_logon_time(samu));
	unix_to_nt_time(&info3->base.logoff_time, get_time_t_max());
	unix_to_nt_time(&info3->base.kickoff_time, get_time_t_max());
	unix_to_nt_time(&info3->base.last_password_change,
			pdb_get_pass_last_set_time(samu));
	unix_to_nt_time(&info3->base.allow_password_change,
			pdb_get_pass_can_change_time(samu));
	unix_to_nt_time(&info3->base.force_password_change,
			pdb_get_pass_must_change_time(samu));

	tmp = pdb_get_username(samu);
	if (tmp) {
		info3->base.account_name.string	= talloc_strdup(info3, tmp);
		RET_NOMEM(info3->base.account_name.string);
	}
	tmp = pdb_get_fullname(samu);
	if (tmp) {
		info3->base.full_name.string = talloc_strdup(info3, tmp);
		RET_NOMEM(info3->base.full_name.string);
	}
	tmp = pdb_get_logon_script(samu);
	if (tmp) {
		info3->base.logon_script.string = talloc_strdup(info3, tmp);
		RET_NOMEM(info3->base.logon_script.string);
	}
	tmp = pdb_get_profile_path(samu);
	if (tmp) {
		info3->base.profile_path.string	= talloc_strdup(info3, tmp);
		RET_NOMEM(info3->base.profile_path.string);
	}
	tmp = pdb_get_homedir(samu);
	if (tmp) {
		info3->base.home_directory.string = talloc_strdup(info3, tmp);
		RET_NOMEM(info3->base.home_directory.string);
	}
	tmp = pdb_get_dir_drive(samu);
	if (tmp) {
		info3->base.home_drive.string = talloc_strdup(info3, tmp);
		RET_NOMEM(info3->base.home_drive.string);
	}

	info3->base.logon_count	= pdb_get_logon_count(samu);
	info3->base.bad_password_count = pdb_get_bad_password_count(samu);

	info3->base.logon_domain.string = talloc_strdup(info3,
						  pdb_get_domain(samu));
	RET_NOMEM(info3->base.logon_domain.string);

	info3->base.domain_sid = dom_sid_dup(info3, &domain_sid);
	RET_NOMEM(info3->base.domain_sid);

	status = pdb_enum_group_memberships(mem_ctx, samu,
					    &group_sids, &gids,
					    &num_group_sids);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(1, ("Failed to get groups from sam account.\n"));
		TALLOC_FREE(info3);
		return status;
	}

	if (num_group_sids) {
		status = group_sids_to_info3(info3, group_sids, num_group_sids);
		if (!NT_STATUS_IS_OK(status)) {
			TALLOC_FREE(info3);
			return status;
		}
	}

	/* We don't need sids and gids after the conversion */
	TALLOC_FREE(group_sids);
	TALLOC_FREE(gids);
	num_group_sids = 0;

	/* FIXME: should we add other flags ? */
	info3->base.user_flags = NETLOGON_EXTRA_SIDS;

	if (login_server) {
		info3->base.logon_server.string = talloc_strdup(info3, login_server);
		RET_NOMEM(info3->base.logon_server.string);
	}

	info3->base.acct_flags = pdb_get_acct_ctrl(samu);

	*_info3 = info3;
	return NT_STATUS_OK;
}
Beispiel #17
0
NTSTATUS passwd_to_SamInfo3(TALLOC_CTX *mem_ctx,
			    const char *unix_username,
			    const struct passwd *pwd,
			    struct netr_SamInfo3 **pinfo3,
			    struct extra_auth_info *extra)
{
	struct netr_SamInfo3 *info3;
	NTSTATUS status;
	TALLOC_CTX *tmp_ctx;
	const char *domain_name = NULL;
	const char *user_name = NULL;
	struct dom_sid domain_sid;
	struct dom_sid user_sid;
	struct dom_sid group_sid;
	enum lsa_SidType type;
	uint32_t num_sids = 0;
	struct dom_sid *user_sids = NULL;
	bool is_null;
	bool ok;

	tmp_ctx = talloc_stackframe();

	ok = lookup_name_smbconf(tmp_ctx,
				 unix_username,
				 LOOKUP_NAME_ALL,
				 &domain_name,
				 &user_name,
				 &user_sid,
				 &type);
	if (!ok) {
		status = NT_STATUS_NO_SUCH_USER;
		goto done;
	}

	if (type != SID_NAME_USER) {
		status = NT_STATUS_NO_SUCH_USER;
		goto done;
	}

	ok = winbind_lookup_usersids(tmp_ctx,
				     &user_sid,
				     &num_sids,
				     &user_sids);
	/* Check if winbind is running */
	if (ok) {
		/*
		 * Winbind is running and the first element of the user_sids
		 * is the primary group.
		 */
		if (num_sids > 0) {
			group_sid = user_sids[0];
		}
	} else {
		/*
		 * Winbind is not running, try to create the group_sid from the
		 * passwd group id.
		 */

		/*
		 * This can lead to a primary group of S-1-22-2-XX which
		 * will be rejected by other Samba code.
		 */
		gid_to_sid(&group_sid, pwd->pw_gid);
	}

	/*
	 * If we are a unix group, or a wellknown/builtin alias,
	 * set the group_sid to the
	 * 'Domain Users' RID of 513 which will always resolve to a
	 * name.
	 */
	if (sid_check_is_in_unix_groups(&group_sid) ||
	    sid_check_is_in_builtin(&group_sid) ||
	    sid_check_is_in_wellknown_domain(&group_sid)) {
		if (sid_check_is_in_unix_users(&user_sid)) {
			sid_compose(&group_sid,
				    get_global_sam_sid(),
				    DOMAIN_RID_USERS);
		} else {
			sid_copy(&domain_sid, &user_sid);
			sid_split_rid(&domain_sid, NULL);
			sid_compose(&group_sid,
				    &domain_sid,
				    DOMAIN_RID_USERS);
		}
	}

	/* Make sure we have a valid group sid */
	is_null = is_null_sid(&group_sid);
	if (is_null) {
		status = NT_STATUS_NO_SUCH_USER;
		goto done;
	}

	/* Construct a netr_SamInfo3 from the information we have */
	info3 = talloc_zero(tmp_ctx, struct netr_SamInfo3);
	if (!info3) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	info3->base.account_name.string = talloc_strdup(info3, unix_username);
	if (info3->base.account_name.string == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	ZERO_STRUCT(domain_sid);

	status = SamInfo3_handle_sids(unix_username,
				&user_sid,
				&group_sid,
				info3,
				&domain_sid,
				extra);

	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	info3->base.domain_sid = dom_sid_dup(info3, &domain_sid);
	if (info3->base.domain_sid == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	ok = sid_peek_check_rid(&domain_sid, &group_sid,
				&info3->base.primary_gid);
	if (!ok) {
		DEBUG(1, ("The primary group domain sid(%s) does not "
			  "match the domain sid(%s) for %s(%s)\n",
			  sid_string_dbg(&group_sid),
			  sid_string_dbg(&domain_sid),
			  unix_username,
			  sid_string_dbg(&user_sid)));
		status = NT_STATUS_INVALID_SID;
		goto done;
	}

	info3->base.acct_flags = ACB_NORMAL;

	if (num_sids) {
		status = group_sids_to_info3(info3, user_sids, num_sids);
		if (!NT_STATUS_IS_OK(status)) {
			goto done;
		}
	}

	*pinfo3 = talloc_steal(mem_ctx, info3);

	status = NT_STATUS_OK;
done:
	talloc_free(tmp_ctx);

	return status;
}
Beispiel #18
0
static NTSTATUS dcerpc_lsa_lookup_sids_noalloc(struct dcerpc_binding_handle *h,
					       TALLOC_CTX *mem_ctx,
					       TALLOC_CTX *domains_ctx,
					       TALLOC_CTX *names_ctx,
					       struct policy_handle *pol,
					       int num_sids,
					       const struct dom_sid *sids,
					       char **domains,
					       char **names,
					       enum lsa_SidType *types,
					       bool use_lookupsids3,
					       NTSTATUS *presult)
{
	NTSTATUS status = NT_STATUS_OK;
	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
	struct lsa_SidArray sid_array;
	struct lsa_RefDomainList *ref_domains = NULL;
	struct lsa_TransNameArray lsa_names;
	enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL;
	uint32_t count = 0;
	int i;

	ZERO_STRUCT(lsa_names);

	sid_array.num_sids = num_sids;
	sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr, num_sids);
	if (sid_array.sids == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	for (i = 0; i<num_sids; i++) {
		sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[i]);
		if (!sid_array.sids[i].sid) {
			return NT_STATUS_NO_MEMORY;
		}
	}

	if (use_lookupsids3) {
		struct lsa_TransNameArray2 lsa_names2;
		uint32_t n;

		ZERO_STRUCT(lsa_names2);

		status = dcerpc_lsa_LookupSids3(h,
						mem_ctx,
						&sid_array,
						&ref_domains,
						&lsa_names2,
						level,
						&count,
						LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES,
						LSA_CLIENT_REVISION_2,
						&result);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}

		if(!NT_STATUS_IS_ERR(result)) {
			lsa_names.count = lsa_names2.count;
			lsa_names.names = talloc_array(mem_ctx,
						       struct lsa_TranslatedName,
						       lsa_names.count);
			if (lsa_names.names == NULL) {
				return NT_STATUS_NO_MEMORY;
			}
			for (n=0; n < lsa_names.count; n++) {
				lsa_names.names[n].sid_type	= lsa_names2.names[n].sid_type;
				lsa_names.names[n].name		= lsa_names2.names[n].name;
				lsa_names.names[n].sid_index	= lsa_names2.names[n].sid_index;
			}
		}

	} else {
Beispiel #19
0
static int samldb_fill_foreignSecurityPrincipal_object(struct ldb_module *module, const struct ldb_message *msg, 
						       struct ldb_message **ret_msg)
{
	struct ldb_message *msg2;
	const char *rdn_name;
	struct dom_sid *dom_sid;
	struct dom_sid *sid;
	const char *dom_attrs[] = { "name", NULL };
	struct ldb_message **dom_msgs;
	const char *errstr;
	int ret;

	TALLOC_CTX *mem_ctx = talloc_new(msg);
	if (!mem_ctx) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* build the new msg */
	msg2 = ldb_msg_copy(mem_ctx, msg);
	if (!msg2) {
		ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_foreignSecurityPrincpal_object: ldb_msg_copy failed!\n");
		talloc_free(mem_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ret = samdb_copy_template(module->ldb, msg2, 
				  "(&(CN=TemplateForeignSecurityPrincipal)(objectclass=foreignSecurityPrincipalTemplate))",
				  &errstr);
	if (ret != 0) {
		ldb_asprintf_errstring(module->ldb, 
				       "samldb_fill_foreignSecurityPrincipal_object: "
				       "Error copying template: %s",
				    errstr);
		talloc_free(mem_ctx);
		return ret;
	}

	rdn_name = ldb_dn_get_rdn_name(msg2->dn);

	if (strcasecmp(rdn_name, "cn") != 0) {
		ldb_asprintf_errstring(module->ldb, "Bad RDN (%s=) for ForeignSecurityPrincipal, should be CN=!", rdn_name);
		talloc_free(mem_ctx);
		return LDB_ERR_CONSTRAINT_VIOLATION;
	}

	/* Slightly different for the foreign sids.  We don't want
	 * domain SIDs ending up there, it would cause all sorts of
	 * pain */

	sid = dom_sid_parse_talloc(msg2, (const char *)ldb_dn_get_rdn_val(msg2->dn)->data);
	if (!sid) {
		ldb_set_errstring(module->ldb, "No valid found SID in ForeignSecurityPrincipal CN!");
		talloc_free(mem_ctx);
		return LDB_ERR_CONSTRAINT_VIOLATION;
	}

	if ( ! samldb_msg_add_sid(module, msg2, "objectSid", sid)) {
		talloc_free(sid);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	dom_sid = dom_sid_dup(mem_ctx, sid);
	if (!dom_sid) {
		talloc_free(mem_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}
	/* get the domain component part of the provided SID */
	dom_sid->num_auths--;

	/* find the domain DN */

	ret = gendb_search(module->ldb,
			   mem_ctx, NULL, &dom_msgs, dom_attrs,
			   "(&(objectSid=%s)(objectclass=domain))",
			   ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));
	if (ret >= 1) {
		/* We don't really like the idea of foreign sids that are not foreign, but it happens */
		const char *name = samdb_result_string(dom_msgs[0], "name", NULL);
		ldb_debug(module->ldb, LDB_DEBUG_TRACE, "NOTE (strange but valid): Adding foreign SID record with SID %s, but this domian (%s) is already in the database", 
			  dom_sid_string(mem_ctx, sid), name); 
	} else if (ret == -1) {
		ldb_asprintf_errstring(module->ldb,
					"samldb_fill_foreignSecurityPrincipal_object: error searching for a domain with this sid: %s\n", 
					dom_sid_string(mem_ctx, dom_sid));
		talloc_free(dom_msgs);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* This isn't an operation on a domain we know about, so just
	 * check for the SID, looking for duplicates via the common
	 * code */
	ret = samldb_notice_sid(module, msg2, sid);
	if (ret == 0) {
		talloc_steal(msg, msg2);
		*ret_msg = msg2;
	}
	
	return ret;
}
Beispiel #20
0
int samldb_notice_sid(struct ldb_module *module, 
		      TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
{
	int ret;
	struct ldb_dn *dom_dn;
	struct dom_sid *dom_sid;
	const char *attrs[] = { NULL };
	struct ldb_result *dom_res;
	struct ldb_result *res;
	uint32_t old_rid;

	/* find if this SID already exists */
	ret = ldb_search_exp_fmt(module->ldb, mem_ctx, &res,
				 NULL, LDB_SCOPE_SUBTREE, attrs,
				 "(objectSid=%s)", ldap_encode_ndr_dom_sid(mem_ctx, sid));
	if (ret == LDB_SUCCESS) {
		if (res->count > 0) {
			talloc_free(res);
			ldb_asprintf_errstring(module->ldb,
						"Attempt to add record with SID %s rejected,"
						" because this SID is already in the database",
						dom_sid_string(mem_ctx, sid));
			/* We have a duplicate SID, we must reject the add */
			return LDB_ERR_CONSTRAINT_VIOLATION;
		}
		talloc_free(res);
	} else {
		ldb_asprintf_errstring(module->ldb,
					"samldb_notice_sid: error searching to see if sid %s is in use: %s\n", 
					dom_sid_string(mem_ctx, sid), 
					ldb_errstring(module->ldb));
		return ret;
	}

	dom_sid = dom_sid_dup(mem_ctx, sid);
	if (!dom_sid) {
		return LDB_ERR_OPERATIONS_ERROR;
	}
	/* get the domain component part of the provided SID */
	dom_sid->num_auths--;

	/* find the domain DN */
	ret = ldb_search_exp_fmt(module->ldb, mem_ctx, &dom_res,
				 NULL, LDB_SCOPE_SUBTREE, attrs,
				 "(&(objectSid=%s)(objectclass=domain))",
				 ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));
	if (ret == LDB_SUCCESS) {
		if (dom_res->count == 0) {
			talloc_free(dom_res);
			/* This isn't an operation on a domain we know about, so nothing to update */
			return LDB_SUCCESS;
		}

		if (dom_res->count > 1) {
			talloc_free(dom_res);
			ldb_asprintf_errstring(module->ldb,
					"samldb_notice_sid: error retrieving domain from sid: duplicate (found %d) domain: %s!\n", 
					dom_res->count, dom_sid_string(dom_res, dom_sid));
			return LDB_ERR_OPERATIONS_ERROR;
		}
	} else {
		ldb_asprintf_errstring(module->ldb,
					"samldb_notice_sid: error retrieving domain from sid: %s: %s\n", 
					dom_sid_string(dom_res, dom_sid), 
					ldb_errstring(module->ldb));
		return ret;
	}

	dom_dn = dom_res->msgs[0]->dn;

	ret = samldb_find_next_rid(module, mem_ctx, 
				   dom_dn, &old_rid);
	if (ret) {
		talloc_free(dom_res);
		return ret;
	}

	if (old_rid <= sid->sub_auths[sid->num_auths - 1]) {
		ret = samldb_set_next_rid(module->ldb, mem_ctx, dom_dn, old_rid, 
					  sid->sub_auths[sid->num_auths - 1] + 1);
	}
	talloc_free(dom_res);
	return ret;
}
static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
				   struct smb_krb5_context *smb_krb5_context,
				   uint32_t format_flags, enum drsuapi_DsNameFormat format_offered,
				   enum drsuapi_DsNameFormat format_desired,
				   struct ldb_dn *name_dn, const char *name, 
				   const char *domain_filter, const char *result_filter, 
				   struct drsuapi_DsNameInfo1 *info1,
				   int scope, struct ldb_dn *search_dn)
{
	int ldb_ret;
	struct ldb_result *domain_res = NULL;
	const char * const *domain_attrs;
	const char * const *result_attrs;
	struct ldb_message **result_res = NULL;
	struct ldb_message *result = NULL;
	int i;
	char *p;
	struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);

	const char * const _domain_attrs_1779[] = { "ncName", "dnsRoot", NULL};
	const char * const _result_attrs_null[] = { NULL };

	const char * const _domain_attrs_canonical[] = { "ncName", "dnsRoot", NULL};
	const char * const _result_attrs_canonical[] = { "canonicalName", NULL };

	const char * const _domain_attrs_nt4[] = { "ncName", "dnsRoot", "nETBIOSName", NULL};
	const char * const _result_attrs_nt4[] = { "sAMAccountName", "objectSid", "objectClass", NULL};

	const char * const _domain_attrs_guid[] = { "ncName", "dnsRoot", NULL};
	const char * const _result_attrs_guid[] = { "objectGUID", NULL};

	const char * const _domain_attrs_display[] = { "ncName", "dnsRoot", NULL};
	const char * const _result_attrs_display[] = { "displayName", "samAccountName", NULL};

	const char * const _domain_attrs_none[] = { "ncName", "dnsRoot" , NULL};
	const char * const _result_attrs_none[] = { NULL};

	/* here we need to set the attrs lists for domain and result lookups */
	switch (format_desired) {
	case DRSUAPI_DS_NAME_FORMAT_FQDN_1779:
	case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX:
		domain_attrs = _domain_attrs_1779;
		result_attrs = _result_attrs_null;
		break;
	case DRSUAPI_DS_NAME_FORMAT_CANONICAL:
		domain_attrs = _domain_attrs_canonical;
		result_attrs = _result_attrs_canonical;
		break;
	case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT:
		domain_attrs = _domain_attrs_nt4;
		result_attrs = _result_attrs_nt4;
		break;
	case DRSUAPI_DS_NAME_FORMAT_GUID:		
		domain_attrs = _domain_attrs_guid;
		result_attrs = _result_attrs_guid;
		break;
	case DRSUAPI_DS_NAME_FORMAT_DISPLAY:		
		domain_attrs = _domain_attrs_display;
		result_attrs = _result_attrs_display;
		break;
	default:
		domain_attrs = _domain_attrs_none;
		result_attrs = _result_attrs_none;
		break;
	}

	if (domain_filter) {
		/* if we have a domain_filter look it up and set the result_basedn and the dns_domain_name */
		ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
					     partitions_basedn,
					     LDB_SCOPE_ONELEVEL,
					     domain_attrs,
					     "%s", domain_filter);

		if (ldb_ret != LDB_SUCCESS) {
			DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s\n", ldb_errstring(sam_ctx)));
			info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
			return WERR_OK;
		}

		switch (domain_res->count) {
		case 1:
			break;
		case 0:
			info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
			return WERR_OK;
		default:
			info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
			return WERR_OK;
		}

		info1->dns_domain_name	= ldb_msg_find_attr_as_string(domain_res->msgs[0], "dnsRoot", NULL);
		W_ERROR_HAVE_NO_MEMORY(info1->dns_domain_name);
		info1->status		= DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY;
	} else {
		info1->dns_domain_name	= NULL;
		info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
	}

	if (result_filter) {
		int ret;
		struct ldb_result *res;
		uint32_t dsdb_flags = 0;
		struct ldb_dn *real_search_dn = NULL;
		info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;

		/*
		 * From 4.1.4.2.11 of MS-DRSR
		 * if DS_NAME_FLAG_GCVERIFY in flags then
		 * rt := select all O from all
		 * where attrValue in GetAttrVals(O, att, false)
		 * else
		 * rt := select all O from subtree DefaultNC()
		 * where attrValue in GetAttrVals(O, att, false)
		 * endif
		 * return rt
		 */
		if (format_flags & DRSUAPI_DS_NAME_FLAG_GCVERIFY ||
		    format_offered == DRSUAPI_DS_NAME_FORMAT_GUID)
		{
			dsdb_flags = DSDB_SEARCH_SEARCH_ALL_PARTITIONS;
		} else if (domain_res) {
			if (!search_dn) {
				struct ldb_dn *tmp_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL);
				real_search_dn = tmp_dn;
			} else {
				real_search_dn = search_dn;
			}
		} else {
			real_search_dn = ldb_get_default_basedn(sam_ctx);
		}
		if (format_desired == DRSUAPI_DS_NAME_FORMAT_GUID){
			 dsdb_flags |= DSDB_SEARCH_SHOW_RECYCLED;
		}
		/* search with the 'phantom root' flag */
		ret = dsdb_search(sam_ctx, mem_ctx, &res,
				  real_search_dn,
				  scope,
				  result_attrs,
				  dsdb_flags,
				  "%s", result_filter);
		if (ret != LDB_SUCCESS) {
			DEBUG(2, ("DsCrackNameOneFilter search from '%s' with flags 0x%08x failed: %s\n",
				  ldb_dn_get_linearized(real_search_dn),
				  dsdb_flags,
				  ldb_errstring(sam_ctx)));
			info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
			return WERR_OK;
		}

		ldb_ret = res->count;
		result_res = res->msgs;
	} else if (format_offered == DRSUAPI_DS_NAME_FORMAT_FQDN_1779) {
		ldb_ret = gendb_search_dn(sam_ctx, mem_ctx, name_dn, &result_res,
					  result_attrs);
	} else if (domain_res) {
		name_dn = samdb_result_dn(sam_ctx, mem_ctx, domain_res->msgs[0], "ncName", NULL);
		ldb_ret = gendb_search_dn(sam_ctx, mem_ctx, name_dn, &result_res,
					  result_attrs);
	} else {
		/* Can't happen */
		DEBUG(0, ("LOGIC ERROR: DsCrackNameOneFilter domain ref search not available: This can't happen...\n"));
		info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
		return WERR_OK;
	}

	switch (ldb_ret) {
	case 1:
		result = result_res[0];
		break;
	case 0:
		switch (format_offered) {
		case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL: 
			return DsCrackNameSPNAlias(sam_ctx, mem_ctx, 
						   smb_krb5_context, 
						   format_flags, format_offered, format_desired,
						   name, info1);

		case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
			return DsCrackNameUPN(sam_ctx, mem_ctx, smb_krb5_context, 
					      format_flags, format_offered, format_desired,
					      name, info1);
		default:
			break;
		}
		info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
		return WERR_OK;
	case -1:
		DEBUG(2, ("DsCrackNameOneFilter result search failed: %s\n", ldb_errstring(sam_ctx)));
		info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
		return WERR_OK;
	default:
		switch (format_offered) {
		case DRSUAPI_DS_NAME_FORMAT_CANONICAL:
		case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX:
		{
			const char *canonical_name = NULL; /* Not required, but we get warnings... */
			/* We may need to manually filter further */
			for (i = 0; i < ldb_ret; i++) {
				switch (format_offered) {
				case DRSUAPI_DS_NAME_FORMAT_CANONICAL:
					canonical_name = ldb_dn_canonical_string(mem_ctx, result_res[i]->dn);
					break;
				case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX:
					canonical_name = ldb_dn_canonical_ex_string(mem_ctx, result_res[i]->dn);
					break;
				default:
					break;
				}
				if (strcasecmp_m(canonical_name, name) == 0) {
					result = result_res[i];
					break;
				}
			}
			if (!result) {
				info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
				return WERR_OK;
			}
		}
		/* FALL TROUGH */
		default:
			info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
			return WERR_OK;
		}
	}

	info1->dns_domain_name = ldb_dn_canonical_string(mem_ctx, result->dn);
	W_ERROR_HAVE_NO_MEMORY(info1->dns_domain_name);
	p = strchr(info1->dns_domain_name, '/');
	if (p) {
		p[0] = '\0';
	}

	/* here we can use result and domain_res[0] */
	switch (format_desired) {
	case DRSUAPI_DS_NAME_FORMAT_FQDN_1779: {
		info1->result_name	= ldb_dn_alloc_linearized(mem_ctx, result->dn);
		W_ERROR_HAVE_NO_MEMORY(info1->result_name);

		info1->status		= DRSUAPI_DS_NAME_STATUS_OK;
		return WERR_OK;
	}
	case DRSUAPI_DS_NAME_FORMAT_CANONICAL: {
		info1->result_name	= ldb_msg_find_attr_as_string(result, "canonicalName", NULL);
		info1->status		= DRSUAPI_DS_NAME_STATUS_OK;
		return WERR_OK;
	}
	case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX: {
		/* Not in the virtual ldb attribute */
		return DsCrackNameOneSyntactical(mem_ctx, 
						 DRSUAPI_DS_NAME_FORMAT_FQDN_1779, 
						 DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
						 result->dn, name, info1);
	}
	case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: {

		const struct dom_sid *sid = samdb_result_dom_sid(mem_ctx, result, "objectSid");
		const char *_acc = "", *_dom = "";
		if (sid == NULL) {
			info1->status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING;
			return WERR_OK;
		}

		if (samdb_find_attribute(sam_ctx, result, "objectClass",
					 "domain")) {
			/* This can also find a DomainDNSZones entry,
			 * but it won't have the SID we just
			 * checked.  */
			ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
						     partitions_basedn,
						     LDB_SCOPE_ONELEVEL,
						     domain_attrs,
						     "(ncName=%s)", ldb_dn_get_linearized(result->dn));

			if (ldb_ret != LDB_SUCCESS) {
				DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s\n", ldb_errstring(sam_ctx)));
				info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
				return WERR_OK;
			}

			switch (domain_res->count) {
			case 1:
				break;
			case 0:
				info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
				return WERR_OK;
			default:
				info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
				return WERR_OK;
			}
			_dom = ldb_msg_find_attr_as_string(domain_res->msgs[0], "nETBIOSName", NULL);
			W_ERROR_HAVE_NO_MEMORY(_dom);
		} else {
			_acc = ldb_msg_find_attr_as_string(result, "sAMAccountName", NULL);
			if (!_acc) {
				info1->status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING;
				return WERR_OK;
			}
			if (dom_sid_in_domain(dom_sid_parse_talloc(mem_ctx, SID_BUILTIN), sid)) {
				_dom = "BUILTIN";
			} else {
				const char *attrs[] = { NULL };
				struct ldb_result *domain_res2;
				struct dom_sid *dom_sid = dom_sid_dup(mem_ctx, sid);
				if (!dom_sid) {
					return WERR_OK;
				}
				dom_sid->num_auths--;
				ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
							     NULL,
							     LDB_SCOPE_BASE,
							     attrs,
							     "(&(objectSid=%s)(objectClass=domain))", 
							     ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));

				if (ldb_ret != LDB_SUCCESS) {
					DEBUG(2, ("DsCrackNameOneFilter domain search failed: %s\n", ldb_errstring(sam_ctx)));
					info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
					return WERR_OK;
				}

				switch (domain_res->count) {
				case 1:
					break;
				case 0:
					info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
					return WERR_OK;
				default:
					info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
					return WERR_OK;
				}

				ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res2,
							     partitions_basedn,
							     LDB_SCOPE_ONELEVEL,
							     domain_attrs,
							     "(ncName=%s)", ldb_dn_get_linearized(domain_res->msgs[0]->dn));

				if (ldb_ret != LDB_SUCCESS) {
					DEBUG(2, ("DsCrackNameOneFilter domain ref search failed: %s\n", ldb_errstring(sam_ctx)));
					info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
					return WERR_OK;
				}

				switch (domain_res2->count) {
				case 1:
					break;
				case 0:
					info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
					return WERR_OK;
				default:
					info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
					return WERR_OK;
				}
				_dom = ldb_msg_find_attr_as_string(domain_res2->msgs[0], "nETBIOSName", NULL);
				W_ERROR_HAVE_NO_MEMORY(_dom);
			}
		}

		info1->result_name	= talloc_asprintf(mem_ctx, "%s\\%s", _dom, _acc);
		W_ERROR_HAVE_NO_MEMORY(info1->result_name);

		info1->status		= DRSUAPI_DS_NAME_STATUS_OK;
		return WERR_OK;
	}
	case DRSUAPI_DS_NAME_FORMAT_GUID: {
		struct GUID guid;

		guid = samdb_result_guid(result, "objectGUID");

		info1->result_name	= GUID_string2(mem_ctx, &guid);
		W_ERROR_HAVE_NO_MEMORY(info1->result_name);

		info1->status		= DRSUAPI_DS_NAME_STATUS_OK;
		return WERR_OK;
	}
	case DRSUAPI_DS_NAME_FORMAT_DISPLAY: {
		info1->result_name	= ldb_msg_find_attr_as_string(result, "displayName", NULL);
		if (!info1->result_name) {
			info1->result_name	= ldb_msg_find_attr_as_string(result, "sAMAccountName", NULL);
		} 
		if (!info1->result_name) {
			info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
		} else {
			info1->status = DRSUAPI_DS_NAME_STATUS_OK;
		}
		return WERR_OK;
	}
	case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL: {
		info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
		return WERR_OK;
	}
	case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN:	
	case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: {
		info1->dns_domain_name = NULL;
		info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
		return WERR_OK;
	}
	default:
		info1->status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING;
		return WERR_OK;
	}
}
Beispiel #22
0
BOOL torture_rpc_lsa_lookup(struct torture_context *torture)
{
        NTSTATUS status;
        struct dcerpc_pipe *p;
	TALLOC_CTX *mem_ctx;
	BOOL ret = True;
	struct policy_handle *handle;
	struct dom_sid *dom_sid;
	struct dom_sid *trusted_sid;
	struct dom_sid *sids[NUM_SIDS];

	mem_ctx = talloc_init("torture_rpc_lsa");

	status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_lsarpc);
	if (!NT_STATUS_IS_OK(status)) {
		ret = False;
		goto done;
	}

	ret &= open_policy(mem_ctx, p, &handle);
	if (!ret) goto done;

	ret &= get_domainsid(mem_ctx, p, handle, &dom_sid);
	if (!ret) goto done;

	ret &= get_downleveltrust(mem_ctx, p, handle, &trusted_sid);
	if (!ret) goto done;

	printf("domain sid: %s\n", dom_sid_string(mem_ctx, dom_sid));

	sids[0] = dom_sid_parse_talloc(mem_ctx, "S-1-1-0");
	sids[1] = dom_sid_parse_talloc(mem_ctx, "S-1-5-4");
	sids[2] = dom_sid_parse_talloc(mem_ctx, "S-1-5-32");
	sids[3] = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-545");
	sids[4] = dom_sid_dup(mem_ctx, dom_sid);
	sids[5] = dom_sid_add_rid(mem_ctx, dom_sid, 512);
	sids[6] = dom_sid_dup(mem_ctx, trusted_sid);
	sids[7] = dom_sid_add_rid(mem_ctx, trusted_sid, 512);

	ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 0,
			       NT_STATUS_INVALID_PARAMETER, NULL);

	{
		enum lsa_SidType types[NUM_SIDS] =
			{ SID_NAME_WKN_GRP, SID_NAME_WKN_GRP, SID_NAME_DOMAIN,
			  SID_NAME_ALIAS, SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
			  SID_NAME_DOMAIN, SID_NAME_DOM_GRP };

		ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 1,
				       NT_STATUS_OK, types);
	}

	{
		enum lsa_SidType types[NUM_SIDS] =
			{ SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
			  SID_NAME_DOMAIN, SID_NAME_DOM_GRP };
		ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 2,
				       STATUS_SOME_UNMAPPED, types);
	}

	{
		enum lsa_SidType types[NUM_SIDS] =
			{ SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
		ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 3,
				       STATUS_SOME_UNMAPPED, types);
	}

	{
		enum lsa_SidType types[NUM_SIDS] =
			{ SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
		ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 4,
				       STATUS_SOME_UNMAPPED, types);
	}

	ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 5,
			       NT_STATUS_NONE_MAPPED, NULL);

	{
		enum lsa_SidType types[NUM_SIDS] =
			{ SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
			  SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
			  SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
		ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 6,
				       STATUS_SOME_UNMAPPED, types);
	}

	ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 7,
			       NT_STATUS_INVALID_PARAMETER, NULL);
	ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 8,
			       NT_STATUS_INVALID_PARAMETER, NULL);
	ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 9,
			       NT_STATUS_INVALID_PARAMETER, NULL);
	ret &= test_lookupsids(mem_ctx, p, handle, sids, NUM_SIDS, 10,
			       NT_STATUS_INVALID_PARAMETER, NULL);

 done:
	talloc_free(mem_ctx);

	return ret;
}
Beispiel #23
0
NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx,
			  struct samu *samu,
			  const char *login_server,
			  struct netr_SamInfo3 **_info3,
			  struct extra_auth_info *extra)
{
	struct netr_SamInfo3 *info3;
	const struct dom_sid *user_sid;
	const struct dom_sid *group_sid;
	struct dom_sid domain_sid;
	struct dom_sid *group_sids;
	uint32_t num_group_sids = 0;
	const char *tmp;
	gid_t *gids;
	NTSTATUS status;
	bool ok;

	user_sid = pdb_get_user_sid(samu);
	group_sid = pdb_get_group_sid(samu);

	if (!user_sid || !group_sid) {
		DEBUG(1, ("Sam account is missing sids!\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}

	info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
	if (!info3) {
		return NT_STATUS_NO_MEMORY;
	}

	ZERO_STRUCT(domain_sid);

	/* check if this is a "Unix Users" domain user,
	 * we need to handle it in a special way if that's the case */
	if (sid_check_is_in_unix_users(user_sid)) {
		/* in info3 you can only set rids for the user and the
		 * primary group, and the domain sid must be that of
		 * the sam domain.
		 *
		 * Store a completely bogus value here.
		 * The real SID is stored in the extra sids.
		 * Other code will know to look there if (-1) is found
		 */
		info3->base.rid = (uint32_t)(-1);
		sid_copy(&extra->user_sid, user_sid);

		DEBUG(10, ("Unix User found in struct samu. Rid marked as "
			   "special and sid (%s) saved as extra sid\n",
			   sid_string_dbg(user_sid)));
	} else {
		sid_copy(&domain_sid, user_sid);
		sid_split_rid(&domain_sid, &info3->base.rid);
	}

	if (is_null_sid(&domain_sid)) {
		sid_copy(&domain_sid, get_global_sam_sid());
	}

	/* check if this is a "Unix Groups" domain group,
	 * if so we need special handling */
	if (sid_check_is_in_unix_groups(group_sid)) {
		/* in info3 you can only set rids for the user and the
		 * primary group, and the domain sid must be that of
		 * the sam domain.
		 *
		 * Store a completely bogus value here.
		 * The real SID is stored in the extra sids.
		 * Other code will know to look there if (-1) is found
		 */
		info3->base.primary_gid = (uint32_t)(-1);
		sid_copy(&extra->pgid_sid, group_sid);

		DEBUG(10, ("Unix Group found in struct samu. Rid marked as "
			   "special and sid (%s) saved as extra sid\n",
			   sid_string_dbg(group_sid)));

	} else {
		ok = sid_peek_check_rid(&domain_sid, group_sid,
					&info3->base.primary_gid);
		if (!ok) {
			DEBUG(1, ("The primary group domain sid(%s) does not "
				  "match the domain sid(%s) for %s(%s)\n",
				  sid_string_dbg(group_sid),
				  sid_string_dbg(&domain_sid),
				  pdb_get_username(samu),
				  sid_string_dbg(user_sid)));
			TALLOC_FREE(info3);
			return NT_STATUS_UNSUCCESSFUL;
		}
	}

	unix_to_nt_time(&info3->base.last_logon, pdb_get_logon_time(samu));
	unix_to_nt_time(&info3->base.last_logoff, get_time_t_max());
	unix_to_nt_time(&info3->base.acct_expiry, get_time_t_max());
	unix_to_nt_time(&info3->base.last_password_change,
			pdb_get_pass_last_set_time(samu));
	unix_to_nt_time(&info3->base.allow_password_change,
			pdb_get_pass_can_change_time(samu));
	unix_to_nt_time(&info3->base.force_password_change,
			pdb_get_pass_must_change_time(samu));

	tmp = pdb_get_username(samu);
	if (tmp) {
		info3->base.account_name.string	= talloc_strdup(info3, tmp);
		RET_NOMEM(info3->base.account_name.string);
	}
	tmp = pdb_get_fullname(samu);
	if (tmp) {
		info3->base.full_name.string = talloc_strdup(info3, tmp);
		RET_NOMEM(info3->base.full_name.string);
	}
	tmp = pdb_get_logon_script(samu);
	if (tmp) {
		info3->base.logon_script.string = talloc_strdup(info3, tmp);
		RET_NOMEM(info3->base.logon_script.string);
	}
	tmp = pdb_get_profile_path(samu);
	if (tmp) {
		info3->base.profile_path.string	= talloc_strdup(info3, tmp);
		RET_NOMEM(info3->base.profile_path.string);
	}
	tmp = pdb_get_homedir(samu);
	if (tmp) {
		info3->base.home_directory.string = talloc_strdup(info3, tmp);
		RET_NOMEM(info3->base.home_directory.string);
	}
	tmp = pdb_get_dir_drive(samu);
	if (tmp) {
		info3->base.home_drive.string = talloc_strdup(info3, tmp);
		RET_NOMEM(info3->base.home_drive.string);
	}

	info3->base.logon_count	= pdb_get_logon_count(samu);
	info3->base.bad_password_count = pdb_get_bad_password_count(samu);

	info3->base.domain.string = talloc_strdup(info3,
						  pdb_get_domain(samu));
	RET_NOMEM(info3->base.domain.string);

	info3->base.domain_sid = dom_sid_dup(info3, &domain_sid);
	RET_NOMEM(info3->base.domain_sid);

	status = pdb_enum_group_memberships(mem_ctx, samu,
					    &group_sids, &gids,
					    &num_group_sids);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(1, ("Failed to get groups from sam account.\n"));
		TALLOC_FREE(info3);
		return status;
	}

	if (num_group_sids) {
		status = group_sids_to_info3(info3, group_sids, num_group_sids);
		if (!NT_STATUS_IS_OK(status)) {
			TALLOC_FREE(info3);
			return status;
		}
	}

	/* We don't need sids and gids after the conversion */
	TALLOC_FREE(group_sids);
	TALLOC_FREE(gids);
	num_group_sids = 0;

	/* FIXME: should we add other flags ? */
	info3->base.user_flags = NETLOGON_EXTRA_SIDS;

	if (login_server) {
		info3->base.logon_server.string = talloc_strdup(info3, login_server);
		RET_NOMEM(info3->base.logon_server.string);
	}

	info3->base.acct_flags = pdb_get_acct_ctrl(samu);

	*_info3 = info3;
	return NT_STATUS_OK;
}
/*
  lookup a SID for 1 name
*/
static NTSTATUS dcesrv_lsa_lookup_name(struct tevent_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,
				       uint32_t *rid)
{
	int ret, i;
	uint32_t atype;
	struct ldb_message **res;
	const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
	const char *p;
	const char *domain;
	const char *username;
	struct ldb_dn *domain_dn;
	struct dom_sid *domain_sid;
	NTSTATUS status;

	p = strchr_m(name, '\\');
	if (p != NULL) {
		domain = talloc_strndup(mem_ctx, name, p-name);
		if (!domain) {
			return NT_STATUS_NO_MEMORY;
		}
		username = p + 1;
	} else if (strchr_m(name, '@')) {
		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;
		}
	} else {
		domain = NULL;
		username = name;
	}
	
	if (!domain) {
		/* Look up table of well known names */
		status = lookup_well_known_names(mem_ctx, NULL, username, authority_name, sid, rtype);
		if (NT_STATUS_IS_OK(status)) {
			dom_sid_split_rid(NULL, *sid, NULL, rid);
			return NT_STATUS_OK;
		}

		if (username == NULL) {
			*authority_name = NAME_BUILTIN;
			*sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN);
			if (*sid == NULL) {
				return NT_STATUS_NO_MEMORY;
			}
			*rtype = SID_NAME_DOMAIN;
			*rid = 0xFFFFFFFF;
			return NT_STATUS_OK;
		}

		if (strcasecmp_m(username, NAME_NT_AUTHORITY) == 0) { 
			*authority_name = NAME_NT_AUTHORITY;
			*sid =  dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
			if (*sid == NULL) {
				return NT_STATUS_NO_MEMORY;
			}
			*rtype = SID_NAME_DOMAIN;
			dom_sid_split_rid(NULL, *sid, NULL, rid);
			return NT_STATUS_OK;
		}
		if (strcasecmp_m(username, NAME_BUILTIN) == 0) { 
			*authority_name = NAME_BUILTIN;
			*sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN);
			if (*sid == NULL) {
				return NT_STATUS_NO_MEMORY;
			}
			*rtype = SID_NAME_DOMAIN;
			*rid = 0xFFFFFFFF;
			return NT_STATUS_OK;
		}
		if (strcasecmp_m(username, state->domain_dns) == 0) { 
			*authority_name = talloc_strdup(mem_ctx,
							state->domain_name);
			if (*authority_name == NULL) {
				return NT_STATUS_NO_MEMORY;
			}
			*sid =  dom_sid_dup(mem_ctx, state->domain_sid);
			if (*sid == NULL) {
				return NT_STATUS_NO_MEMORY;
			}
			*rtype = SID_NAME_DOMAIN;
			*rid = 0xFFFFFFFF;
			return NT_STATUS_OK;
		}
		if (strcasecmp_m(username, state->domain_name) == 0) { 
			*authority_name = talloc_strdup(mem_ctx,
							state->domain_name);
			if (*authority_name == NULL) {
				return NT_STATUS_NO_MEMORY;
			}
			*sid =  dom_sid_dup(mem_ctx, state->domain_sid);
			if (*sid == NULL) {
				return NT_STATUS_NO_MEMORY;
			}
			*rtype = SID_NAME_DOMAIN;
			*rid = 0xFFFFFFFF;
			return NT_STATUS_OK;
		}

		/* Perhaps this is a well known user? */
		name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_NT_AUTHORITY, username);
		if (!name) {
			return NT_STATUS_NO_MEMORY;
		}
		status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid);
		if (NT_STATUS_IS_OK(status)) {
			return status;
		}

		/* Perhaps this is a BUILTIN user? */
		name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_BUILTIN, username);
		if (!name) {
			return NT_STATUS_NO_MEMORY;
		}
		status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid);
		if (NT_STATUS_IS_OK(status)) {
			return status;
		}

		/* OK, I give up - perhaps we need to assume the user is in our domain? */
		name = talloc_asprintf(mem_ctx, "%s\\%s", state->domain_name, username);
		if (!name) {
			return NT_STATUS_NO_MEMORY;
		}
		status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid);
		if (NT_STATUS_IS_OK(status)) {
			return status;
		}

		return STATUS_SOME_UNMAPPED;
	} else if (strcasecmp_m(domain, NAME_NT_AUTHORITY) == 0) {
		if (!*username) {
			*authority_name = NAME_NT_AUTHORITY;
			*sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
			if (*sid == NULL) {
				return NT_STATUS_NO_MEMORY;
			}
			*rtype = SID_NAME_DOMAIN;
			dom_sid_split_rid(NULL, *sid, NULL, rid);
			return NT_STATUS_OK;
		}

		/* Look up table of well known names */
		status = lookup_well_known_names(mem_ctx, domain, username, authority_name, 
						 sid, rtype);
		if (NT_STATUS_IS_OK(status)) {
			dom_sid_split_rid(NULL, *sid, NULL, rid);
		}
		return status;
	} else if (strcasecmp_m(domain, NAME_BUILTIN) == 0) {
		*authority_name = NAME_BUILTIN;
		domain_dn = state->builtin_dn;
	} else if (strcasecmp_m(domain, state->domain_dns) == 0) { 
		*authority_name = talloc_strdup(mem_ctx,
						state->domain_name);
		if (*authority_name == NULL) {
			return NT_STATUS_NO_MEMORY;
		}
		domain_dn = state->domain_dn;
	} else if (strcasecmp_m(domain, state->domain_name) == 0) { 
		*authority_name = talloc_strdup(mem_ctx,
						state->domain_name);
		if (*authority_name == NULL) {
			return NT_STATUS_NO_MEMORY;
		}
		domain_dn = state->domain_dn;
	} else {
		/* Not local, need to ask winbind in future */
		return STATUS_SOME_UNMAPPED;
	}

	ret = gendb_search_dn(state->sam_ldb, mem_ctx, domain_dn, &res, attrs);
	if (ret != 1) {
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}
	domain_sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
	if (domain_sid == NULL) {
		return NT_STATUS_INVALID_SID;
	}

	if (!*username) {
		*sid = domain_sid;
		*rtype = SID_NAME_DOMAIN;
		*rid = 0xFFFFFFFF;
		return NT_STATUS_OK;
	}
	
	ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs, 
			   "(&(sAMAccountName=%s)(objectSid=*))", 
			   ldb_binary_encode_string(mem_ctx, username));
	if (ret < 0) {
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	for (i=0; i < ret; i++) {
		*sid = samdb_result_dom_sid(mem_ctx, res[i], "objectSid");
		if (*sid == NULL) {
			return NT_STATUS_INVALID_SID;
		}

		/* Check that this is in the domain */
		if (!dom_sid_in_domain(domain_sid, *sid)) {
			continue;
		}

		atype = ldb_msg_find_attr_as_uint(res[i], "sAMAccountType", 0);
			
		*rtype = ds_atype_map(atype);
		if (*rtype == SID_NAME_UNKNOWN) {
			return STATUS_SOME_UNMAPPED;
		}

		dom_sid_split_rid(NULL, *sid, NULL, rid);
		return NT_STATUS_OK;
	}

	/* need to check for an allocated sid */

	return NT_STATUS_INVALID_SID;
}
Beispiel #25
0
/*
  save the acl for a file into system.nfs4acl
*/
static NTSTATUS pvfs_acl_save_nfs4(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
				   struct security_descriptor *sd)
{
	NTSTATUS status;
	void *privs;
	struct nfs4acl acl;
	int i;
	TALLOC_CTX *tmp_ctx;
	struct id_map *ids;

	tmp_ctx = talloc_new(pvfs);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	acl.a_version = 0;
	acl.a_flags   = sd->type;
	acl.a_count   = sd->dacl?sd->dacl->num_aces:0;
	acl.a_owner_mask = 0;
	acl.a_group_mask = 0;
	acl.a_other_mask = 0;

	acl.ace = talloc_array(tmp_ctx, struct nfs4ace, acl.a_count);
	if (!acl.ace) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	ids = talloc_array(tmp_ctx, struct id_map, acl.a_count);
	if (ids == NULL) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	for (i=0;i<acl.a_count;i++) {
		struct security_ace *ace = &sd->dacl->aces[i];
		ZERO_STRUCT(ids[i].xid);
		ids[i].sid = dom_sid_dup(ids, &ace->trustee);
		if (ids[i].sid == NULL) {
			talloc_free(tmp_ctx);
			return NT_STATUS_NO_MEMORY;
		}
		ids[i].status = ID_UNKNOWN;
	}

	status = wbc_sids_to_xids(ids, acl.a_count);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(tmp_ctx);
		return status;
	}

	for (i=0;i<acl.a_count;i++) {
		struct nfs4ace *a = &acl.ace[i];
		struct security_ace *ace = &sd->dacl->aces[i];
		a->e_type  = ace->type;
		a->e_flags = ace->flags;
		a->e_mask  = ace->access_mask;
		if (ids[i].xid.type != ID_TYPE_UID) {
			a->e_flags |= ACE4_IDENTIFIER_GROUP;
		}
		a->e_id = ids[i].xid.id;
		a->e_who   = "";
	}

	privs = root_privileges();
	status = pvfs_xattr_ndr_save(pvfs, name->full_name, fd, 
				     NFS4ACL_XATTR_NAME, 
				     &acl, (void *) ndr_push_nfs4acl);
	talloc_free(privs);

	talloc_free(tmp_ctx);
	return status;
}
Beispiel #26
0
struct netr_SamInfo3 *wbcAuthUserInfo_to_netr_SamInfo3(TALLOC_CTX *mem_ctx,
					const struct wbcAuthUserInfo *info)
{
	struct netr_SamInfo3 *info3;
	struct dom_sid user_sid;
	struct dom_sid group_sid;
	struct dom_sid domain_sid;
	NTSTATUS status;
	bool ok;

	memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
	memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));

	info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
	if (!info3) return NULL;

	unix_to_nt_time(&info3->base.logon_time, info->logon_time);
	unix_to_nt_time(&info3->base.logoff_time, info->logoff_time);
	unix_to_nt_time(&info3->base.kickoff_time, info->kickoff_time);
	unix_to_nt_time(&info3->base.last_password_change, info->pass_last_set_time);
	unix_to_nt_time(&info3->base.allow_password_change,
			info->pass_can_change_time);
	unix_to_nt_time(&info3->base.force_password_change,
			info->pass_must_change_time);

	if (info->account_name) {
		info3->base.account_name.string	=
				talloc_strdup(info3, info->account_name);
		RET_NOMEM(info3->base.account_name.string);
	}
	if (info->full_name) {
		info3->base.full_name.string =
				talloc_strdup(info3, info->full_name);
		RET_NOMEM(info3->base.full_name.string);
	}
	if (info->logon_script) {
		info3->base.logon_script.string =
				talloc_strdup(info3, info->logon_script);
		RET_NOMEM(info3->base.logon_script.string);
	}
	if (info->profile_path) {
		info3->base.profile_path.string	=
				talloc_strdup(info3, info->profile_path);
		RET_NOMEM(info3->base.profile_path.string);
	}
	if (info->home_directory) {
		info3->base.home_directory.string =
				talloc_strdup(info3, info->home_directory);
		RET_NOMEM(info3->base.home_directory.string);
	}
	if (info->home_drive) {
		info3->base.home_drive.string =
				talloc_strdup(info3, info->home_drive);
		RET_NOMEM(info3->base.home_drive.string);
	}

	info3->base.logon_count	= info->logon_count;
	info3->base.bad_password_count = info->bad_password_count;

	sid_copy(&domain_sid, &user_sid);
	sid_split_rid(&domain_sid, &info3->base.rid);

	ok = sid_peek_check_rid(&domain_sid, &group_sid,
				&info3->base.primary_gid);
	if (!ok) {
		DEBUG(1, ("The primary group sid domain does not"
			  "match user sid domain for user: %s\n",
			  info->account_name));
		TALLOC_FREE(info3);
		return NULL;
	}

	status = wbcsids_to_samr_RidWithAttributeArray(info3,
						       &info3->base.groups,
						       &domain_sid,
						       &info->sids[1],
						       info->num_sids - 1);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(info3);
		return NULL;
	}

	status = wbcsids_to_netr_SidAttrArray(&domain_sid,
					      &info->sids[1],
					      info->num_sids - 1,
					      info3,
					      &info3->sids,
					      &info3->sidcount);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(info3);
		return NULL;
	}

	info3->base.user_flags = info->user_flags;
	memcpy(info3->base.key.key, info->user_session_key, 16);

	if (info->logon_server) {
		info3->base.logon_server.string =
				talloc_strdup(info3, info->logon_server);
		RET_NOMEM(info3->base.logon_server.string);
	}
	if (info->domain_name) {
		info3->base.logon_domain.string =
				talloc_strdup(info3, info->domain_name);
		RET_NOMEM(info3->base.logon_domain.string);
	}

	info3->base.domain_sid = dom_sid_dup(info3, &domain_sid);
	RET_NOMEM(info3->base.domain_sid);

	memcpy(info3->base.LMSessKey.key, info->lm_session_key, 8);
	info3->base.acct_flags = info->acct_flags;

	return info3;
}