1 /* ========================================================================
2 * Copyright 1988-2006 University of Washington
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
11 * ========================================================================
15 * Program: Pluggable Authentication Modules login services, buggy systems
16 * (use this instead of ckp_pam.c on Solaris)
18 * Author: Mark Crispin
19 * Networks and Distributed Computing
20 * Computing & Communications
21 * University of Washington
22 * Administration Building, AG-44
24 * Internet: MRC@CAC.Washington.EDU
27 * Last Edited: 31 August 2006
31 #include <security/pam_appl.h>
33 static char *pam_uname
; /* user name */
34 static char *pam_pass
; /* password */
36 /* PAM conversation function
37 * Accepts: number of messages
39 * pointer to response return
41 * Returns: PAM_SUCCESS if OK, response vector filled in, else PAM_CONV_ERR
44 static int checkpw_conv (int num_msg
,const struct pam_message
**msg
,
45 struct pam_response
**resp
,void *appdata_ptr
)
48 struct pam_response
*reply
= fs_get (sizeof (struct pam_response
) * num_msg
);
49 for (i
= 0; i
< num_msg
; i
++) switch (msg
[i
]->msg_style
) {
50 case PAM_PROMPT_ECHO_ON
: /* assume want user name */
51 reply
[i
].resp_retcode
= PAM_SUCCESS
;
52 reply
[i
].resp
= cpystr (pam_uname
);
54 case PAM_PROMPT_ECHO_OFF
: /* assume want password */
55 reply
[i
].resp_retcode
= PAM_SUCCESS
;
56 reply
[i
].resp
= cpystr (pam_pass
);
60 reply
[i
].resp_retcode
= PAM_SUCCESS
;
63 default: /* unknown message style */
64 fs_give ((void **) &reply
);
76 static void checkpw_cleanup (pam_handle_t
*hdl
)
78 #if 0 /* see checkpw() for why this is #if 0 */
79 pam_close_session (hdl
,NIL
); /* close session [uw]tmp */
81 pam_setcred (hdl
,PAM_DELETE_CRED
);
82 pam_end (hdl
,PAM_SUCCESS
);
86 * Accepts: user name string
88 * Returns: T if password validated, NIL otherwise
91 struct passwd
*checkpw (struct passwd
*pw
,char *pass
,int argc
,char *argv
[])
95 char *name
= cpystr (pw
->pw_name
);
96 conv
.conv
= &checkpw_conv
;
97 pam_uname
= pw
->pw_name
;
99 if (pw
= ((pam_start ((char *) mail_parameters (NIL
,GET_SERVICENAME
,NIL
),
100 pw
->pw_name
,&conv
,&hdl
) == PAM_SUCCESS
) &&
101 (pam_set_item (hdl
,PAM_RHOST
,tcp_clientaddr ()) == PAM_SUCCESS
) &&
102 (pam_authenticate (hdl
,NIL
) == PAM_SUCCESS
) &&
103 (pam_acct_mgmt (hdl
,NIL
) == PAM_SUCCESS
) &&
104 (pam_setcred (hdl
,PAM_ESTABLISH_CRED
) == PAM_SUCCESS
)) ?
105 getpwnam (name
) : NIL
) {
108 * Some people have reported that this causes a SEGV in strncpy() from
112 * This pam_open_session() call is inconsistant with how we handle other
113 * platforms, where we don't write [uw]tmp records. However, unlike our
114 * code on other platforms, pam_acct_mgmt() will check those records for
115 * inactivity and deny the authentication.
117 pam_open_session (hdl
,NIL
); /* make sure account doesn't go inactive */
119 /* arm hook to delete credentials */
120 mail_parameters (NIL
,SET_LOGOUTHOOK
,(void *) checkpw_cleanup
);
121 mail_parameters (NIL
,SET_LOGOUTDATA
,(void *) hdl
);
123 else checkpw_cleanup (hdl
); /* clean up */
124 fs_give ((void **) &name
);
125 /* reset log facility in case PAM broke it */
126 if (myServerName
) openlog (myServerName
,LOG_PID
,syslog_facility
);