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	"courierauthstaticlist.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 */
auth_pipe(const char * service,const char * authtype,char * authdata,int (* callback_func)(struct authinfo *,void *),void * callback_arg)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) */
auth_pipe_pre(const char * uid,const char * service,int (* callback)(struct authinfo *,void *),void * arg)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 */
auth_pipe_chgpwd(const char * service,const char * uid,const char * opwd,const char * npwd)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 
auth_pipe_idle()139 void auth_pipe_idle()
140 {
141 	/* don't need to do anything when idle */
142 }
143 
144 
auth_pipe_close()145 void auth_pipe_close()
146 {
147 	closePipe();
148 }
149 
auth_pipe_enumerate(void (* cb_func)(const char * name,uid_t uid,gid_t gid,const char * homedir,const char * maildir,const char * options,void * void_arg),void * void_arg)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 
courier_authpipe_init()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 }
189