1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
#include <sys/types.h>
#include <security/pam_appl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Static variables used to communicate between the conversation function
* and the server_login function
*/
static char *PAM_username;
static char *PAM_password;
/* PAM conversation function
*/
static int PAM_conv (int num_msg,
const struct pam_message **msg,
struct pam_response **resp,
void *appdata_ptr) {
int replies = 0;
struct pam_response *reply = NULL;
#define COPY_STRING(s) (s) ? strdup(s) : NULL
reply = malloc(sizeof(struct pam_response) * num_msg);
if (!reply) return PAM_CONV_ERR;
for (replies = 0; replies < num_msg; replies++) {
switch (msg[replies]->msg_style) {
case PAM_PROMPT_ECHO_ON:
reply[replies].resp_retcode = PAM_SUCCESS;
reply[replies].resp = COPY_STRING(PAM_username);
/* PAM frees resp */
break;
case PAM_PROMPT_ECHO_OFF:
reply[replies].resp_retcode = PAM_SUCCESS;
reply[replies].resp = COPY_STRING(PAM_password);
/* PAM frees resp */
break;
case PAM_TEXT_INFO:
/* fall through */
case PAM_ERROR_MSG:
/* ignore it, but pam still wants a NULL response... */
reply[replies].resp_retcode = PAM_SUCCESS;
reply[replies].resp = NULL;
break;
default:
/* Must be an error of some sort... */
free (reply);
return PAM_CONV_ERR;
}
}
*resp = reply;
return PAM_SUCCESS;
}
static struct pam_conv PAM_conversation = {
PAM_conv,
NULL
};
/* Server log in
* Accepts: user name string
* password string
* Returns: "OK" if password validated, error message otherwise
*/
char *pwcheck(char *username, char *password)
{
pam_handle_t *pamh;
int pam_error;
/* PAM only handles authentication, not user information. */
if ( !(username && password && strlen(username) && strlen(password)) )
return "Incorrect username";
/* validate password */
PAM_password = password;
PAM_username = username;
fprintf(stderr, "checking %s\n", username);
pam_error = pam_start("cyrus", username, &PAM_conversation, &pamh);
if (pam_error == PAM_SUCCESS)
pam_error = pam_authenticate(pamh, 0);
if (pam_error == PAM_SUCCESS)
pam_error = pam_acct_mgmt(pamh, 0);
if ( pam_error == PAM_SUCCESS)
fprintf(stderr, "\tauthenticated %s\n", username);
else
fprintf(stderr, "\tfailed to authenticate %s\n", username);
if(pam_end(pamh, pam_error) != PAM_SUCCESS) {
pamh = NULL;
fprintf(stderr, "pwcheck: failed to release authenticator\n");
exit(1);
}
return ( pam_error == PAM_SUCCESS ? "OK" : "Incorrect passwd" );
}
|