예제 #1
0
static NTSTATUS check_samba4_security(const struct auth_context *auth_context,
				      void *my_private_data,
				      TALLOC_CTX *mem_ctx,
				      const struct auth_usersupplied_info *user_info,
				      struct auth_serversupplied_info **server_info)
{
	TALLOC_CTX *frame = talloc_stackframe();
	struct netr_SamInfo3 *info3 = NULL;
	NTSTATUS nt_status;
	struct auth_user_info_dc *user_info_dc;
	struct auth4_context *auth4_context;
	struct loadparm_context *lp_ctx;

	lp_ctx = loadparm_init_s3(frame, loadparm_s3_context());
	if (lp_ctx == NULL) {
		DEBUG(10, ("loadparm_init_s3 failed\n"));
		talloc_free(frame);
		return NT_STATUS_INVALID_SERVER_STATE;
	}

	/* We create a private tevent context here to avoid nested loops in
	 * the s3 one, as that may not be expected */
	nt_status = auth_context_create(mem_ctx,
					s4_event_context_init(frame), NULL, 
					lp_ctx,
					&auth4_context);
	NT_STATUS_NOT_OK_RETURN(nt_status);
		
	nt_status = auth_context_set_challenge(auth4_context, auth_context->challenge.data, "auth_samba4");
	NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, auth4_context);

	nt_status = auth_check_password(auth4_context, auth4_context, user_info, &user_info_dc);
	NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, auth4_context);
	
	nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx,
						       user_info_dc,
						       &info3);
	if (NT_STATUS_IS_OK(nt_status)) {
		/* We need the strings from the server_info to be valid as long as the info3 is around */
		talloc_steal(info3, user_info_dc);
	}
	talloc_free(auth4_context);

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

	nt_status = make_server_info_info3(mem_ctx, user_info->client.account_name,
					   user_info->mapped.domain_name, server_info,
					info3);
	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(10, ("make_server_info_info3 failed: %s\n",
			   nt_errstr(nt_status)));
		TALLOC_FREE(frame);
		return nt_status;
	}

	nt_status = NT_STATUS_OK;

 done:
	TALLOC_FREE(frame);
	return nt_status;
}
예제 #2
0
파일: session.c 프로젝트: rti7743/samba
_PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
        struct loadparm_context *lp_ctx, /* Optional, if you don't want privilages */
        struct ldb_context *sam_ctx, /* Optional, if you don't want local groups */
        struct auth_user_info_dc *user_info_dc,
        uint32_t session_info_flags,
        struct auth_session_info **_session_info)
{
    struct auth_session_info *session_info;
    NTSTATUS nt_status;
    unsigned int i, num_sids = 0;

    const char *filter;

    struct dom_sid *sids = NULL;
    const struct dom_sid *anonymous_sid, *system_sid;

    TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

    session_info = talloc_zero(tmp_ctx, struct auth_session_info);
    NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info, tmp_ctx);

    session_info->info = talloc_reference(session_info, user_info_dc->info);

    session_info->torture = talloc_zero(session_info, struct auth_user_info_torture);
    NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture, tmp_ctx);
    session_info->torture->num_dc_sids = user_info_dc->num_sids;
    session_info->torture->dc_sids = talloc_reference(session_info, user_info_dc->sids);
    NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture->dc_sids, tmp_ctx);

    /* unless set otherwise, the session key is the user session
     * key from the auth subsystem */
    session_info->session_key = data_blob_talloc(session_info, user_info_dc->user_session_key.data, user_info_dc->user_session_key.length);
    if (!session_info->session_key.data && session_info->session_key.length) {
        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->session_key.data, tmp_ctx);
    }

    anonymous_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_ANONYMOUS);
    NT_STATUS_HAVE_NO_MEMORY_AND_FREE(anonymous_sid, tmp_ctx);

    system_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_SYSTEM);
    NT_STATUS_HAVE_NO_MEMORY_AND_FREE(system_sid, tmp_ctx);

    sids = talloc_array(tmp_ctx, struct dom_sid, user_info_dc->num_sids);
    NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, tmp_ctx);
    if (!sids) {
        talloc_free(tmp_ctx);
        return NT_STATUS_NO_MEMORY;
    }

    num_sids = user_info_dc->num_sids;

    for (i=0; i < user_info_dc->num_sids; i++) {
        sids[i] = user_info_dc->sids[i];
    }

    if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(anonymous_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) {
        /* Don't expand nested groups of system, anonymous etc*/
    } else if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(system_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) {
        /* Don't expand nested groups of system, anonymous etc*/
    } else if (sam_ctx) {
        filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
                                 GROUP_TYPE_BUILTIN_LOCAL_GROUP);

        /* Search for each group in the token */
        for (i = 0; i < user_info_dc->num_sids; i++) {
            char *sid_string;
            const char *sid_dn;
            DATA_BLOB sid_blob;

            sid_string = dom_sid_string(tmp_ctx,
                                        &user_info_dc->sids[i]);
            NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, user_info_dc);

            sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
            talloc_free(sid_string);
            NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, user_info_dc);
            sid_blob = data_blob_string_const(sid_dn);

            /* This function takes in memberOf values and expands
             * them, as long as they meet the filter - so only
             * builtin groups
             *
             * We already have the SID in the token, so set
             * 'only childs' flag to true */
            nt_status = dsdb_expand_nested_groups(sam_ctx, &sid_blob, true, filter,
                                                  tmp_ctx, &sids, &num_sids);
            if (!NT_STATUS_IS_OK(nt_status)) {
                talloc_free(tmp_ctx);
                return nt_status;
            }
        }
    }

    nt_status = security_token_create(session_info,
                                      lp_ctx,
                                      num_sids,
                                      sids,
                                      session_info_flags,
                                      &session_info->security_token);
    NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx);

    session_info->credentials = NULL;

    talloc_steal(mem_ctx, session_info);
    *_session_info = session_info;
    talloc_free(tmp_ctx);
    return NT_STATUS_OK;
}