4 * system-level password checking for host auth mode
5 * by Nathan Bryant, March 1999
6 * updated by Trey van Riper, June 2005
10 #if defined(__linux) || defined(__sun) /* needed for crypt(): */
12 #define _XOPEN_SOURCE_EXTENDED 1
19 #include <sys/types.h>
29 #include <security/pam_appl.h>
32 * struct appdata: passed to the conversation function
42 * conv(): the PAM conversation function. this assumes that a
43 * PAM_PROMPT_ECHO_ON is asking for a username, and a PAM_PROMPT_ECHO_OFF is
44 * asking for a password. esoteric authentication modules will fail with this
45 * code, but we can't really support them with the existing client protocol
46 * anyway. the failure mode should be to deny access, in any case.
49 static int conv(int num_msg
, const struct pam_message
**msg
,
50 struct pam_response
**resp
, void *appdata_ptr
)
52 struct pam_response
*temp_resp
;
53 struct appdata
*data
= appdata_ptr
;
55 if ((temp_resp
= malloc(sizeof(struct pam_response
[num_msg
]))) == NULL
)
60 switch ((*msg
)[num_msg
].msg_style
)
62 case PAM_PROMPT_ECHO_ON
:
63 temp_resp
[num_msg
].resp
= strdup(data
->name
);
65 case PAM_PROMPT_ECHO_OFF
:
66 temp_resp
[num_msg
].resp
= strdup(data
->pw
);
69 temp_resp
[num_msg
].resp
= NULL
;
71 temp_resp
[num_msg
].resp_retcode
= 0;
77 #endif /* HAVE_PAM_START */
81 * check that `pass' is the correct password for `uid'
82 * returns zero if no, nonzero if yes
85 int validate_password(uid_t uid
, const char *pass
)
102 flags
= 0; /* silences compiler warning */
104 #ifdef PAM_DATA_SILENT
105 flags
= ( flags
| PAM_DATA_SILENT
) ;
106 #endif /* PAM_DATA_SILENT */
107 if ((pw
= getpwuid(uid
)) == NULL
) {
111 #ifdef HAVE_PAM_START
113 pc
.appdata_ptr
= &data
;
114 data
.name
= pw
->pw_name
;
116 if (pam_start("citadel", pw
->pw_name
, &pc
, &ph
) != PAM_SUCCESS
)
119 if ((i
= pam_authenticate(ph
, flags
)) == PAM_SUCCESS
)
120 if ((i
= pam_acct_mgmt(ph
, flags
)) == PAM_SUCCESS
)
123 pam_end(ph
, i
| flags
);
125 crypted_pwd
= pw
->pw_passwd
;
128 if ((sp
= getspnam(pw
->pw_name
)) != NULL
)
129 crypted_pwd
= sp
->sp_pwdp
;
132 if (!strcmp(crypt(pass
, crypted_pwd
), crypted_pwd
))
134 #endif /* HAVE_PAM_START */