Commit | Line | Data |
---|---|---|
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)) | |
8d138742 CE |
65 | { |
66 | free(buf); | |
d9898ee8 | 67 | return 1; |
8d138742 | 68 | } |
d9898ee8 | 69 | rc=_authdaemondo(wrfd, rdfd, buf, callback_func, callback_arg); |
70 | free(buf); | |
71 | if (rc > 0) closePipe(); | |
72 | return rc; | |
73 | } | |
74 | ||
75 | ||
76 | /* modelled on auth_getuserinfo() in preauthdaemon.c (but note first | |
77 | * two args are reversed) */ | |
78 | int auth_pipe_pre(const char *uid, const char *service, | |
79 | int (*callback)(struct authinfo *, void *), | |
80 | void *arg) | |
81 | { | |
82 | char *buf; | |
83 | int rdfd, wrfd, rc; | |
84 | ||
85 | if (disabled_flag) | |
86 | return -1; | |
87 | ||
88 | buf=malloc(strlen(service)+strlen(uid)+20); | |
89 | if (!buf) | |
90 | return 1; | |
91 | ||
92 | strcat(strcat(strcat(strcat(strcpy(buf, "PRE . "), service), " "), | |
93 | uid), "\n"); | |
94 | ||
95 | if (getPipe(&rdfd, &wrfd)) | |
96 | { | |
97 | free(buf); | |
98 | return 1; | |
99 | } | |
100 | rc=_authdaemondo(wrfd, rdfd, buf, callback, arg); | |
101 | free(buf); | |
102 | if (rc > 0) closePipe(); | |
103 | return (rc); | |
104 | } | |
105 | ||
106 | ||
107 | /* modelled on auth_passwd() in authmoduser2.c */ | |
108 | int auth_pipe_chgpwd(const char *service, | |
109 | const char *uid, | |
110 | const char *opwd, | |
111 | const char *npwd) | |
112 | { | |
113 | char *buf; | |
114 | int rdfd, wrfd, rc; | |
115 | ||
116 | if (disabled_flag) | |
117 | return -1; | |
118 | ||
119 | buf=malloc(strlen(service)+strlen(uid)+strlen(opwd)+ | |
120 | strlen(npwd)+20); | |
121 | if (!buf) | |
122 | return 1; | |
123 | ||
124 | sprintf(buf, "PASSWD %s\t%s\t%s\t%s\n", | |
125 | service, uid, opwd, npwd); | |
126 | ||
127 | if (getPipe(&rdfd, &wrfd)) | |
128 | { | |
129 | free(buf); | |
130 | return 1; | |
131 | } | |
132 | rc = _authdaemondopasswd(wrfd, rdfd, buf, strlen(buf)); | |
133 | free(buf); | |
134 | if (rc > 0) closePipe(); | |
135 | return (rc); | |
136 | } | |
137 | ||
138 | ||
139 | void auth_pipe_idle() | |
140 | { | |
141 | /* don't need to do anything when idle */ | |
142 | } | |
143 | ||
144 | ||
145 | void auth_pipe_close() | |
146 | { | |
147 | closePipe(); | |
148 | } | |
149 | ||
150 | void auth_pipe_enumerate(void(*cb_func)(const char *name, | |
151 | uid_t uid, | |
152 | gid_t gid, | |
153 | const char *homedir, | |
154 | const char *maildir, | |
155 | const char *options, | |
156 | void *void_arg), | |
157 | void *void_arg) | |
158 | { | |
159 | int rdfd, wrfd, rc; | |
160 | ||
161 | if (disabled_flag) | |
162 | return; | |
163 | ||
164 | if (getPipe(&rdfd, &wrfd)) | |
165 | return; | |
166 | rc = _auth_enumerate(wrfd, rdfd, cb_func, void_arg); | |
167 | if (rc > 0) closePipe(); | |
168 | } | |
169 | ||
170 | static struct authstaticinfo authpipe_info={ | |
171 | "authpipe", | |
172 | auth_pipe, | |
173 | auth_pipe_pre, | |
174 | auth_pipe_close, | |
175 | auth_pipe_chgpwd, | |
176 | auth_pipe_idle, | |
177 | auth_pipe_enumerate}; | |
178 | ||
179 | struct authstaticinfo *courier_authpipe_init() | |
180 | { | |
181 | disabled_flag=access(PIPE_PROGRAM, X_OK); | |
182 | if (disabled_flag) | |
183 | { | |
184 | DPRINTF("authpipe: disabled: failed to stat pipe program %s: %s", | |
185 | PIPE_PROGRAM, strerror(errno)); | |
186 | } | |
187 | return &authpipe_info; | |
188 | } |