Example #1
0
/* Get some basic (and authorization) information about the user on
 * this session.  This uses either the PAC (if present) or a local
 * database lookup */
static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_security,
					   TALLOC_CTX *mem_ctx,
					   struct auth_session_info **_session_info) 
{
	NTSTATUS nt_status;
	TALLOC_CTX *tmp_ctx;
	struct gensec_gssapi_state *gensec_gssapi_state
		= talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
	struct auth_session_info *session_info = NULL;
	OM_uint32 maj_stat, min_stat;
	DATA_BLOB pac_blob, *pac_blob_ptr = NULL;

	gss_buffer_desc name_token;
	char *principal_string;
	
	tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context");
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	maj_stat = gss_display_name (&min_stat,
				     gensec_gssapi_state->client_name,
				     &name_token,
				     NULL);
	if (GSS_ERROR(maj_stat)) {
		DEBUG(1, ("GSS display_name failed: %s\n",
			  gssapi_error_string(tmp_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
		talloc_free(tmp_ctx);
		return NT_STATUS_FOOBAR;
	}

	principal_string = talloc_strndup(tmp_ctx,
					  (const char *)name_token.value,
					  name_token.length);

	gss_release_buffer(&min_stat, &name_token);

	if (!principal_string) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	nt_status = gssapi_obtain_pac_blob(tmp_ctx,  gensec_gssapi_state->gssapi_context,
					   gensec_gssapi_state->client_name,
					   &pac_blob);
	
	/* IF we have the PAC - otherwise we need to get this
	 * data from elsewere - local ldb, or (TODO) lookup of some
	 * kind... 
	 */
	if (NT_STATUS_IS_OK(nt_status)) {
		pac_blob_ptr = &pac_blob;
	}
	nt_status = gensec_generate_session_info_pac(tmp_ctx,
						     gensec_security,
						     gensec_gssapi_state->smb_krb5_context,
						     pac_blob_ptr, principal_string,
						     gensec_get_remote_address(gensec_security),
						     &session_info);
	if (!NT_STATUS_IS_OK(nt_status)) {
		talloc_free(tmp_ctx);
		return nt_status;
	}

	nt_status = gensec_gssapi_session_key(gensec_security, session_info, &session_info->session_key);
	if (!NT_STATUS_IS_OK(nt_status)) {
		talloc_free(tmp_ctx);
		return nt_status;
	}

	if (gensec_gssapi_state->gss_got_flags & GSS_C_DELEG_FLAG &&
	    gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) {
		krb5_error_code ret;
		const char *error_string;

		DEBUG(10, ("gensec_gssapi: delegated credentials supplied by client\n"));
		session_info->credentials = cli_credentials_init(session_info);
		if (!session_info->credentials) {
			talloc_free(tmp_ctx);
			return NT_STATUS_NO_MEMORY;
		}

		cli_credentials_set_conf(session_info->credentials, gensec_security->settings->lp_ctx);
		/* Just so we don't segfault trying to get at a username */
		cli_credentials_set_anonymous(session_info->credentials);
		
		ret = cli_credentials_set_client_gss_creds(session_info->credentials, 
							   gensec_security->settings->lp_ctx,
							   gensec_gssapi_state->delegated_cred_handle,
							   CRED_SPECIFIED, &error_string);
		if (ret) {
			talloc_free(tmp_ctx);
			DEBUG(2,("Failed to get gss creds: %s\n", error_string));
			return NT_STATUS_NO_MEMORY;
		}
		
		/* This credential handle isn't useful for password authentication, so ensure nobody tries to do that */
		cli_credentials_set_kerberos_state(session_info->credentials, CRED_MUST_USE_KERBEROS);

		/* It has been taken from this place... */
		gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
	} else {
		DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n"));
	}

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

	return NT_STATUS_OK;
}
Example #2
0
static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security,
        TALLOC_CTX *mem_ctx,
        struct auth_session_info **_session_info)
{
    NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
    struct gensec_krb5_state *gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
    krb5_context context = gensec_krb5_state->smb_krb5_context->krb5_context;
    struct auth_session_info *session_info = NULL;

    krb5_principal client_principal;
    char *principal_string;

    DATA_BLOB pac_blob, *pac_blob_ptr = NULL;
    krb5_data pac_data;

    krb5_error_code ret;

    TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    if (!tmp_ctx) {
        return NT_STATUS_NO_MEMORY;
    }

    ret = krb5_ticket_get_client(context, gensec_krb5_state->ticket, &client_principal);
    if (ret) {
        DEBUG(5, ("krb5_ticket_get_client failed to get cleint principal: %s\n",
                  smb_get_krb5_error_message(context,
                                             ret, tmp_ctx)));
        talloc_free(tmp_ctx);
        return NT_STATUS_NO_MEMORY;
    }

    ret = krb5_unparse_name(gensec_krb5_state->smb_krb5_context->krb5_context,
                            client_principal, &principal_string);
    if (ret) {
        DEBUG(1, ("Unable to parse client principal: %s\n",
                  smb_get_krb5_error_message(context,
                                             ret, tmp_ctx)));
        krb5_free_principal(context, client_principal);
        talloc_free(tmp_ctx);
        return NT_STATUS_NO_MEMORY;
    }

    ret = krb5_ticket_get_authorization_data_type(context, gensec_krb5_state->ticket,
            KRB5_AUTHDATA_WIN2K_PAC,
            &pac_data);

    if (ret) {
        /* NO pac */
        DEBUG(5, ("krb5_ticket_get_authorization_data_type failed to find PAC: %s\n",
                  smb_get_krb5_error_message(context,
                                             ret, tmp_ctx)));
    } else {
        /* Found pac */
        pac_blob = data_blob_talloc(tmp_ctx, pac_data.data, pac_data.length);
        if (!pac_blob.data) {
            free(principal_string);
            krb5_free_principal(context, client_principal);
            talloc_free(tmp_ctx);
            return NT_STATUS_NO_MEMORY;
        }

        /* decode and verify the pac */
        nt_status = kerberos_decode_pac(gensec_krb5_state,
                                        pac_blob,
                                        gensec_krb5_state->smb_krb5_context->krb5_context,
                                        NULL, gensec_krb5_state->keyblock,
                                        client_principal,
                                        gensec_krb5_state->ticket->ticket.authtime, NULL);

        if (!NT_STATUS_IS_OK(nt_status)) {
            free(principal_string);
            krb5_free_principal(context, client_principal);
            talloc_free(tmp_ctx);
            return nt_status;
        }

        pac_blob_ptr = &pac_blob;
    }

    nt_status = gensec_generate_session_info_pac(tmp_ctx,
                gensec_security,
                gensec_krb5_state->smb_krb5_context,
                pac_blob_ptr, principal_string,
                gensec_get_remote_address(gensec_security),
                &session_info);

    free(principal_string);
    krb5_free_principal(context, client_principal);

    if (!NT_STATUS_IS_OK(nt_status)) {
        talloc_free(tmp_ctx);
        return nt_status;
    }

    nt_status = gensec_krb5_session_key(gensec_security, session_info, &session_info->session_key);

    if (!NT_STATUS_IS_OK(nt_status)) {
        talloc_free(tmp_ctx);
        return nt_status;
    }

    *_session_info = talloc_steal(mem_ctx, session_info);

    talloc_free(tmp_ctx);
    return NT_STATUS_OK;
}