d9898ee8 |
1 | /* |
2 | ** Copyright 1998 - 2005 Double Precision, Inc. See COPYING for |
3 | ** distribution information. |
4 | */ |
5 | |
6 | #if HAVE_CONFIG_H |
7 | #include "courier_auth_config.h" |
8 | #endif |
9 | #include <stdio.h> |
10 | #include <stdlib.h> |
11 | #include <ctype.h> |
12 | #include <string.h> |
13 | #include <errno.h> |
14 | #include <unistd.h> |
15 | #include "numlib/numlib.h" |
16 | |
17 | #include "courierauth.h" |
18 | #include "authstaticlist.h" |
19 | #include "courierauthdebug.h" |
20 | |
21 | #include "authpipelib.h" |
22 | #include "authpiperc.h" |
23 | |
24 | extern int _authdaemondopasswd(int wrfd, int rdfd, char *buffer, int bufsiz); |
25 | extern int _authdaemondo(int wrfd, int rdfd, const char *authreq, |
26 | int (*func)(struct authinfo *, void *), void *arg); |
27 | extern int _auth_enumerate(int wrfd, int rdfd, |
28 | void(*cb_func)(const char *name, |
29 | uid_t uid, |
30 | gid_t gid, |
31 | const char *homedir, |
32 | const char *maildir, |
33 | const char *options, |
34 | void *void_arg), |
35 | void *void_arg); |
36 | |
37 | static int disabled_flag; |
38 | |
39 | /* modelled on auth_generic() in authdaemon.c */ |
40 | int auth_pipe(const char *service, const char *authtype, char *authdata, |
41 | int (*callback_func)(struct authinfo *, void *), |
42 | void *callback_arg) |
43 | { |
44 | char tbuf[NUMBUFSIZE]; |
45 | size_t l=strlen(service)+strlen(authtype)+strlen(authdata)+2; |
46 | char *n=libmail_str_size_t(l, tbuf); |
47 | char *buf=malloc(strlen(n)+l+20); |
48 | int rdfd, wrfd, rc; |
49 | |
50 | if (!buf) |
51 | return 1; |
52 | |
53 | if (disabled_flag) |
54 | { |
55 | free(buf); |
56 | return -1; |
57 | } |
58 | |
59 | strcat(strcat(strcpy(buf, "AUTH "), n), "\n"); |
60 | strcat(strcat(buf, service), "\n"); |
61 | strcat(strcat(buf, authtype), "\n"); |
62 | strcat(buf, authdata); |
63 | |
64 | if (getPipe(&rdfd, &wrfd)) |
65 | return 1; |
66 | rc=_authdaemondo(wrfd, rdfd, buf, callback_func, callback_arg); |
67 | free(buf); |
68 | if (rc > 0) closePipe(); |
69 | return rc; |
70 | } |
71 | |
72 | |
73 | /* modelled on auth_getuserinfo() in preauthdaemon.c (but note first |
74 | * two args are reversed) */ |
75 | int auth_pipe_pre(const char *uid, const char *service, |
76 | int (*callback)(struct authinfo *, void *), |
77 | void *arg) |
78 | { |
79 | char *buf; |
80 | int rdfd, wrfd, rc; |
81 | |
82 | if (disabled_flag) |
83 | return -1; |
84 | |
85 | buf=malloc(strlen(service)+strlen(uid)+20); |
86 | if (!buf) |
87 | return 1; |
88 | |
89 | strcat(strcat(strcat(strcat(strcpy(buf, "PRE . "), service), " "), |
90 | uid), "\n"); |
91 | |
92 | if (getPipe(&rdfd, &wrfd)) |
93 | { |
94 | free(buf); |
95 | return 1; |
96 | } |
97 | rc=_authdaemondo(wrfd, rdfd, buf, callback, arg); |
98 | free(buf); |
99 | if (rc > 0) closePipe(); |
100 | return (rc); |
101 | } |
102 | |
103 | |
104 | /* modelled on auth_passwd() in authmoduser2.c */ |
105 | int auth_pipe_chgpwd(const char *service, |
106 | const char *uid, |
107 | const char *opwd, |
108 | const char *npwd) |
109 | { |
110 | char *buf; |
111 | int rdfd, wrfd, rc; |
112 | |
113 | if (disabled_flag) |
114 | return -1; |
115 | |
116 | buf=malloc(strlen(service)+strlen(uid)+strlen(opwd)+ |
117 | strlen(npwd)+20); |
118 | if (!buf) |
119 | return 1; |
120 | |
121 | sprintf(buf, "PASSWD %s\t%s\t%s\t%s\n", |
122 | service, uid, opwd, npwd); |
123 | |
124 | if (getPipe(&rdfd, &wrfd)) |
125 | { |
126 | free(buf); |
127 | return 1; |
128 | } |
129 | rc = _authdaemondopasswd(wrfd, rdfd, buf, strlen(buf)); |
130 | free(buf); |
131 | if (rc > 0) closePipe(); |
132 | return (rc); |
133 | } |
134 | |
135 | |
136 | void auth_pipe_idle() |
137 | { |
138 | /* don't need to do anything when idle */ |
139 | } |
140 | |
141 | |
142 | void auth_pipe_close() |
143 | { |
144 | closePipe(); |
145 | } |
146 | |
147 | void auth_pipe_enumerate(void(*cb_func)(const char *name, |
148 | uid_t uid, |
149 | gid_t gid, |
150 | const char *homedir, |
151 | const char *maildir, |
152 | const char *options, |
153 | void *void_arg), |
154 | void *void_arg) |
155 | { |
156 | int rdfd, wrfd, rc; |
157 | |
158 | if (disabled_flag) |
159 | return; |
160 | |
161 | if (getPipe(&rdfd, &wrfd)) |
162 | return; |
163 | rc = _auth_enumerate(wrfd, rdfd, cb_func, void_arg); |
164 | if (rc > 0) closePipe(); |
165 | } |
166 | |
167 | static struct authstaticinfo authpipe_info={ |
168 | "authpipe", |
169 | auth_pipe, |
170 | auth_pipe_pre, |
171 | auth_pipe_close, |
172 | auth_pipe_chgpwd, |
173 | auth_pipe_idle, |
174 | auth_pipe_enumerate}; |
175 | |
176 | struct authstaticinfo *courier_authpipe_init() |
177 | { |
178 | disabled_flag=access(PIPE_PROGRAM, X_OK); |
179 | if (disabled_flag) |
180 | { |
181 | DPRINTF("authpipe: disabled: failed to stat pipe program %s: %s", |
182 | PIPE_PROGRAM, strerror(errno)); |
183 | } |
184 | return &authpipe_info; |
185 | } |