Beispiel #1
0
static NTSTATUS get_system_info3(TALLOC_CTX *mem_ctx,
				 struct netr_SamInfo3 *info3)
{
	NTSTATUS status;
	struct dom_sid *system_sid;

	/* Set account name */
	init_lsa_String(&info3->base.account_name, "SYSTEM");

	/* Set domain name */
	init_lsa_StringLarge(&info3->base.logon_domain, "NT AUTHORITY");


	/* The SID set here will be overwirtten anyway, but try and make it SID_NT_SYSTEM anyway */
	/* Domain sid is NT_AUTHORITY */
	
	system_sid = dom_sid_parse_talloc(mem_ctx, SID_NT_SYSTEM);
	if (system_sid == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	
	status = dom_sid_split_rid(mem_ctx, system_sid, &info3->base.domain_sid, 
				   &info3->base.rid);
	TALLOC_FREE(system_sid);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}
	
	/* Primary gid is the same */
	info3->base.primary_gid = info3->base.rid;

	return NT_STATUS_OK;
}
Beispiel #2
0
static NTSTATUS auth_convert_user_info_dc_sambaseinfo(TALLOC_CTX *mem_ctx,
				const struct auth_user_info_dc *user_info_dc,
				struct netr_SamBaseInfo *sam)
{
	NTSTATUS status;
	const struct auth_user_info *info;

	ZERO_STRUCTP(sam);

	if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX) {
		status = dom_sid_split_rid(sam, &user_info_dc->sids[PRIMARY_USER_SID_INDEX],
					   &sam->domain_sid, &sam->rid);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}
	} else {
		return NT_STATUS_INVALID_PARAMETER;
	}

	if (user_info_dc->num_sids > PRIMARY_GROUP_SID_INDEX) {
		status = dom_sid_split_rid(NULL, &user_info_dc->sids[PRIMARY_GROUP_SID_INDEX],
					   NULL, &sam->primary_gid);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}
	} else {
		/* if we have to encode something like SYSTEM (with no
		 * second SID in the token) then this is the only
		 * choice */
		sam->primary_gid = sam->rid;
	}

	info = user_info_dc->info;

	sam->logon_time = info->last_logon;
	sam->logoff_time =  info->last_logoff;
	sam->kickoff_time = info->acct_expiry;
	sam->last_password_change = info->last_password_change;
	sam->allow_password_change = info->allow_password_change;
	sam->force_password_change = info->force_password_change;

#define _COPY_STRING_TALLOC(src_name, dst_name) do { \
	if (info->src_name != NULL) {\
		sam->dst_name.string = talloc_strdup(mem_ctx, info->src_name); \
		if (sam->dst_name.string == NULL) { \
			return NT_STATUS_NO_MEMORY; \
		} \
	} \
} while(0)
	_COPY_STRING_TALLOC(account_name, account_name);
	_COPY_STRING_TALLOC(full_name, full_name);
	_COPY_STRING_TALLOC(logon_script, logon_script);
	_COPY_STRING_TALLOC(profile_path, profile_path);
	_COPY_STRING_TALLOC(home_directory, home_directory);
	_COPY_STRING_TALLOC(home_drive, home_drive);
	_COPY_STRING_TALLOC(logon_server, logon_server);
	_COPY_STRING_TALLOC(domain_name, logon_domain);
#undef _COPY_STRING_TALLOC

	sam->logon_count = info->logon_count;
	sam->bad_password_count = info->bad_password_count;
	sam->groups.count = 0;
	sam->groups.rids = NULL;

	if (user_info_dc->num_sids > 2) {
		size_t i;
		sam->groups.rids = talloc_array(mem_ctx, struct samr_RidWithAttribute,
						user_info_dc->num_sids);

		if (sam->groups.rids == NULL)
			return NT_STATUS_NO_MEMORY;

		for (i=2; i<user_info_dc->num_sids; i++) {
			struct dom_sid *group_sid = &user_info_dc->sids[i];
			if (!dom_sid_in_domain(sam->domain_sid, group_sid)) {
				/* We handle this elsewhere */
				continue;
			}
			sam->groups.rids[sam->groups.count].rid =
				group_sid->sub_auths[group_sid->num_auths-1];

			sam->groups.rids[sam->groups.count].attributes =
				SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
			sam->groups.count += 1;
		}
	}
Beispiel #3
0
/*
  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);
            *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);
            *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);
            *rtype = SID_NAME_DOMAIN;
            *rid = 0xFFFFFFFF;
            return NT_STATUS_OK;
        }
        if (strcasecmp_m(username, state->domain_dns) == 0) {
            *authority_name = state->domain_name;
            *sid =  state->domain_sid;
            *rtype = SID_NAME_DOMAIN;
            *rid = 0xFFFFFFFF;
            return NT_STATUS_OK;
        }
        if (strcasecmp_m(username, state->domain_name) == 0) {
            *authority_name = state->domain_name;
            *sid =  state->domain_sid;
            *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);
            *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 = state->domain_name;
        domain_dn = state->domain_dn;
    } else if (strcasecmp_m(domain, state->domain_name) == 0) {
        *authority_name = state->domain_name;
        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) {
        domain_sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
        if (domain_sid == NULL) {
            return NT_STATUS_INVALID_SID;
        }
    } else {
        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 == -1) {
        return NT_STATUS_INVALID_SID;
    }

    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 = samdb_result_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 #4
0
_PUBLIC_ NTSTATUS authsam_make_user_info_dc(TALLOC_CTX *mem_ctx,
					   struct ldb_context *sam_ctx,
					   const char *netbios_name,
					   const char *domain_name,
					   struct ldb_dn *domain_dn, 
					   struct ldb_message *msg,
					   DATA_BLOB user_sess_key,
					   DATA_BLOB lm_sess_key,
					   struct auth_user_info_dc **_user_info_dc)
{
	NTSTATUS status;
	struct auth_user_info_dc *user_info_dc;
	struct auth_user_info *info;
	const char *str, *filter;
	/* SIDs for the account and his primary group */
	struct dom_sid *account_sid;
	const char *primary_group_string;
	const char *primary_group_dn;
	DATA_BLOB primary_group_blob;
	/* SID structures for the expanded group memberships */
	struct dom_sid *sids = NULL;
	unsigned int num_sids = 0, i;
	struct dom_sid *domain_sid;
	TALLOC_CTX *tmp_ctx;
	struct ldb_message_element *el;

	user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
	NT_STATUS_HAVE_NO_MEMORY(user_info_dc);

	tmp_ctx = talloc_new(user_info_dc);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc, user_info_dc);

	sids = talloc_array(user_info_dc, struct dom_sid, 2);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, user_info_dc);

	num_sids = 2;

	account_sid = samdb_result_dom_sid(user_info_dc, msg, "objectSid");
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(account_sid, user_info_dc);

	status = dom_sid_split_rid(tmp_ctx, account_sid, &domain_sid, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(user_info_dc);
		return status;
	}

	sids[PRIMARY_USER_SID_INDEX] = *account_sid;
	sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid;
	sid_append_rid(&sids[PRIMARY_GROUP_SID_INDEX], ldb_msg_find_attr_as_uint(msg, "primaryGroupID", ~0));

	/* Filter out builtin groups from this token.  We will search
	 * for builtin groups later, and not include them in the PAC
	 * on SamLogon validation info */
	filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(!(groupType:1.2.840.113556.1.4.803:=%u))(groupType:1.2.840.113556.1.4.803:=%u))", GROUP_TYPE_BUILTIN_LOCAL_GROUP, GROUP_TYPE_SECURITY_ENABLED);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(filter, user_info_dc);

	primary_group_string = dom_sid_string(tmp_ctx, &sids[PRIMARY_GROUP_SID_INDEX]);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_string, user_info_dc);

	primary_group_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", primary_group_string);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_dn, user_info_dc);

	primary_group_blob = data_blob_string_const(primary_group_dn);

	/* Expands the primary group - this function takes in
	 * memberOf-like values, so we fake one up with the
	 * <SID=S-...> format of DN and then let it expand
	 * them, as long as they meet the filter - so only
	 * domain groups, not builtin groups
	 *
	 * The primary group is still treated specially, so we set the
	 * 'only childs' flag to true
	 */
	status = dsdb_expand_nested_groups(sam_ctx, &primary_group_blob, true, filter,
					   user_info_dc, &sids, &num_sids);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(user_info_dc);
		return status;
	}

	/* Expands the additional groups */
	el = ldb_msg_find_element(msg, "memberOf");
	for (i = 0; el && i < el->num_values; i++) {
		/* This function takes in memberOf values and expands
		 * them, as long as they meet the filter - so only
		 * domain groups, not builtin groups */
		status = dsdb_expand_nested_groups(sam_ctx, &el->values[i], false, filter,
						   user_info_dc, &sids, &num_sids);
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(user_info_dc);
			return status;
		}
	}

	user_info_dc->sids = sids;
	user_info_dc->num_sids = num_sids;

	user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
	NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);

	info->account_name = talloc_steal(info,
		ldb_msg_find_attr_as_string(msg, "sAMAccountName", NULL));

	info->domain_name = talloc_strdup(info, domain_name);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->domain_name,
		user_info_dc);

	str = ldb_msg_find_attr_as_string(msg, "displayName", "");
	info->full_name = talloc_strdup(info, str);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->full_name, user_info_dc);

	str = ldb_msg_find_attr_as_string(msg, "scriptPath", "");
	info->logon_script = talloc_strdup(info, str);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_script,
		user_info_dc);

	str = ldb_msg_find_attr_as_string(msg, "profilePath", "");
	info->profile_path = talloc_strdup(info, str);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->profile_path,
		user_info_dc);

	str = ldb_msg_find_attr_as_string(msg, "homeDirectory", "");
	info->home_directory = talloc_strdup(info, str);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_directory,
		user_info_dc);

	str = ldb_msg_find_attr_as_string(msg, "homeDrive", "");
	info->home_drive = talloc_strdup(info, str);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_drive, user_info_dc);

	info->logon_server = talloc_strdup(info, netbios_name);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_server,
		user_info_dc);

	info->last_logon = samdb_result_nttime(msg, "lastLogon", 0);
	info->last_logoff = samdb_result_last_logoff(msg);
	info->acct_expiry = samdb_result_account_expires(msg);
	info->last_password_change = samdb_result_nttime(msg,
		"pwdLastSet", 0);
	info->allow_password_change
		= samdb_result_allow_password_change(sam_ctx, mem_ctx, 
			domain_dn, msg, "pwdLastSet");
	info->force_password_change
		= samdb_result_force_password_change(sam_ctx, mem_ctx,
			domain_dn, msg);
	info->logon_count = ldb_msg_find_attr_as_uint(msg, "logonCount", 0);
	info->bad_password_count = ldb_msg_find_attr_as_uint(msg, "badPwdCount",
		0);

	info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx,
							  msg, domain_dn);

	user_info_dc->user_session_key = data_blob_talloc(user_info_dc,
							 user_sess_key.data,
							 user_sess_key.length);
	if (user_sess_key.data) {
		NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->user_session_key.data,
						  user_info_dc);
	}
	user_info_dc->lm_session_key = data_blob_talloc(user_info_dc,
						       lm_sess_key.data,
						       lm_sess_key.length);
	if (lm_sess_key.data) {
		NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->lm_session_key.data,
						  user_info_dc);
	}

	if (info->acct_flags & ACB_SVRTRUST) {
		/* the SID_NT_ENTERPRISE_DCS SID gets added into the
		   PAC */
		user_info_dc->sids = talloc_realloc(user_info_dc,
						   user_info_dc->sids,
						   struct dom_sid,
						   user_info_dc->num_sids+1);
		NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc);
		user_info_dc->sids[user_info_dc->num_sids] = global_sid_Enterprise_DCs;
		user_info_dc->num_sids++;
	}
Beispiel #5
0
/*
  construct the token groups for SAM objects from a message
*/
static int construct_token_groups(struct ldb_module *module,
				  struct ldb_message *msg, enum ldb_scope scope,
				  struct ldb_request *parent)
{
	struct ldb_context *ldb = ldb_module_get_ctx(module);;
	TALLOC_CTX *tmp_ctx = talloc_new(msg);
	unsigned int i;
	int ret;
	const char *filter;

	NTSTATUS status;

	struct dom_sid *primary_group_sid;
	const char *primary_group_string;
	const char *primary_group_dn;
	DATA_BLOB primary_group_blob;

	struct dom_sid *account_sid;
	const char *account_sid_string;
	const char *account_sid_dn;
	DATA_BLOB account_sid_blob;
	struct dom_sid *groupSIDs = NULL;
	unsigned int num_groupSIDs = 0;

	struct dom_sid *domain_sid;

	if (scope != LDB_SCOPE_BASE) {
		ldb_set_errstring(ldb, "Cannot provide tokenGroups attribute, this is not a BASE search");
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* If it's not a user, it won't have a primaryGroupID */
	if (ldb_msg_find_element(msg, "primaryGroupID") == NULL) {
		talloc_free(tmp_ctx);
		return LDB_SUCCESS;
	}

	/* Ensure it has an objectSID too */
	account_sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
	if (account_sid == NULL) {
		talloc_free(tmp_ctx);
		return LDB_SUCCESS;
	}

	status = dom_sid_split_rid(tmp_ctx, account_sid, &domain_sid, NULL);
	if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
		talloc_free(tmp_ctx);
		return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
	} else if (!NT_STATUS_IS_OK(status)) {
		talloc_free(tmp_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	primary_group_sid = dom_sid_add_rid(tmp_ctx,
					    domain_sid,
					    ldb_msg_find_attr_as_uint(msg, "primaryGroupID", ~0));
	if (!primary_group_sid) {
		talloc_free(tmp_ctx);
		return ldb_oom(ldb);
	}

	/* only return security groups */
	filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
				 GROUP_TYPE_SECURITY_ENABLED);
	if (!filter) {
		talloc_free(tmp_ctx);
		return ldb_oom(ldb);
	}

	primary_group_string = dom_sid_string(tmp_ctx, primary_group_sid);
	if (!primary_group_string) {
		talloc_free(tmp_ctx);
		return ldb_oom(ldb);
	}

	primary_group_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", primary_group_string);
	if (!primary_group_dn) {
		talloc_free(tmp_ctx);
		return ldb_oom(ldb);
	}

	primary_group_blob = data_blob_string_const(primary_group_dn);

	account_sid_string = dom_sid_string(tmp_ctx, account_sid);
	if (!account_sid_string) {
		talloc_free(tmp_ctx);
		return ldb_oom(ldb);
	}

	account_sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", account_sid_string);
	if (!account_sid_dn) {
		talloc_free(tmp_ctx);
		return ldb_oom(ldb);
	}

	account_sid_blob = data_blob_string_const(account_sid_dn);

	status = dsdb_expand_nested_groups(ldb, &account_sid_blob,
					   true, /* We don't want to add the object's SID itself,
						    it's not returend in this attribute */
					   filter,
					   tmp_ctx, &groupSIDs, &num_groupSIDs);

	if (!NT_STATUS_IS_OK(status)) {
		ldb_asprintf_errstring(ldb, "Failed to construct tokenGroups: expanding groups of SID %s failed: %s",
				       account_sid_string, nt_errstr(status));
		talloc_free(tmp_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* Expands the primary group - this function takes in
	 * memberOf-like values, so we fake one up with the
	 * <SID=S-...> format of DN and then let it expand
	 * them, as long as they meet the filter - so only
	 * domain groups, not builtin groups
	 */
	status = dsdb_expand_nested_groups(ldb, &primary_group_blob, false, filter,
					   tmp_ctx, &groupSIDs, &num_groupSIDs);
	if (!NT_STATUS_IS_OK(status)) {
		ldb_asprintf_errstring(ldb, "Failed to construct tokenGroups: expanding groups of SID %s failed: %s",
				       account_sid_string, nt_errstr(status));
		talloc_free(tmp_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	for (i=0; i < num_groupSIDs; i++) {
		ret = samdb_msg_add_dom_sid(ldb, msg, msg, "tokenGroups", &groupSIDs[i]);
		if (ret) {
			talloc_free(tmp_ctx);
			return ret;
		}
	}

	return LDB_SUCCESS;
}
Beispiel #6
0
static NTSTATUS get_info3_from_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
					       struct smb_iconv_convenience *ic,
					       struct wbcAuthUserInfo *info,
					       struct netr_SamInfo3 *info3)
{
	int i, j;
	struct samr_RidWithAttribute *rids = NULL;

	info3->base.last_logon = info->logon_time;
	info3->base.last_logoff = info->logoff_time;
	info3->base.acct_expiry = info->kickoff_time;
	info3->base.last_password_change = info->pass_last_set_time;
	info3->base.allow_password_change = info->pass_can_change_time;
	info3->base.force_password_change = info->pass_must_change_time;

	info3->base.account_name.string = talloc_strdup(mem_ctx,
							info->account_name);
	info3->base.full_name.string = talloc_strdup(mem_ctx,
						     info->full_name);
	info3->base.logon_script.string = talloc_strdup(mem_ctx,
							info->logon_script);
	info3->base.profile_path.string = talloc_strdup(mem_ctx,
							info->profile_path);
	info3->base.home_directory.string = talloc_strdup(mem_ctx,
							  info->home_directory);
	info3->base.home_drive.string = talloc_strdup(mem_ctx,
						      info->home_drive);
	info3->base.logon_server.string = talloc_strdup(mem_ctx,
							info->logon_server);
	info3->base.domain.string = talloc_strdup(mem_ctx,
						  info->domain_name);

	info3->base.logon_count = info->logon_count;
	info3->base.bad_password_count = info->bad_password_count;
	info3->base.user_flags = info->user_flags;
	memcpy(info3->base.key.key, info->user_session_key,
	       sizeof(info3->base.key.key));
	memcpy(info3->base.LMSessKey.key, info->lm_session_key,
	       sizeof(info3->base.LMSessKey.key));
	info3->base.acct_flags = info->acct_flags;
	memset(info3->base.unknown, 0, sizeof(info3->base.unknown));

	if (info->num_sids < 2) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	dom_sid_split_rid(mem_ctx, (struct dom_sid2 *) &info->sids[0].sid,
			  &info3->base.domain_sid,
			  &info3->base.rid);
	dom_sid_split_rid(mem_ctx, (struct dom_sid2 *) &info->sids[1].sid, NULL,
			  &info3->base.primary_gid);

	/* We already handled the first two, now take care of the rest */
	info3->base.groups.count = info->num_sids - 2;

	rids = talloc_array(mem_ctx, struct samr_RidWithAttribute,
			    info3->base.groups.count);
	NT_STATUS_HAVE_NO_MEMORY(rids);

	for (i = 2, j = 0; i < info->num_sids; ++i, ++j) {
		rids[j].attributes = info->sids[i].attributes;
		dom_sid_split_rid(mem_ctx,
				  (struct dom_sid2 *) &info->sids[i].sid,
				  NULL, &rids[j].rid);
	}
	info3->base.groups.rids = rids;

	return NT_STATUS_OK;
}