[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: pppd 2.3.3 with pam



On Wed, 7 Jan 1998, Sergio Ballestrero wrote:

> allow Auto-PPP (PAP) logins, but PAM always answers with an authentication
> failure. Note that the thing works if i recompile pppd without PAM
> support.

The PAM "support" in pppd-2.3.3 is BROKEN, badly BROKEN, completely
BROKEN, etc.

Whoever patched that in failed to read PAM standards.

A PAM patch for pppd 2.3.3 and RH 5.0 is attached. RH will release an
updated pppd package "soon". I don't expect it to work on RH 4.2. But it
will be easy enough to adapt it for the older PAM lib.

Cristian
--
----------------------------------------------------------------------
Cristian Gafton   --   gafton@redhat.com   --   Red Hat Software, Inc.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 UNIX is user friendly. It's just selective about who its friends are.
--- ppp-2.3.3/pppd/auth.c.pam	Thu Nov 27 01:49:15 1997
+++ ppp-2.3.3/pppd/auth.c	Tue Jan  6 17:10:11 1998
@@ -694,18 +694,63 @@
     return ret;
 }
 
-/*
- * This function is needed for PAM. However, it should not be called.
- * If it is, return the error code.
- */
-
 #ifdef USE_PAM
-static int pam_conv(int num_msg, const struct pam_message **msg,
-		    struct pam_response **resp, void *appdata_ptr)
+/* Static variables used to communicate between the conversation function
+ * and the server_login function
+ */
+static char *PAM_username;
+static char *PAM_password;
+static int PAM_error = 0;
+
+/* PAM conversation function
+ * Here we assume (for now, at least) that echo on means login name, and
+ * echo off means password.
+ */
+static int PAM_conv (int num_msg, const struct pam_message **msg,
+		     struct pam_response **resp, void *appdata_ptr)
 {
-    return PAM_CONV_ERR;
+    int replies = 0;
+    struct pam_response *reply = NULL;
+
+#define COPY_STRING(s) (s) ? strdup(s) : NULL
+
+    reply = malloc(sizeof(struct pam_response) * num_msg);
+    if (!reply) return PAM_CONV_ERR;
+
+    for (replies = 0; replies < num_msg; replies++) {
+	switch (msg[replies]->msg_style) {
+	    case PAM_PROMPT_ECHO_ON:
+		reply[replies].resp_retcode = PAM_SUCCESS;
+		reply[replies].resp = COPY_STRING(PAM_username);
+		/* PAM frees resp */
+		break;
+	    case PAM_PROMPT_ECHO_OFF:
+		reply[replies].resp_retcode = PAM_SUCCESS;
+		reply[replies].resp = COPY_STRING(PAM_password);
+		/* PAM frees resp */
+		break;
+	    case PAM_TEXT_INFO:
+		/* fall through */
+	    case PAM_ERROR_MSG:
+		/* ignore it, but pam still wants a NULL response... */
+		reply[replies].resp_retcode = PAM_SUCCESS;
+		reply[replies].resp = NULL;
+		break;
+	    default:
+		/* Must be an error of some sort... */
+		free (reply);
+		PAM_error = 1;
+		return PAM_CONV_ERR;
+	}
+    }
+    *resp = reply;
+    return PAM_SUCCESS;
 }
-#endif
+static struct pam_conv PAM_conversation = {
+    &PAM_conv,
+    NULL
+};
+#endif /* USE_PAM */
 
 /*
  * plogin - Check the user name and password against the system
@@ -725,50 +770,44 @@
     int *msglen;
 {
     char *tty;
-
+    struct passwd *pw = NULL;
+    
 #ifdef USE_PAM
-    struct pam_conv pam_conversation;
+    /* Oh, my God! the previous patch was SO BROKEN... */
     pam_handle_t *pamh;
     int pam_error;
-    char *pass;
-    char *dev;
-/*
- * Fill the pam_conversion structure
- */
-    memset (&pam_conversation, '\0', sizeof (struct pam_conv));
-    pam_conversation.conv = &pam_conv;
 
-    pam_error = pam_start ("ppp", user, &pam_conversation, &pamh);
+    pam_error = pam_start ("pppd", user, &PAM_conversation, &pamh);
     if (pam_error != PAM_SUCCESS) {
-        *msg = (char *) pam_strerror (pam_error);
+        *msg = pam_strerror (pamh, pam_error);
 	return UPAP_AUTHNAK;
     }
-/*
- * Define the fields for the credintial validation
- */
-    (void) pam_set_item (pamh, PAM_AUTHTOK, passwd);
-    (void) pam_set_item (pamh, PAM_TTY,     devnam);
-/*
- * Validate the user
- */
+    /*
+     * Define the fields for the credintial validation
+     */
+    PAM_username = user;
+    PAM_password = passwd;
+    PAM_error = 0;
+    /*
+     * Validate the user
+     */
     pam_error = pam_authenticate (pamh, PAM_SILENT);
-    if (pam_error == PAM_SUCCESS)
+    if (pam_error == PAM_SUCCESS && !PAM_error)
         pam_error = pam_acct_mgmt (pamh, PAM_SILENT);
 
-    *msg = (char *) pam_strerror (pam_error);
-/*
- * Clean up the mess
- */
+    *msg = (char *) pam_strerror (pamh, pam_error);
+    /*
+     * Clean up the mess
+     */
     (void) pam_end (pamh, pam_error);
 
     if (pam_error != PAM_SUCCESS)
         return UPAP_AUTHNAK;
-/*
- * Use the non-PAM methods directly
- */
-#else /* #ifdef USE_PAM */
 
-    struct passwd *pw;
+#else /* #ifdef USE_PAM */
+    /*
+     * Use the non-PAM methods directly
+     */
 
 #ifdef HAS_SHADOW
     struct spwd *spwd;
@@ -814,7 +853,7 @@
     logwtmp(tty, user, remote_name);		/* Add wtmp login entry */
 
 #ifdef _PATH_LASTLOG
-    {
+    if (pw != (struct passwd *)NULL) {
 	    struct lastlog ll;
 	    int fd;
 

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index] []