Merge branch 'debian'
[hcoop/debian/courier-authlib.git] / authpipe.c
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 {
66 free(buf);
67 return 1;
68 }
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 }