-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpam-atheme.c
More file actions
98 lines (86 loc) · 2.31 KB
/
Copy pathpam-atheme.c
File metadata and controls
98 lines (86 loc) · 2.31 KB
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/client.h>
#include "config.h"
#define NAME "Atheme/PAM Identify Validator"
#define VERSION "1.0"
#define XMLRPC_CLEANUP xmlrpc_env_clean(&env); xmlrpc_client_cleanup();
static int evaluate_xmlrpc_auth(const char *user, const char *password)
{
xmlrpc_env env;
xmlrpc_value *res;
xmlrpc_env_init(&env);
xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION,
NULL, 0);
if (env.fault_occurred)
{
fprintf(stderr, "Atheme/PAM Error: %s (%d)\n",
env.fault_string, env.fault_code);
XMLRPC_CLEANUP;
return PAM_SERVICE_ERR;
}
res = xmlrpc_client_call(&env, NETURL, "atheme.login",
"(sss)", user, password, "::1");
if (env.fault_occurred)
{
XMLRPC_CLEANUP;
return PAM_AUTH_ERR;
}
XMLRPC_CLEANUP;
return PAM_SUCCESS;
}
/* required in a PAM module but useless for this product */
PAM_EXTERN int pam_sm_setcred( pam_handle_t *pamh, int flags, int argc, const char **argv )
{
return PAM_SUCCESS;
}
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
return PAM_SUCCESS;
}
/* expected hook, this is where custom stuff happens */
PAM_EXTERN int pam_sm_authenticate( pam_handle_t *pamh, int flags,int argc, const char **argv )
{
struct pam_conv *conv;
struct pam_message msg;
const struct pam_message *msgp;
struct pam_response *resp;
struct passwd *pwd;
const char *user;
char *crypt_password, *password;
int pam_err, retry;
/* identify user */
if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
return (pam_err);
/* get password */
pam_err = pam_get_item(pamh, PAM_CONV, (const void **)&conv);
if (pam_err != PAM_SUCCESS)
return (PAM_SYSTEM_ERR);
msg.msg_style = PAM_PROMPT_ECHO_OFF;
msg.msg = NETNAME " Password: ";
msgp = &msg;
for (retry = 0; retry < 3; ++retry)
{
resp = NULL;
pam_err = (*conv->conv)(1, &msgp, &resp, conv->appdata_ptr);
if (resp != NULL)
{
if (pam_err == PAM_SUCCESS)
password = resp->resp;
else
free(resp->resp);
free(resp);
}
if (pam_err == PAM_SUCCESS)
break;
}
if (pam_err == PAM_CONV_ERR)
return (pam_err);
if (pam_err != PAM_SUCCESS)
return (PAM_AUTH_ERR);
return evaluate_xmlrpc_auth(user, password);
}