sesman: Remove unused authentication methods
The Kerberos module and pam_userpass modules are now unused: 1) On all supported systems, PAM provides a far superior way to integrate Kerberos support. 2) The pam_userpass module (https://github.com/openwall/pam_userpass) (which is a lovely idea) is no longer maintained.
This commit is contained in:
+1
-23
@@ -95,18 +95,10 @@ AC_ARG_ENABLE(ipv6, AS_HELP_STRING([--enable-ipv6],
|
|||||||
AC_ARG_ENABLE(ipv6only, AS_HELP_STRING([--enable-ipv6only],
|
AC_ARG_ENABLE(ipv6only, AS_HELP_STRING([--enable-ipv6only],
|
||||||
[Build IPv6-only (default: no)]),
|
[Build IPv6-only (default: no)]),
|
||||||
[], [enable_ipv6only=no])
|
[], [enable_ipv6only=no])
|
||||||
AC_ARG_ENABLE(kerberos, AS_HELP_STRING([--enable-kerberos],
|
|
||||||
[Build kerberos support (prefer --enable-pam if available) (default: no)]),
|
|
||||||
[], [enable_kerberos=no])
|
|
||||||
AM_CONDITIONAL(SESMAN_KERBEROS, [test x$enable_kerberos = xyes])
|
|
||||||
AC_ARG_ENABLE(bsd, AS_HELP_STRING([--enable-bsd],
|
AC_ARG_ENABLE(bsd, AS_HELP_STRING([--enable-bsd],
|
||||||
[Build BSD auth support (default: no)]),
|
[Build BSD auth support (default: no)]),
|
||||||
[], [enable_bsd=no])
|
[], [enable_bsd=no])
|
||||||
AM_CONDITIONAL(SESMAN_BSD, [test x$enable_bsd = xyes])
|
AM_CONDITIONAL(SESMAN_BSD, [test x$enable_bsd = xyes])
|
||||||
AC_ARG_ENABLE(pamuserpass, AS_HELP_STRING([--enable-pamuserpass],
|
|
||||||
[Build PAM userpass support (default: no)]),
|
|
||||||
[], [enable_pamuserpass=no])
|
|
||||||
AM_CONDITIONAL(SESMAN_PAMUSERPASS, [test x$enable_pamuserpass = xyes])
|
|
||||||
AC_ARG_ENABLE(pam-config, AS_HELP_STRING([--enable-pam-config=CONF],
|
AC_ARG_ENABLE(pam-config, AS_HELP_STRING([--enable-pam-config=CONF],
|
||||||
[Select PAM config to install: arch, debian, redhat, suse, freebsd, macos, unix
|
[Select PAM config to install: arch, debian, redhat, suse, freebsd, macos, unix
|
||||||
(default: autodetect)]))
|
(default: autodetect)]))
|
||||||
@@ -388,24 +380,10 @@ then
|
|||||||
AUTHMOD_OBJ=verify_user_bsd.lo
|
AUTHMOD_OBJ=verify_user_bsd.lo
|
||||||
AUTHMOD_LIB=
|
AUTHMOD_LIB=
|
||||||
fi
|
fi
|
||||||
if test x$enable_kerberos = xyes
|
|
||||||
then
|
|
||||||
auth_cnt=`expr $auth_cnt + 1`
|
|
||||||
auth_mech="Kerberos"
|
|
||||||
AUTHMOD_OBJ=verify_user_kerberos.lo
|
|
||||||
AUTHMOD_LIB=-lkrb5
|
|
||||||
fi
|
|
||||||
if test x$enable_pamuserpass = xyes
|
|
||||||
then
|
|
||||||
auth_cnt=`expr $auth_cnt + 1`
|
|
||||||
auth_mech="PAM userpass"
|
|
||||||
AUTHMOD_OBJ=verify_user_pam_userpass.lo
|
|
||||||
AUTHMOD_LIB="-lpam -lpam_userpass"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test $auth_cnt -gt 1
|
if test $auth_cnt -gt 1
|
||||||
then
|
then
|
||||||
AC_MSG_ERROR([--enable-pam, --enable-bsd, --enable-pamuserpass and --enable-kerberos are mutually exclusive])
|
AC_MSG_ERROR([--enable-pam and --enable-bsd are mutually exclusive])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_SUBST([AUTHMOD_OBJ])
|
AC_SUBST([AUTHMOD_OBJ])
|
||||||
|
|||||||
@@ -15,16 +15,8 @@ CLEANFILES = xrdp-sesman
|
|||||||
if SESMAN_NOPAM
|
if SESMAN_NOPAM
|
||||||
PAMFILE =
|
PAMFILE =
|
||||||
else
|
else
|
||||||
if SESMAN_PAMUSERPASS
|
|
||||||
PAMFILE =
|
|
||||||
else
|
|
||||||
if SESMAN_KERBEROS
|
|
||||||
PAMFILE =
|
|
||||||
else
|
|
||||||
PAMFILE = xrdp-sesman
|
PAMFILE = xrdp-sesman
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
pamddir = $(pamconfdir)
|
pamddir = $(pamconfdir)
|
||||||
|
|
||||||
|
|||||||
@@ -45,9 +45,7 @@ module_LTLIBRARIES = \
|
|||||||
EXTRA_libsesman_la_SOURCES = \
|
EXTRA_libsesman_la_SOURCES = \
|
||||||
verify_user.c \
|
verify_user.c \
|
||||||
verify_user_bsd.c \
|
verify_user_bsd.c \
|
||||||
verify_user_kerberos.c \
|
verify_user_pam.c
|
||||||
verify_user_pam.c \
|
|
||||||
verify_user_pam_userpass.c
|
|
||||||
|
|
||||||
# Make sure the right authentication module is pulled in
|
# Make sure the right authentication module is pulled in
|
||||||
libsesman_la_DEPENDENCIES = $(AUTHMOD_OBJ)
|
libsesman_la_DEPENDENCIES = $(AUTHMOD_OBJ)
|
||||||
|
|||||||
@@ -1,237 +0,0 @@
|
|||||||
/**
|
|
||||||
* xrdp: A Remote Desktop Protocol server.
|
|
||||||
*
|
|
||||||
* Copyright (C) Jay Sorg 2004-2013
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @file verify_user_kerberos.c
|
|
||||||
* @brief Authenticate user using kerberos
|
|
||||||
* @author Jay Sorg
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(HAVE_CONFIG_H)
|
|
||||||
#include <config_ac.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "arch.h"
|
|
||||||
#include "sesman_auth.h"
|
|
||||||
#include "os_calls.h"
|
|
||||||
#include "string_calls.h"
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#include <krb5.h>
|
|
||||||
|
|
||||||
struct auth_info
|
|
||||||
{
|
|
||||||
krb5_context ctx;
|
|
||||||
krb5_ccache cc;
|
|
||||||
krb5_principal me;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/* Logs a kerberos error code */
|
|
||||||
static void
|
|
||||||
log_kerberos_failure(krb5_context ctx, krb5_error_code code, const char *where)
|
|
||||||
{
|
|
||||||
const char *errstr = krb5_get_error_message(ctx, code);
|
|
||||||
LOG(LOG_LEVEL_ERROR, "Kerberos call to %s failed [%s]", where, errstr);
|
|
||||||
krb5_free_error_message(ctx, errstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
int
|
|
||||||
auth_end(struct auth_info *auth_info)
|
|
||||||
{
|
|
||||||
if (auth_info != NULL)
|
|
||||||
{
|
|
||||||
if (auth_info->me)
|
|
||||||
{
|
|
||||||
krb5_free_principal(auth_info->ctx, auth_info->me);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auth_info->cc)
|
|
||||||
{
|
|
||||||
krb5_cc_close(auth_info->ctx, auth_info->cc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auth_info->ctx)
|
|
||||||
{
|
|
||||||
krb5_free_context(auth_info->ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_memset(auth_info, 0, sizeof(*auth_info));
|
|
||||||
g_free(auth_info);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/* Checks Kerberos can be used
|
|
||||||
*
|
|
||||||
* If all is well, an auth_info struct is returned */
|
|
||||||
static struct auth_info *
|
|
||||||
k5_begin(const char *username)
|
|
||||||
{
|
|
||||||
int ok = 0;
|
|
||||||
struct auth_info *auth_info = g_new0(struct auth_info, 1);
|
|
||||||
krb5_error_code code;
|
|
||||||
|
|
||||||
if (auth_info == NULL)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "Out of memory in k5_begin()");
|
|
||||||
}
|
|
||||||
else if ((code = krb5_init_context(&auth_info->ctx)) != 0)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "Can't init Kerberos context");
|
|
||||||
}
|
|
||||||
/* Determine the credentials cache to use */
|
|
||||||
else if ((code = krb5_cc_default(auth_info->ctx, &auth_info->cc)) != 0)
|
|
||||||
{
|
|
||||||
log_kerberos_failure(auth_info->ctx, code, "krb5_cc_default");
|
|
||||||
}
|
|
||||||
/* Parse the username into a full principal */
|
|
||||||
else if ((code = krb5_parse_name(auth_info->ctx,
|
|
||||||
username, &auth_info->me)) != 0)
|
|
||||||
{
|
|
||||||
log_kerberos_failure(auth_info->ctx, code, "krb5_parse_name");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ok = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
auth_end(auth_info);
|
|
||||||
auth_info = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return auth_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/* returns boolean */
|
|
||||||
static enum scp_login_status
|
|
||||||
k5_kinit(struct auth_info *auth_info, const char *password)
|
|
||||||
{
|
|
||||||
enum scp_login_status status = E_SCP_LOGIN_GENERAL_ERROR;
|
|
||||||
krb5_creds my_creds;
|
|
||||||
krb5_error_code code = 0;
|
|
||||||
|
|
||||||
code = krb5_get_init_creds_password(auth_info->ctx,
|
|
||||||
&my_creds, auth_info->me,
|
|
||||||
password, NULL, NULL,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
if (code != 0)
|
|
||||||
{
|
|
||||||
log_kerberos_failure(auth_info->ctx, code,
|
|
||||||
"krb5_get_init_creds_password");
|
|
||||||
status = E_SCP_LOGIN_NOT_AUTHENTICATED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Try to store the creds in the credentials cache
|
|
||||||
*/
|
|
||||||
if ((code = krb5_cc_initialize(auth_info->ctx, auth_info->cc,
|
|
||||||
auth_info->me)) != 0)
|
|
||||||
{
|
|
||||||
log_kerberos_failure(auth_info->ctx, code, "krb5_cc_initialize");
|
|
||||||
}
|
|
||||||
else if ((code = krb5_cc_store_cred(auth_info->ctx, auth_info->cc,
|
|
||||||
&my_creds)) != 0)
|
|
||||||
{
|
|
||||||
log_kerberos_failure(auth_info->ctx, code, "krb5_cc_store_cred");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = E_SCP_LOGIN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prevent double-free of the client principal */
|
|
||||||
if (my_creds.client == auth_info->me)
|
|
||||||
{
|
|
||||||
my_creds.client = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
krb5_free_cred_contents(auth_info->ctx, &my_creds);
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/* returns non-NULL for success */
|
|
||||||
struct auth_info *
|
|
||||||
auth_userpass(const char *user, const char *pass,
|
|
||||||
const char *client_ip, enum scp_login_status *errorcode)
|
|
||||||
{
|
|
||||||
enum scp_login_status status = E_SCP_LOGIN_GENERAL_ERROR;
|
|
||||||
struct auth_info *auth_info = k5_begin(user);
|
|
||||||
|
|
||||||
if (auth_info)
|
|
||||||
{
|
|
||||||
status = k5_kinit(auth_info, pass);
|
|
||||||
if (status != E_SCP_LOGIN_OK)
|
|
||||||
{
|
|
||||||
auth_end(auth_info);
|
|
||||||
auth_info = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorcode != NULL)
|
|
||||||
{
|
|
||||||
*errorcode = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return auth_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/* returns non-NULL for success */
|
|
||||||
struct auth_info *
|
|
||||||
auth_uds(const char *user, enum scp_login_status *errorcode)
|
|
||||||
{
|
|
||||||
struct auth_info *auth_info = k5_begin(user);
|
|
||||||
|
|
||||||
if (errorcode != NULL)
|
|
||||||
{
|
|
||||||
*errorcode =
|
|
||||||
(auth_info != NULL) ? E_SCP_LOGIN_OK : E_SCP_LOGIN_GENERAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return auth_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/* returns error */
|
|
||||||
int
|
|
||||||
auth_start_session(struct auth_info *auth_info, const char *display)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
int
|
|
||||||
auth_set_env(struct auth_info *auth_info)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,365 +0,0 @@
|
|||||||
/**
|
|
||||||
* xrdp: A Remote Desktop Protocol server.
|
|
||||||
*
|
|
||||||
* Copyright (C) Jay Sorg 2004-2013
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @file verify_user_pam.c
|
|
||||||
* @brief Authenticate user using pam
|
|
||||||
* @author Jay Sorg
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(HAVE_CONFIG_H)
|
|
||||||
#include <config_ac.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "arch.h"
|
|
||||||
#include "os_calls.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "string_calls.h"
|
|
||||||
#include "sesman_auth.h"
|
|
||||||
|
|
||||||
#include <security/pam_userpass.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <security/pam_appl.h>
|
|
||||||
|
|
||||||
#define SERVICE "xrdp"
|
|
||||||
|
|
||||||
struct auth_info
|
|
||||||
{
|
|
||||||
pam_userpass_t userpass;
|
|
||||||
int session_opened;
|
|
||||||
int did_setcred;
|
|
||||||
struct pam_conv pamc;
|
|
||||||
pam_handle_t *ph;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
/** Performs PAM operations common to login methods
|
|
||||||
*
|
|
||||||
* @param auth_info Module auth_info structure
|
|
||||||
* @param client_ip Client IP if known, or NULL
|
|
||||||
* @param need_pam_authenticate True if user must be authenticated as
|
|
||||||
* well as authorized
|
|
||||||
* @return Code describing the success of the operation
|
|
||||||
*
|
|
||||||
* The username is assumed to be supplied by the caller in
|
|
||||||
* auth_info->userpass.user
|
|
||||||
*/
|
|
||||||
static enum scp_login_status
|
|
||||||
common_pam_login(struct auth_info *auth_info,
|
|
||||||
const char *client_ip,
|
|
||||||
int need_pam_authenticate)
|
|
||||||
{
|
|
||||||
int perror;
|
|
||||||
|
|
||||||
perror = pam_start(SERVICE, auth_info->userpass.user,
|
|
||||||
&(auth_info->pamc), &(auth_info->ph));
|
|
||||||
|
|
||||||
if (perror != PAM_SUCCESS)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "pam_start failed: %s",
|
|
||||||
pam_strerror(auth_info->ph, perror));
|
|
||||||
pam_end(auth_info->ph, perror);
|
|
||||||
return E_SCP_LOGIN_GENERAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client_ip != NULL && client_ip[0] != '\0')
|
|
||||||
{
|
|
||||||
perror = pam_set_item(auth_info->ph, PAM_RHOST, client_ip);
|
|
||||||
if (perror != PAM_SUCCESS)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "pam_set_item(PAM_RHOST) failed: %s",
|
|
||||||
pam_strerror(auth_info->ph, perror));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
perror = pam_set_item(auth_info->ph, PAM_TTY, SERVICE);
|
|
||||||
if (perror != PAM_SUCCESS)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "pam_set_item(PAM_TTY) failed: %s",
|
|
||||||
pam_strerror(auth_info->ph, perror));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (need_pam_authenticate)
|
|
||||||
{
|
|
||||||
perror = pam_authenticate(auth_info->ph, 0);
|
|
||||||
|
|
||||||
if (perror != PAM_SUCCESS)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "pam_authenticate failed: %s",
|
|
||||||
pam_strerror(auth_info->ph, perror));
|
|
||||||
pam_end(auth_info->ph, perror);
|
|
||||||
return E_SCP_LOGIN_NOT_AUTHENTICATED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* From man page:
|
|
||||||
The pam_acct_mgmt function is used to determine if the users account is
|
|
||||||
valid. It checks for authentication token and account expiration and
|
|
||||||
verifies access restrictions. It is typically called after the user has
|
|
||||||
been authenticated.
|
|
||||||
*/
|
|
||||||
perror = pam_acct_mgmt(auth_info->ph, 0);
|
|
||||||
|
|
||||||
if (perror != PAM_SUCCESS)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "pam_acct_mgmt failed: %s",
|
|
||||||
pam_strerror(auth_info->ph, perror));
|
|
||||||
pam_end(auth_info->ph, perror);
|
|
||||||
return E_SCP_LOGIN_NOT_AUTHORIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return E_SCP_LOGIN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/* returns non-NULL for success
|
|
||||||
* Detailed error code is in the errorcode variable */
|
|
||||||
|
|
||||||
struct auth_info *
|
|
||||||
auth_userpass(const char *user, const char *pass,
|
|
||||||
const char *client_ip, enum scp_login_status *errorcode)
|
|
||||||
{
|
|
||||||
struct auth_info *auth_info;
|
|
||||||
enum scp_login_status status;
|
|
||||||
|
|
||||||
auth_info = g_new0(struct auth_info, 1);
|
|
||||||
if (auth_info == NULL)
|
|
||||||
{
|
|
||||||
status = E_SCP_LOGIN_NO_MEMORY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auth_info->userpass.user = user;
|
|
||||||
auth_info->userpass.pass = pass;
|
|
||||||
|
|
||||||
auth_info->pamc.conv = &pam_userpass_conv;
|
|
||||||
auth_info->pamc.appdata_ptr = &(auth_info->userpass);
|
|
||||||
status = common_pam_login(auth_info, client_ip, 1);
|
|
||||||
|
|
||||||
if (status != E_SCP_LOGIN_OK)
|
|
||||||
{
|
|
||||||
g_free(auth_info);
|
|
||||||
auth_info = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorcode != NULL)
|
|
||||||
{
|
|
||||||
*errorcode = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return auth_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
struct auth_info *
|
|
||||||
auth_uds(const char *user, enum scp_login_status *errorcode)
|
|
||||||
{
|
|
||||||
struct auth_info *auth_info;
|
|
||||||
enum scp_login_status status;
|
|
||||||
|
|
||||||
auth_info = g_new0(struct auth_info, 1);
|
|
||||||
if (auth_info == NULL)
|
|
||||||
{
|
|
||||||
status = E_SCP_LOGIN_NO_MEMORY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auth_info->userpass.user = user;
|
|
||||||
status = common_pam_login(auth_info, NULL, 0);
|
|
||||||
|
|
||||||
if (status != E_SCP_LOGIN_OK)
|
|
||||||
{
|
|
||||||
g_free(auth_info);
|
|
||||||
auth_info = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorcode != NULL)
|
|
||||||
{
|
|
||||||
*errorcode = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return auth_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
/* returns error */
|
|
||||||
static int
|
|
||||||
auth_start_session_private(struct auth_info *auth_info, const char *display)
|
|
||||||
{
|
|
||||||
// For Linux and maybe other systems, pam_systemd needs to know the
|
|
||||||
// session type in order to set the session up correctly
|
|
||||||
const char *session_type;
|
|
||||||
if (g_get_x11_display_from_display_string(display) >= 0)
|
|
||||||
{
|
|
||||||
session_type = "x11";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
session_type = "wayland";
|
|
||||||
}
|
|
||||||
g_setenv_log("XDG_SESSION_TYPE", session_type, 1);
|
|
||||||
|
|
||||||
int error = pam_set_item(auth_info->ph, PAM_TTY, display);
|
|
||||||
|
|
||||||
if (error != PAM_SUCCESS)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "pam_set_item(PAM_TTY) failed: %s",
|
|
||||||
pam_strerror(auth_info->ph, error));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = pam_setcred(auth_info->ph, PAM_ESTABLISH_CRED);
|
|
||||||
|
|
||||||
if (error != PAM_SUCCESS)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "pam_setcred failed: %s",
|
|
||||||
pam_strerror(auth_info->ph, error));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
auth_info->did_setcred = 1;
|
|
||||||
error = pam_open_session(auth_info->ph, 0);
|
|
||||||
|
|
||||||
if (error != PAM_SUCCESS)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "pam_open_session failed: %s",
|
|
||||||
pam_strerror(auth_info->ph, error));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
auth_info->session_opened = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/**
|
|
||||||
* Main routine to start a session
|
|
||||||
*
|
|
||||||
* Calls the private routine and logs an additional error if the private
|
|
||||||
* routine fails
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
auth_start_session(struct auth_info *auth_info, const char *display)
|
|
||||||
{
|
|
||||||
int result = auth_start_session_private(auth_info, display);
|
|
||||||
if (result != 0)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR,
|
|
||||||
"Can't start PAM session. See PAM logging for more info");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/* returns error */
|
|
||||||
static int
|
|
||||||
auth_stop_session(struct auth_info *auth_info)
|
|
||||||
{
|
|
||||||
int rv = 0;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
if (auth_info->session_opened)
|
|
||||||
{
|
|
||||||
error = pam_close_session(auth_info->ph, 0);
|
|
||||||
if (error != PAM_SUCCESS)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "pam_close_session failed: %s",
|
|
||||||
pam_strerror(auth_info->ph, error));
|
|
||||||
rv = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auth_info->session_opened = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auth_info->did_setcred)
|
|
||||||
{
|
|
||||||
pam_setcred(auth_info->ph, PAM_DELETE_CRED);
|
|
||||||
auth_info->did_setcred = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/* returns error */
|
|
||||||
/* cleanup */
|
|
||||||
int
|
|
||||||
auth_end(struct auth_info *auth_info)
|
|
||||||
{
|
|
||||||
if (auth_info != NULL)
|
|
||||||
{
|
|
||||||
if (auth_info->ph != 0)
|
|
||||||
{
|
|
||||||
auth_stop_session(auth_info);
|
|
||||||
|
|
||||||
pam_end(auth_info->ph, PAM_SUCCESS);
|
|
||||||
auth_info->ph = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free(auth_info);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/* returns error */
|
|
||||||
/* set any pam env vars */
|
|
||||||
int
|
|
||||||
auth_set_env(struct auth_info *auth_info)
|
|
||||||
{
|
|
||||||
char **pam_envlist;
|
|
||||||
char **pam_env;
|
|
||||||
|
|
||||||
if (auth_info != NULL)
|
|
||||||
{
|
|
||||||
/* export PAM environment */
|
|
||||||
pam_envlist = pam_getenvlist(auth_info->ph);
|
|
||||||
|
|
||||||
if (pam_envlist != NULL)
|
|
||||||
{
|
|
||||||
for (pam_env = pam_envlist; *pam_env != NULL; ++pam_env)
|
|
||||||
{
|
|
||||||
char *str = *pam_env;
|
|
||||||
char *eq_pos = strchr(str, '=');
|
|
||||||
|
|
||||||
if (eq_pos != NULL)
|
|
||||||
{
|
|
||||||
*eq_pos = '\0';
|
|
||||||
g_setenv_log(str, eq_pos + 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free(pam_envlist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user