Date: Tue, 8 May 2001 20:00:19 -0700 From: Alfred Perlstein <bright@wintelcom.net> To: Brian Feldman <green@FreeBSD.org> Cc: cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org Subject: Re: cvs commit: src/crypto/openssh auth-pam.c Message-ID: <20010508200018.S18676@fw.wintelcom.net> In-Reply-To: <200105082230.f48MUJH20777@freefall.freebsd.org>; from green@FreeBSD.org on Tue, May 08, 2001 at 03:30:18PM -0700 References: <200105082230.f48MUJH20777@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
* Brian Feldman <green@FreeBSD.org> [010508 15:30] wrote:
> green 2001/05/08 15:30:18 PDT
>
> Modified files:
> crypto/openssh auth-pam.c
> Log:
> Since PAM is broken, let pam_setcred() failure be non-fatal.
That could be pretty bad if auth_pam_password fails with pam.
here's what I think is a better fix.
I sync'd the code up a bit with the "portable ssh" project.
please review as soon as you can as i'm nervous about the
missing check for 'was_authenticated'
-Alfred
Index: auth-pam.c
===================================================================
RCS file: /home/ncvs/src/crypto/openssh/auth-pam.c,v
retrieving revision 1.3
diff -u -r1.3 auth-pam.c
--- auth-pam.c 2001/05/05 01:12:45 1.3
+++ auth-pam.c 2001/05/09 02:57:37
@@ -42,14 +42,14 @@
#define PAM_STRERROR(a, b) pam_strerror((a), (b))
/* Callbacks */
-static int pamconv(int num_msg, const struct pam_message **msg,
+static int do_pam_conversation(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr);
-void pam_cleanup_proc(void *context);
+void do_pam_cleanup_proc(void *context);
void pam_msg_cat(const char *msg);
/* module-local variables */
static struct pam_conv conv = {
- pamconv,
+ do_pam_conversation,
NULL
};
static pam_handle_t *pamh = NULL;
@@ -57,12 +57,27 @@
static char *pam_msg = NULL;
extern ServerOptions options;
-/* states for pamconv() */
+/* states for do_pam_conversation() */
typedef enum { INITIAL_LOGIN, OTHER } pamstates;
static pamstates pamstate = INITIAL_LOGIN;
/* remember whether pam_acct_mgmt() returned PAM_NEWAUTHTOK_REQD */
static int password_change_required = 0;
+/* remember whether the last pam_authenticate() succeeded or not */
+static int was_authenticated = 0;
+/* Remember what has been initialised */
+static int session_opened = 0;
+static int creds_set = 0;
+
+/*
+ * accessor which allows us to switch conversation structs according to
+ * the authentication method being used
+ */
+void do_pam_set_conv(struct pam_conv *conv)
+{
+ pam_set_item(pamh, PAM_CONV, conv);
+}
+
/*
* PAM conversation function.
* There are two states this can run in.
@@ -76,7 +91,7 @@
* and outputs messages to stderr. This mode is used if pam_chauthtok()
* is called to update expired passwords.
*/
-static int pamconv(int num_msg, const struct pam_message **msg,
+static int do_pam_conversation(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr)
{
struct pam_response *reply;
@@ -139,24 +154,27 @@
}
/* Called at exit to cleanly shutdown PAM */
-void pam_cleanup_proc(void *context)
+void do_pam_cleanup_proc(void *context)
{
int pam_retval;
- if (pamh != NULL)
- {
+ if (pamh != NULL && session_opened) {
pam_retval = pam_close_session(pamh, 0);
if (pam_retval != PAM_SUCCESS) {
log("Cannot close PAM session[%d]: %.200s",
pam_retval, PAM_STRERROR(pamh, pam_retval));
}
+ }
+ if (pamh != NULL && creds_set) {
pam_retval = pam_setcred(pamh, PAM_DELETE_CRED);
if (pam_retval != PAM_SUCCESS) {
debug("Cannot delete credentials[%d]: %.200s",
pam_retval, PAM_STRERROR(pamh, pam_retval));
}
+ }
+ if (pamh != NULL) {
pam_retval = pam_end(pamh, pam_retval);
if (pam_retval != PAM_SUCCESS) {
log("Cannot release PAM authentication[%d]: %.200s",
@@ -171,6 +189,8 @@
struct passwd *pw = authctxt->pw;
int pam_retval;
+ do_pam_set_conv(&conv);
+
/* deny if no user. */
if (pw == NULL)
return 0;
@@ -183,6 +203,7 @@
pamstate = INITIAL_LOGIN;
pam_retval = pam_authenticate(pamh, 0);
+ was_authenticated = (pam_retval == PAM_SUCCESS);
if (pam_retval == PAM_SUCCESS) {
debug("PAM Password authentication accepted for user \"%.100s\"",
pw->pw_name);
@@ -198,6 +219,8 @@
int do_pam_account(char *username, char *remote_user)
{
int pam_retval;
+
+ do_pam_set_conv(&conv);
debug("PAM setting rhost to \"%.200s\"",
get_canonical_hostname(options.reverse_mapping_check));
@@ -241,6 +264,8 @@
{
int pam_retval;
+ do_pam_set_conv(&conv);
+
if (ttyname != NULL) {
debug("PAM setting tty to \"%.200s\"", ttyname);
pam_retval = pam_set_item(pamh, PAM_TTY, ttyname);
@@ -256,19 +281,28 @@
fatal("PAM session setup failed[%d]: %.200s",
pam_retval, PAM_STRERROR(pamh, pam_retval));
}
+
+ session_opened = 1;
}
/* Set PAM credentials */
void do_pam_setcred(void)
{
int pam_retval;
+
+ do_pam_set_conv(&conv);
debug("PAM establishing creds");
pam_retval = pam_setcred(pamh, PAM_ESTABLISH_CRED);
if (pam_retval != PAM_SUCCESS) {
- fatal("PAM setcred failed[%d]: %.200s",
- pam_retval, PAM_STRERROR(pamh, pam_retval));
- }
+ if (was_authenticated)
+ fatal("PAM setcred failed[%d]: %.200s",
+ pam_retval, PAM_STRERROR(pamh, pam_retval));
+ else
+ debug("PAM setcred failed[%d]: %.200s",
+ pam_retval, PAM_STRERROR(pamh, pam_retval));
+ } else
+ creds_set = 1;
}
/* accessor function for file scope static variable */
@@ -287,6 +321,8 @@
{
int pam_retval;
+ do_pam_set_conv(&conv);
+
if (password_change_required) {
pamstate = OTHER;
/*
@@ -305,8 +341,8 @@
/* Cleanly shutdown PAM */
void finish_pam(void)
{
- pam_cleanup_proc(NULL);
- fatal_remove_cleanup(&pam_cleanup_proc, NULL);
+ do_pam_cleanup_proc(NULL);
+ fatal_remove_cleanup(&do_pam_cleanup_proc, NULL);
}
/* Start PAM authentication for specified account */
@@ -338,7 +374,7 @@
}
#endif /* PAM_TTY_KLUDGE */
- fatal_add_cleanup(&pam_cleanup_proc, NULL);
+ fatal_add_cleanup(&do_pam_cleanup_proc, NULL);
}
/* Return list of PAM enviornment strings */
--
-Alfred Perlstein - [alfred@freebsd.org]
Represent yourself, show up at BABUG http://www.babug.org/
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010508200018.S18676>
