rev |
line source |
yuuji@0
|
1 /* ========================================================================
|
yuuji@0
|
2 * Copyright 1988-2006 University of Washington
|
yuuji@0
|
3 *
|
yuuji@0
|
4 * Licensed under the Apache License, Version 2.0 (the "License");
|
yuuji@0
|
5 * you may not use this file except in compliance with the License.
|
yuuji@0
|
6 * You may obtain a copy of the License at
|
yuuji@0
|
7 *
|
yuuji@0
|
8 * http://www.apache.org/licenses/LICENSE-2.0
|
yuuji@0
|
9 *
|
yuuji@0
|
10 *
|
yuuji@0
|
11 * ========================================================================
|
yuuji@0
|
12 */
|
yuuji@0
|
13
|
yuuji@0
|
14 /*
|
yuuji@0
|
15 * Program: Pluggable Authentication Modules login services, buggy systems
|
yuuji@0
|
16 * (use this instead of ckp_pam.c on Solaris)
|
yuuji@0
|
17 *
|
yuuji@0
|
18 * Author: Mark Crispin
|
yuuji@0
|
19 * Networks and Distributed Computing
|
yuuji@0
|
20 * Computing & Communications
|
yuuji@0
|
21 * University of Washington
|
yuuji@0
|
22 * Administration Building, AG-44
|
yuuji@0
|
23 * Seattle, WA 98195
|
yuuji@0
|
24 * Internet: MRC@CAC.Washington.EDU
|
yuuji@0
|
25 *
|
yuuji@0
|
26 * Date: 1 August 1988
|
yuuji@0
|
27 * Last Edited: 31 August 2006
|
yuuji@0
|
28 */
|
yuuji@0
|
29
|
yuuji@0
|
30
|
yuuji@0
|
31 #include <security/pam_appl.h>
|
yuuji@0
|
32
|
yuuji@0
|
33 static char *pam_uname; /* user name */
|
yuuji@0
|
34 static char *pam_pass; /* password */
|
yuuji@0
|
35
|
yuuji@0
|
36 /* PAM conversation function
|
yuuji@0
|
37 * Accepts: number of messages
|
yuuji@0
|
38 * vector of messages
|
yuuji@0
|
39 * pointer to response return
|
yuuji@0
|
40 * application data
|
yuuji@0
|
41 * Returns: PAM_SUCCESS if OK, response vector filled in, else PAM_CONV_ERR
|
yuuji@0
|
42 */
|
yuuji@0
|
43
|
yuuji@0
|
44 static int checkpw_conv (int num_msg,const struct pam_message **msg,
|
yuuji@0
|
45 struct pam_response **resp,void *appdata_ptr)
|
yuuji@0
|
46 {
|
yuuji@0
|
47 int i;
|
yuuji@0
|
48 struct pam_response *reply = fs_get (sizeof (struct pam_response) * num_msg);
|
yuuji@0
|
49 for (i = 0; i < num_msg; i++) switch (msg[i]->msg_style) {
|
yuuji@0
|
50 case PAM_PROMPT_ECHO_ON: /* assume want user name */
|
yuuji@0
|
51 reply[i].resp_retcode = PAM_SUCCESS;
|
yuuji@0
|
52 reply[i].resp = cpystr (pam_uname);
|
yuuji@0
|
53 break;
|
yuuji@0
|
54 case PAM_PROMPT_ECHO_OFF: /* assume want password */
|
yuuji@0
|
55 reply[i].resp_retcode = PAM_SUCCESS;
|
yuuji@0
|
56 reply[i].resp = cpystr (pam_pass);
|
yuuji@0
|
57 break;
|
yuuji@0
|
58 case PAM_TEXT_INFO:
|
yuuji@0
|
59 case PAM_ERROR_MSG:
|
yuuji@0
|
60 reply[i].resp_retcode = PAM_SUCCESS;
|
yuuji@0
|
61 reply[i].resp = NULL;
|
yuuji@0
|
62 break;
|
yuuji@0
|
63 default: /* unknown message style */
|
yuuji@0
|
64 fs_give ((void **) &reply);
|
yuuji@0
|
65 return PAM_CONV_ERR;
|
yuuji@0
|
66 }
|
yuuji@0
|
67 *resp = reply;
|
yuuji@0
|
68 return PAM_SUCCESS;
|
yuuji@0
|
69 }
|
yuuji@0
|
70
|
yuuji@0
|
71
|
yuuji@0
|
72 /* PAM cleanup
|
yuuji@0
|
73 * Accepts: handle
|
yuuji@0
|
74 */
|
yuuji@0
|
75
|
yuuji@0
|
76 static void checkpw_cleanup (pam_handle_t *hdl)
|
yuuji@0
|
77 {
|
yuuji@0
|
78 #if 0 /* see checkpw() for why this is #if 0 */
|
yuuji@0
|
79 pam_close_session (hdl,NIL); /* close session [uw]tmp */
|
yuuji@0
|
80 #endif
|
yuuji@0
|
81 pam_setcred (hdl,PAM_DELETE_CRED);
|
yuuji@0
|
82 pam_end (hdl,PAM_SUCCESS);
|
yuuji@0
|
83 }
|
yuuji@0
|
84
|
yuuji@0
|
85 /* Server log in
|
yuuji@0
|
86 * Accepts: user name string
|
yuuji@0
|
87 * password string
|
yuuji@0
|
88 * Returns: T if password validated, NIL otherwise
|
yuuji@0
|
89 */
|
yuuji@0
|
90
|
yuuji@0
|
91 struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[])
|
yuuji@0
|
92 {
|
yuuji@0
|
93 pam_handle_t *hdl;
|
yuuji@0
|
94 struct pam_conv conv;
|
yuuji@0
|
95 char *name = cpystr (pw->pw_name);
|
yuuji@0
|
96 conv.conv = &checkpw_conv;
|
yuuji@0
|
97 pam_uname = pw->pw_name;
|
yuuji@0
|
98 pam_pass = pass;
|
yuuji@0
|
99 if (pw = ((pam_start ((char *) mail_parameters (NIL,GET_SERVICENAME,NIL),
|
yuuji@0
|
100 pw->pw_name,&conv,&hdl) == PAM_SUCCESS) &&
|
yuuji@0
|
101 (pam_set_item (hdl,PAM_RHOST,tcp_clientaddr ()) == PAM_SUCCESS) &&
|
yuuji@0
|
102 (pam_authenticate (hdl,NIL) == PAM_SUCCESS) &&
|
yuuji@0
|
103 (pam_acct_mgmt (hdl,NIL) == PAM_SUCCESS) &&
|
yuuji@0
|
104 (pam_setcred (hdl,PAM_ESTABLISH_CRED) == PAM_SUCCESS)) ?
|
yuuji@0
|
105 getpwnam (name) : NIL) {
|
yuuji@0
|
106 #if 0
|
yuuji@0
|
107 /*
|
yuuji@0
|
108 * Some people have reported that this causes a SEGV in strncpy() from
|
yuuji@0
|
109 * pam_unix.so.1
|
yuuji@0
|
110 */
|
yuuji@0
|
111 /*
|
yuuji@0
|
112 * This pam_open_session() call is inconsistant with how we handle other
|
yuuji@0
|
113 * platforms, where we don't write [uw]tmp records. However, unlike our
|
yuuji@0
|
114 * code on other platforms, pam_acct_mgmt() will check those records for
|
yuuji@0
|
115 * inactivity and deny the authentication.
|
yuuji@0
|
116 */
|
yuuji@0
|
117 pam_open_session (hdl,NIL); /* make sure account doesn't go inactive */
|
yuuji@0
|
118 #endif
|
yuuji@0
|
119 /* arm hook to delete credentials */
|
yuuji@0
|
120 mail_parameters (NIL,SET_LOGOUTHOOK,(void *) checkpw_cleanup);
|
yuuji@0
|
121 mail_parameters (NIL,SET_LOGOUTDATA,(void *) hdl);
|
yuuji@0
|
122 }
|
yuuji@0
|
123 else checkpw_cleanup (hdl); /* clean up */
|
yuuji@0
|
124 fs_give ((void **) &name);
|
yuuji@0
|
125 /* reset log facility in case PAM broke it */
|
yuuji@0
|
126 if (myServerName) openlog (myServerName,LOG_PID,syslog_facility);
|
yuuji@0
|
127 return pw;
|
yuuji@0
|
128 }
|