]> granicus.if.org Git - uw-imap/commitdiff
add files for 2006-08-31T20:42:02Z
authorUnknown <>
Thu, 31 Aug 2006 20:42:02 +0000 (20:42 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Fri, 7 Sep 2018 00:02:35 +0000 (00:02 +0000)
src/osdep/unix/ckp_pam.c [new file with mode: 0644]

diff --git a/src/osdep/unix/ckp_pam.c b/src/osdep/unix/ckp_pam.c
new file mode 100644 (file)
index 0000000..60c6c1f
--- /dev/null
@@ -0,0 +1,136 @@
+/* ========================================================================
+ * Copyright 1988-2006 University of Washington
+ *
+ * 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
+ *
+ * 
+ * ========================================================================
+ */
+
+/*
+ * Program:    Pluggable Authentication Modules login services
+ *
+ * Author:     Mark Crispin
+ *             Networks and Distributed Computing
+ *             Computing & Communications
+ *             University of Washington
+ *             Administration Building, AG-44
+ *             Seattle, WA  98195
+ *             Internet: MRC@CAC.Washington.EDU
+ *
+ * Date:       1 August 1988
+ * Last Edited:        31 August 2006
+ */
+
+
+#ifdef MAC_OSX_KLUDGE          /* why can't Apple be compatible? */
+#include <pam/pam_appl.h>
+#else
+#include <security/pam_appl.h>
+#endif
+
+struct checkpw_cred {
+  char *uname;                 /* user name */
+  char *pass;                  /* password */
+};
+\f
+/* PAM conversation function
+ * Accepts: number of messages
+ *         vector of messages
+ *         pointer to response return
+ *         application data
+ * Returns: PAM_SUCCESS if OK, response vector filled in, else PAM_CONV_ERR
+ */
+
+static int checkpw_conv (int num_msg,const struct pam_message **msg,
+                        struct pam_response **resp,void *appdata_ptr)
+{
+  int i;
+  struct checkpw_cred *cred = (struct checkpw_cred *) appdata_ptr;
+  struct pam_response *reply = fs_get (sizeof (struct pam_response) * num_msg);
+  for (i = 0; i < num_msg; i++) switch (msg[i]->msg_style) {
+  case PAM_PROMPT_ECHO_ON:     /* assume want user name */
+    reply[i].resp_retcode = PAM_SUCCESS;
+    reply[i].resp = cpystr (cred->uname);
+    break;
+  case PAM_PROMPT_ECHO_OFF:    /* assume want password */
+    reply[i].resp_retcode = PAM_SUCCESS;
+    reply[i].resp = cpystr (cred->pass);
+    break;
+  case PAM_TEXT_INFO:
+  case PAM_ERROR_MSG:
+    reply[i].resp_retcode = PAM_SUCCESS;
+    reply[i].resp = NULL;
+    break;
+  default:                     /* unknown message style */
+    fs_give ((void **) &reply);
+    return PAM_CONV_ERR;
+  }
+  *resp = reply;
+  return PAM_SUCCESS;
+}
+
+
+/* PAM cleanup
+ * Accepts: handle
+ */
+
+static void checkpw_cleanup (pam_handle_t *hdl)
+{
+#if 0  /* see checkpw() for why this is #if 0 */
+  pam_close_session (hdl,NIL); /* close session [uw]tmp */
+#endif
+  pam_setcred (hdl,PAM_DELETE_CRED);
+  pam_end (hdl,PAM_SUCCESS);
+}
+\f
+/* Server log in
+ * Accepts: user name string
+ *         password string
+ * Returns: T if password validated, NIL otherwise
+ */
+
+struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[])
+{
+  pam_handle_t *hdl;
+  struct pam_conv conv;
+  struct checkpw_cred cred;
+  char *name = cpystr (pw->pw_name);
+  conv.conv = &checkpw_conv;
+  conv.appdata_ptr = &cred;
+  cred.uname = name;
+  cred.pass = pass;
+  if (pw = ((pam_start ((char *) mail_parameters (NIL,GET_SERVICENAME,NIL),
+                       pw->pw_name,&conv,&hdl) == PAM_SUCCESS) &&
+           (pam_set_item (hdl,PAM_RHOST,tcp_clientaddr ()) == PAM_SUCCESS) &&
+           (pam_authenticate (hdl,NIL) == PAM_SUCCESS) &&
+           (pam_acct_mgmt (hdl,NIL) == PAM_SUCCESS) &&
+           (pam_setcred (hdl,PAM_ESTABLISH_CRED) == PAM_SUCCESS)) ?
+      getpwnam (name) : NIL) {
+#if 0
+    /*
+     * Some people have reported that this causes a SEGV in strncpy() from
+     * pam_unix.so.1
+     */
+    /*
+     * This pam_open_session() call is inconsistant with how we handle other
+     * platforms, where we don't write [uw]tmp records.  However, unlike our
+     * code on other platforms, pam_acct_mgmt() will check those records for
+     * inactivity and deny the authentication.
+     */
+    pam_open_session (hdl,NIL);        /* make sure account doesn't go inactive */
+#endif
+                               /* arm hook to delete credentials */
+    mail_parameters (NIL,SET_LOGOUTHOOK,(void *) checkpw_cleanup);
+    mail_parameters (NIL,SET_LOGOUTDATA,(void *) hdl);
+  }
+  else checkpw_cleanup (hdl);  /* clean up */
+  fs_give ((void **) &name);
+                               /* reset log facility in case PAM broke it */
+  if (myServerName) openlog (myServerName,LOG_PID,syslog_facility);
+  return pw;
+}