]> andersk Git - openssh.git/commitdiff
Attempt to clean up PAM code
authordamien <damien>
Wed, 27 Oct 1999 13:42:05 +0000 (13:42 +0000)
committerdamien <damien>
Wed, 27 Oct 1999 13:42:05 +0000 (13:42 +0000)
Use PWDB getpw* functions if HAVE_PWDB defined

Minor other tidyups

Makefile.GNU
auth-passwd.c
includes.h
sshd.c

index f36bdb3dfbdc0e615d2b6e709678a93db003395a..09719952759d5e3d35e4a93cf73b76f3854f1074 100644 (file)
@@ -1,8 +1,8 @@
 OPT_FLAGS=-g
-CFLAGS=$(OPT_FLAGS) -Wall -DETCDIR=\"/etc/ssh\" -DHAVE_PAM
+CFLAGS=$(OPT_FLAGS) -Wall -DETCDIR=\"/etc/ssh\" -DHAVE_PAM -DHAVE_PWDB
 TARGETS=bin/libssh.a bin/ssh bin/sshd bin/ssh-add bin/ssh-keygen bin/ssh-agent bin/scp
 LFLAGS=-L./bin
-LIBS=-lssh -lcrypto -lz -lutil -lpam -ldl
+LIBS=-lssh -lcrypto -lz -lutil  -lpwdb -lpam -ldl
 AR=ar
 RANLIB=ranlib
 
index a1cffba3c63df9e38478d6261b0e55ae467d0e18..27d2818a9e32ce7bc3e2c26796b4500f70308e28 100644 (file)
@@ -26,14 +26,6 @@ RCSID("$Id$");
 extern char *ticket;
 #endif /* KRB4 */
 
-#ifdef HAVE_PAM
-#include <security/pam_appl.h>
-extern pam_handle_t *pamh;
-extern int retval;
-extern char* pampasswd;
-extern int origretval;
-#endif /* HAVE_PAM */
-
 /* Tries to authenticate the user using password.  Returns true if
    authentication succeeds. */
 
@@ -58,26 +50,6 @@ int auth_password(struct passwd *pw, const char *password)
   if (pw == NULL)
     return 0;
 
-#ifdef HAVE_PAM
-  retval = origretval;
-
-  pampasswd = xstrdup(password);
-
-  if (retval == PAM_SUCCESS)
-    retval = pam_authenticate ((pam_handle_t *)pamh, 0);
-
-  if (retval == PAM_SUCCESS)
-    retval = pam_acct_mgmt ((pam_handle_t *)pamh, 0);
-
-  xfree(pampasswd);
-
-  if (retval == PAM_SUCCESS) 
-    retval = pam_open_session ((pam_handle_t *)pamh, 0);
-  
-  return (retval == PAM_SUCCESS);
-
-#else /* HAVE_PAM */
-
 #ifdef SKEY
   if (options.skey_authentication == 1) {
     if (strncasecmp(password, "s/key", 5) == 0) {
@@ -205,5 +177,4 @@ int auth_password(struct passwd *pw, const char *password)
 
   /* Authentication is accepted if the encrypted passwords are identical. */
   return (strcmp(encrypted_password, pw->pw_passwd) == 0);
-#endif /* HAVE_PAM */
 }
index 8fa174bd6b7b4f48fa6edf026714b7247059eaf9..b2e8c1e78ac83581d902bbb05a8c6452fb337db1 100644 (file)
@@ -61,6 +61,14 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
 #include "mktemp.h"
 #include "strlcpy.h"
 
+#ifdef HAVE_PAM
+#include <security/pam_appl.h>
+#endif /* HAVE_PAM */
+
+#ifdef HAVE_PWDB
+#include <pwdb/pwdb_map.h>
+#endif /* HAVE_PWDB */
+
 /* Define this to be the path of the xauth program. */
 #ifndef XAUTH_PATH
 #define XAUTH_PATH "/usr/X11R6/bin/xauth"
diff --git a/sshd.c b/sshd.c
index 1ff9c92480bbd306cc75ac492dd000c1670166d0..7f259ae4aa8159e6cbb373d2c743f187c4989ce5 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -47,14 +47,6 @@ int deny_severity = LOG_WARNING;
 char *ticket = NULL;
 #endif /* KRB4 */
 
-#ifdef HAVE_PAM
-#include <security/pam_appl.h>
-struct pam_handle_t *pamh=NULL;
-char *pampasswd=NULL;
-int retval;
-int origretval;
-#endif /* HAVE_PAM */
-
 /* Local Xauthority file. */
 char *xauthfile = NULL;
 
@@ -139,69 +131,127 @@ void do_child(const char *command, struct passwd *pw, const char *term,
 #ifdef HAVE_PAM
 static int pamconv(int num_msg, const struct pam_message **msg,
                    struct pam_response **resp, void *appdata_ptr);
+void do_pam_authentication(const char *username, const char *password, 
+                           const char *remote_user, const char *remote_host);
+void pam_cleanup_proc(void *context);
 
 static struct pam_conv conv = {
     pamconv,
     NULL
 };
+struct pam_handle_t *pamh = NULL;
+const char *pampasswd = NULL;
 
 static int pamconv(int num_msg, const struct pam_message **msg,
                    struct pam_response **resp, void *appdata_ptr)
 {
   int count = 0;
-  int replies = 0;
   struct pam_response *reply = NULL;
-  int size = sizeof(struct pam_response);
 
+  /* PAM will free this later */
+  reply = malloc(num_msg * sizeof(*reply));
+  if (reply == NULL)
+    return PAM_CONV_ERR; 
+  
   for(count = 0; count < num_msg; count++)
   {
     switch (msg[count]->msg_style)
     {
-      case PAM_PROMPT_ECHO_ON:
       case PAM_PROMPT_ECHO_OFF:
-        if (reply == NULL) 
-          reply = xmalloc(size); 
-        else 
-          reply = realloc(reply, size);
-                        
-                 if (reply == NULL)
-          return PAM_CONV_ERR; 
-                        
-        size += sizeof(struct pam_response);
-                 
-                 reply[replies].resp_retcode = PAM_SUCCESS;
-                 
-                 reply[replies++].resp = xstrdup(pampasswd);
-                        /* PAM frees resp */
-                 break;
-
-               case PAM_TEXT_INFO:
-                 /* ignore it... */
-                 break;
-
-               case PAM_ERROR_MSG:
-               default:
-                 /* Must be an error of some sort... */
-                 if (reply != NULL)
+       if (pampasswd == NULL)
+        {
           free(reply);
+          return PAM_CONV_ERR;
+        }
+        reply[count].resp_retcode = PAM_SUCCESS;
+        reply[count].resp = xstrdup(pampasswd);
+        break;
+
+      case PAM_TEXT_INFO:
+        reply[count].resp_retcode = PAM_SUCCESS;
+        reply[count].resp = xstrdup("");
+        break;
 
-                 return PAM_CONV_ERR;
-        }
+      case PAM_PROMPT_ECHO_ON:
+      case PAM_ERROR_MSG:
+      default:
+        free(reply);
+        return PAM_CONV_ERR;
+    }
   }
 
-  if (reply != NULL)
-    *resp = reply;
+  *resp = reply;
         
   return PAM_SUCCESS;
 }
 
 void pam_cleanup_proc(void *context)
 {
-  if (retval == PAM_SUCCESS) 
+  int retval;
+  
+  if (pamh != NULL)
+  {
     retval = pam_close_session((pam_handle_t *)pamh, 0);
         
-  if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
-    log("Cannot release PAM authentication.");
+    if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
+      log("Cannot release PAM authentication.");
+  }
+}
+
+void do_pam_authentication(const char *username, const char *password, const char *remote_user, const char *remote_host)
+{
+  int pam_auth_ok = 1;
+
+  pampasswd = password;
+  
+  do
+  {
+    if (PAM_SUCCESS != pam_start("ssh", username, &conv, (pam_handle_t**)&pamh))
+    {
+      pam_auth_ok = 0;
+      break;
+    }
+
+    fatal_add_cleanup(&pam_cleanup_proc, NULL); 
+
+    if (remote_host && (PAM_SUCCESS != pam_set_item((pam_handle_t *)pamh, PAM_RHOST, remote_host)))
+    {
+      pam_auth_ok = 0;
+      break;
+    }
+
+    if (remote_user && (PAM_SUCCESS != pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user)))
+    {
+      pam_auth_ok = 0;
+      break;
+    }
+    
+    if (PAM_SUCCESS != pam_authenticate((pam_handle_t *)pamh, 0))
+    {
+      pam_auth_ok = 0;
+      break;
+    }
+
+    if (PAM_SUCCESS != pam_acct_mgmt((pam_handle_t *)pamh, 0))
+    {
+      pam_auth_ok = 0;
+      break;
+    }
+
+    if (PAM_SUCCESS != pam_open_session((pam_handle_t *)pamh, 0))
+    {
+      pam_auth_ok = 0;
+      break;
+    }
+  } while (0);
+  
+  if (!pam_auth_ok)
+  {
+    packet_start(SSH_SMSG_FAILURE);
+    packet_send();
+    packet_write_wait();
+    packet_disconnect("PAM authentication failed.");
+  }
 }
 #endif /* HAVE_PAM */
 
@@ -788,13 +838,19 @@ main(int ac, char **av)
   log("Closing connection to %.100s", inet_ntoa(sin.sin_addr));
 
 #ifdef HAVE_PAM
-  if (retval == PAM_SUCCESS)
-    retval = pam_close_session((pam_handle_t *)pamh, 0);
+  {
+    int retval;
+    
+    if (pamh != NULL)
+    {
+      retval = pam_close_session((pam_handle_t *)pamh, 0);
 
-  if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
-    log("Cannot release PAM authentication.");
+      if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
+        log("Cannot release PAM authentication.");
         
-  fatal_remove_cleanup(&pam_cleanup_proc, NULL);
+      fatal_remove_cleanup(&pam_cleanup_proc, NULL);
+    }
+  }
 #endif /* HAVE_PAM */
 
   packet_close();
@@ -1078,14 +1134,11 @@ do_authentication(char *user, int privileged_port)
   int type;
   int authenticated = 0;
   int authentication_failures = 0;
-  char *password;
+  char *password = NULL;
   struct passwd *pw, pwcopy;
-  char *client_user;
+  char *client_user = NULL;
   unsigned int client_host_key_bits;
   BIGNUM *client_host_key_e, *client_host_key_n;
-#ifdef HAVE_PAM
-  int pam_auth_ok;
-#endif /* HAVE_PAM */
                         
 #ifdef AFS
   /* If machine has AFS, set process authentication group. */
@@ -1097,21 +1150,7 @@ do_authentication(char *user, int privileged_port)
        
   /* Verify that the user is a valid user. */
   pw = getpwnam(user);
-#ifdef HAVE_PAM
-  if ((pw != NULL) && allowed_user(pw))
-  {
-    /* Initialise PAM */
-    retval = pam_start("ssh", pw->pw_name, &conv, (pam_handle_t **)&pamh);
-    fatal_add_cleanup(&pam_cleanup_proc, NULL); 
-    origretval = retval;
-    if (retval == PAM_SUCCESS)
-               pam_auth_ok = 1;
-  }
-  
-  if (pam_auth_ok == 0)
-#else /* HAVE_PAM */
   if (!pw || !allowed_user(pw))
-#endif /* HAVE_PAM */
     {
       /* The user does not exist or access is denied,
          but fake indication that authentication is needed. */
@@ -1306,12 +1345,16 @@ do_authentication(char *user, int privileged_port)
              log("Rhosts authentication accepted for %.100s, remote %.100s on %.700s.",
                  user, client_user, get_canonical_hostname());
              authenticated = 1;
+#ifndef HAVE_PAM
              xfree(client_user);
+#endif /* HAVE_PAM */
              break;
            }
          log("Rhosts authentication failed for %.100s, remote %.100s.",
                user, client_user);
+#ifndef HAVE_PAM
          xfree(client_user);
+#endif /* HAVE_PAM */
          break;
 
        case SSH_CMSG_AUTH_RHOSTS_RSA:
@@ -1354,14 +1397,18 @@ do_authentication(char *user, int privileged_port)
            {
              /* Authentication accepted. */
              authenticated = 1;
+#ifndef HAVE_PAM
              xfree(client_user);
+#endif /* HAVE_PAM */
              BN_clear_free(client_host_key_e);
              BN_clear_free(client_host_key_n);
              break;
            }
          log("Rhosts authentication failed for %.100s, remote %.100s.",
                user, client_user);
-         xfree(client_user);
+#ifndef HAVE_PAM
+          xfree(client_user);
+#endif /* HAVE_PAM */
          BN_clear_free(client_host_key_e);
          BN_clear_free(client_host_key_n);
          break;
@@ -1412,6 +1459,12 @@ do_authentication(char *user, int privileged_port)
            packet_integrity_check(plen, 4 + passw_len, type);
          }
 
+#ifdef HAVE_PAM
+          /* Authentication will be handled later */
+          /* keep password around until then */
+          authenticated = 1;
+          break;
+#else /* HAVE_PAM */
          /* Try authentication with the password. */
          if (auth_password(pw, password))
            {
@@ -1427,6 +1480,7 @@ do_authentication(char *user, int privileged_port)
          memset(password, 0, strlen(password));
          xfree(password);
          break;
+#endif /* HAVE_PAM */
 
        case SSH_CMSG_AUTH_TIS:
          /* TIS Authentication is unsupported */
@@ -1464,6 +1518,20 @@ do_authentication(char *user, int privileged_port)
                          get_canonical_hostname());
     }
 
+#ifdef HAVE_PAM
+  do_pam_authentication(pw->pw_name, password, client_user, get_canonical_hostname());
+
+  /* Clean up */
+  if (client_user != NULL)
+    xfree(client_user);
+
+  if (password != NULL)
+  {
+    memset(password, 0, strlen(password));
+    xfree(password);
+  }
+#endif /* HAVE_PAM */
+
   /* The user has been authenticated and accepted. */
   packet_start(SSH_SMSG_SUCCESS);
   packet_send();
@@ -2151,10 +2219,6 @@ void do_child(const char *command, struct passwd *pw, const char *term,
        exit(254);
     }
 
-  /* Set login name in the kernel. */
-  if (setlogin(pw->pw_name) < 0)
-    error("setlogin failed: %s", strerror(errno));
-
   /* Set uid, gid, and groups. */
   /* Login(1) does this as well, and it needs uid 0 for the "-h" switch,
      so we let login(1) to this for us. */
This page took 0.084274 seconds and 5 git commands to generate.