imapext-2007

diff src/osdep/unix/ckp_pam.c @ 0:ada5e610ab86

imap-2007e
author yuuji@gentei.org
date Mon, 14 Sep 2009 15:17:45 +0900
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/osdep/unix/ckp_pam.c	Mon Sep 14 15:17:45 2009 +0900
     1.3 @@ -0,0 +1,136 @@
     1.4 +/* ========================================================================
     1.5 + * Copyright 1988-2006 University of Washington
     1.6 + *
     1.7 + * Licensed under the Apache License, Version 2.0 (the "License");
     1.8 + * you may not use this file except in compliance with the License.
     1.9 + * You may obtain a copy of the License at
    1.10 + *
    1.11 + *     http://www.apache.org/licenses/LICENSE-2.0
    1.12 + *
    1.13 + * 
    1.14 + * ========================================================================
    1.15 + */
    1.16 +
    1.17 +/*
    1.18 + * Program:	Pluggable Authentication Modules login services
    1.19 + *
    1.20 + * Author:	Mark Crispin
    1.21 + *		Networks and Distributed Computing
    1.22 + *		Computing & Communications
    1.23 + *		University of Washington
    1.24 + *		Administration Building, AG-44
    1.25 + *		Seattle, WA  98195
    1.26 + *		Internet: MRC@CAC.Washington.EDU
    1.27 + *
    1.28 + * Date:	1 August 1988
    1.29 + * Last Edited:	31 August 2006
    1.30 + */
    1.31 +
    1.32 +
    1.33 +#ifdef MAC_OSX_KLUDGE		/* why can't Apple be compatible? */
    1.34 +#include <pam/pam_appl.h>
    1.35 +#else
    1.36 +#include <security/pam_appl.h>
    1.37 +#endif
    1.38 +
    1.39 +struct checkpw_cred {
    1.40 +  char *uname;			/* user name */
    1.41 +  char *pass;			/* password */
    1.42 +};
    1.43 +
    1.44 +/* PAM conversation function
    1.45 + * Accepts: number of messages
    1.46 + *	    vector of messages
    1.47 + *	    pointer to response return
    1.48 + *	    application data
    1.49 + * Returns: PAM_SUCCESS if OK, response vector filled in, else PAM_CONV_ERR
    1.50 + */
    1.51 +
    1.52 +static int checkpw_conv (int num_msg,const struct pam_message **msg,
    1.53 +			 struct pam_response **resp,void *appdata_ptr)
    1.54 +{
    1.55 +  int i;
    1.56 +  struct checkpw_cred *cred = (struct checkpw_cred *) appdata_ptr;
    1.57 +  struct pam_response *reply = fs_get (sizeof (struct pam_response) * num_msg);
    1.58 +  for (i = 0; i < num_msg; i++) switch (msg[i]->msg_style) {
    1.59 +  case PAM_PROMPT_ECHO_ON:	/* assume want user name */
    1.60 +    reply[i].resp_retcode = PAM_SUCCESS;
    1.61 +    reply[i].resp = cpystr (cred->uname);
    1.62 +    break;
    1.63 +  case PAM_PROMPT_ECHO_OFF:	/* assume want password */
    1.64 +    reply[i].resp_retcode = PAM_SUCCESS;
    1.65 +    reply[i].resp = cpystr (cred->pass);
    1.66 +    break;
    1.67 +  case PAM_TEXT_INFO:
    1.68 +  case PAM_ERROR_MSG:
    1.69 +    reply[i].resp_retcode = PAM_SUCCESS;
    1.70 +    reply[i].resp = NULL;
    1.71 +    break;
    1.72 +  default:			/* unknown message style */
    1.73 +    fs_give ((void **) &reply);
    1.74 +    return PAM_CONV_ERR;
    1.75 +  }
    1.76 +  *resp = reply;
    1.77 +  return PAM_SUCCESS;
    1.78 +}
    1.79 +
    1.80 +
    1.81 +/* PAM cleanup
    1.82 + * Accepts: handle
    1.83 + */
    1.84 +
    1.85 +static void checkpw_cleanup (pam_handle_t *hdl)
    1.86 +{
    1.87 +#if 0	/* see checkpw() for why this is #if 0 */
    1.88 +  pam_close_session (hdl,NIL);	/* close session [uw]tmp */
    1.89 +#endif
    1.90 +  pam_setcred (hdl,PAM_DELETE_CRED);
    1.91 +  pam_end (hdl,PAM_SUCCESS);
    1.92 +}
    1.93 +
    1.94 +/* Server log in
    1.95 + * Accepts: user name string
    1.96 + *	    password string
    1.97 + * Returns: T if password validated, NIL otherwise
    1.98 + */
    1.99 +
   1.100 +struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[])
   1.101 +{
   1.102 +  pam_handle_t *hdl;
   1.103 +  struct pam_conv conv;
   1.104 +  struct checkpw_cred cred;
   1.105 +  char *name = cpystr (pw->pw_name);
   1.106 +  conv.conv = &checkpw_conv;
   1.107 +  conv.appdata_ptr = &cred;
   1.108 +  cred.uname = name;
   1.109 +  cred.pass = pass;
   1.110 +  if (pw = ((pam_start ((char *) mail_parameters (NIL,GET_SERVICENAME,NIL),
   1.111 +			pw->pw_name,&conv,&hdl) == PAM_SUCCESS) &&
   1.112 +	    (pam_set_item (hdl,PAM_RHOST,tcp_clientaddr ()) == PAM_SUCCESS) &&
   1.113 +	    (pam_authenticate (hdl,NIL) == PAM_SUCCESS) &&
   1.114 +	    (pam_acct_mgmt (hdl,NIL) == PAM_SUCCESS) &&
   1.115 +	    (pam_setcred (hdl,PAM_ESTABLISH_CRED) == PAM_SUCCESS)) ?
   1.116 +      getpwnam (name) : NIL) {
   1.117 +#if 0
   1.118 +    /*
   1.119 +     * Some people have reported that this causes a SEGV in strncpy() from
   1.120 +     * pam_unix.so.1
   1.121 +     */
   1.122 +    /*
   1.123 +     * This pam_open_session() call is inconsistant with how we handle other
   1.124 +     * platforms, where we don't write [uw]tmp records.  However, unlike our
   1.125 +     * code on other platforms, pam_acct_mgmt() will check those records for
   1.126 +     * inactivity and deny the authentication.
   1.127 +     */
   1.128 +    pam_open_session (hdl,NIL);	/* make sure account doesn't go inactive */
   1.129 +#endif
   1.130 +				/* arm hook to delete credentials */
   1.131 +    mail_parameters (NIL,SET_LOGOUTHOOK,(void *) checkpw_cleanup);
   1.132 +    mail_parameters (NIL,SET_LOGOUTDATA,(void *) hdl);
   1.133 +  }
   1.134 +  else checkpw_cleanup (hdl);	/* clean up */
   1.135 +  fs_give ((void **) &name);
   1.136 +				/* reset log facility in case PAM broke it */
   1.137 +  if (myServerName) openlog (myServerName,LOG_PID,syslog_facility);
   1.138 +  return pw;
   1.139 +}

UW-IMAP'd extensions by yuuji