s/qmail 4.2.29a
Next generation secure email transport
Loading...
Searching...
No Matches
qmail-lspawn.c
Go to the documentation of this file.
1#include <unistd.h>
2#include "fd.h"
3#include "wait.h"
4#include "prot.h"
5#include "buffer.h"
6#include "stralloc.h"
7#include "scan.h"
8#include "exit.h"
9#include "cdbread.h"
10#include "case.h"
11#include "readclose.h"
12#include "auto_qmail.h"
13#include "auto_uids.h"
14#include "qlx.h"
15#include "error.h"
16#include "open.h"
17#include "byte.h"
18
20
21void initialize(int argc,char **argv)
22{
23 aliasempty = argv[1];
24 if (!aliasempty) _exit(100);
25}
26
27int truncreport = 3000;
28
29void report(buffer *log,int wstat,char *s,int len)
30{
31 int i;
32 if (wait_crashed(wstat)) { buffer_putsflush(log,"Zqmail-lspawn: qmail-local crashed.\n"); return; }
33
34 switch (wait_exitcode(wstat)) {
35 case QLX_CDB:
36 buffer_putsflush(log,"Zqmail-lspawn: Trouble reading users/assign.cdb.\n"); return;
37 case QLX_NOMEM:
38 buffer_putsflush(log,"Zqmail-lspawn: Out of memory.\n"); return;
39 case QLX_SYS:
40 buffer_putsflush(log,"Zqmail-lspawn: Temporary failure.\n"); return;
41 case QLX_NOALIAS:
42 buffer_putsflush(log,"Zqmail-lspawn: Unable to find alias user!\n"); return;
43 case QLX_ROOT:
44 buffer_putsflush(log,"Zqmail-spawn: Not allowed to perform deliveries as root.\n"); return;
45 case QLX_USAGE:
46 buffer_putsflush(log,"Zqmail-spawn: Internal bug.\n"); return;
47 case QLX_NFS:
48 buffer_putsflush(log,"Zqmail-spawn: NFS failure in qmail-local.\n"); return;
49 case QLX_EXECHARD:
50 buffer_putsflush(log,"Dqmail-spawn: Unable to run qmail-local.\n"); return;
51 case QLX_EXECSOFT:
52 buffer_putsflush(log,"Zqmail-spawn: Unable to run qmail-local.\n"); return;
53 case QLX_EXECPW:
54 buffer_putsflush(log,"Zqmail-spawn: Unable to run qmail-getpw.\n"); return;
55 case 111: case 71: case 74: case 75:
56 buffer_put(log,"Z",1); break;
57 case 0:
58 buffer_put(log,"K",1); break;
59 case 100:
60 default:
61 buffer_put(log,"D",1); break;
62 }
63
64 for (i = 0; i < len; ++i)
65 if (!s[i]) break;
66
67 buffer_put(log,s,i);
68}
69
70stralloc lower = {0};
71stralloc nughde = {0};
72stralloc wildchars = {0};
73
74static struct cdb c;
75
76void nughde_get(char *local)
77{
78 char *(args[3]);
79 int pi[2];
80 int gpwpid;
81 int gpwstat;
82 int r;
83 int fd;
84 int flagwild;
85
87 if (!stralloc_cats(&lower,local)) _exit(QLX_NOMEM);
88 if (!stralloc_0(&lower)) _exit(QLX_NOMEM);
89 case_lowerb(lower.s,lower.len);
90
92
93 fd = open_read("users/assign.cdb");
94 if (fd == -1)
95 if (errno != ENOENT)
97
98 if (fd != -1) {
99 unsigned int i;
100
101 cdb_init(&c,fd);
102 r = cdb_find(&c,"",0);
103 if (r != 1) _exit(QLX_CDB);
104 if (!stralloc_ready(&wildchars,cdb_datalen(&c))) _exit(QLX_NOMEM);
105 wildchars.len = cdb_datalen(&c);
106 if (cdb_read(&c,wildchars.s,wildchars.len,cdb_datapos(&c)) == -1) _exit(QLX_CDB);
107
108 i = lower.len;
109 flagwild = 0;
110
111 do {
112 /* i > 0 */
113 if (!flagwild || (i == 1) || (byte_chr(wildchars.s,wildchars.len,lower.s[i - 1]) < wildchars.len)) {
114 r = cdb_find(&c,lower.s,i);
115 if (r == -1) _exit(QLX_CDB);
116 if (r == 1) {
117 if (!stralloc_ready(&nughde,cdb_datalen(&c))) _exit(QLX_NOMEM);
118 nughde.len = cdb_datalen(&c);
119 if (cdb_read(&c,nughde.s,nughde.len,cdb_datapos(&c)) == -1) _exit(QLX_CDB);
120 if (flagwild)
121 if (!stralloc_cats(&nughde,local + i - 1)) _exit(QLX_NOMEM);
122 if (!stralloc_0(&nughde)) _exit(QLX_NOMEM);
123 close(fd);
124 return;
125 }
126 }
127 --i;
128 flagwild = 1;
129 } while (i);
130
131 close(fd);
132 }
133
134 if (pipe(pi) == -1) _exit(QLX_SYS);
135
136 args[0] = "bin/qmail-getpw";
137 args[1] = local;
138 args[2] = 0;
139 switch (gpwpid = fork()) {
140 case -1:
141 _exit(QLX_SYS);
142 case 0:
143 if (prot_gid(auto_gidn) == -1) _exit(QLX_USAGE);
144 if (prot_uid(auto_uidp) == -1) _exit(QLX_USAGE);
145 close(pi[0]);
146 if (fd_move(1,pi[1]) == -1) _exit(QLX_SYS);
147 execv(*args,args);
149 }
150 close(pi[1]);
151
152 if (readclose_append(pi[0],&nughde,128) == -1) _exit(QLX_SYS);
153
154 if (wait_pid(&gpwstat,gpwpid) != -1) {
155 if (wait_crashed(gpwstat)) _exit(QLX_SYS);
156 if (wait_exitcode(gpwstat) != 0) _exit(wait_exitcode(gpwstat));
157 }
158}
159
160int spawn(int fdmess,int fdout,const char *s,char *r,const int at)
161{
162 int f;
163
164 if (!(f = fork())) {
165 char *(args[11]);
166 unsigned long u;
167 int n;
168 int uid;
169 int gid;
170 char *x;
171 unsigned int xlen;
172
173 r[at] = 0;
174 if (!r[0]) _exit(0); /* <> */
175
176 if (chdir(auto_qmail) == -1) _exit(QLX_USAGE);
177
178 nughde_get(r);
179
180 x = nughde.s;
181 xlen = nughde.len;
182
183 args[0] = "bin/qmail-local";
184 args[1] = "--";
185 args[2] = x;
186 n = byte_chr(x,xlen,0);
187 if (n++ == xlen) _exit(QLX_USAGE);
188 x += n;
189 xlen -= n;
190
191 scan_ulong(x,&u);
192 uid = u;
193 n = byte_chr(x,xlen,0);
194 if (n++ == xlen) _exit(QLX_USAGE);
195 x += n;
196 xlen -= n;
197
198 scan_ulong(x,&u);
199 gid = u;
200 n = byte_chr(x,xlen,0);
201 if (n++ == xlen) _exit(QLX_USAGE);
202 x += n;
203 xlen -= n;
204
205 args[3] = x;
206 n = byte_chr(x,xlen,0);
207 if (n++ == xlen) _exit(QLX_USAGE);
208 x += n;
209 xlen -= n;
210
211 args[4] = r;
212 args[5] = x;
213 n = byte_chr(x,xlen,0);
214 if (n++ == xlen) _exit(QLX_USAGE);
215 x += n;
216 xlen -= n;
217
218 args[6] = x;
219 n = byte_chr(x,xlen,0);
220 if (n++ == xlen) _exit(QLX_USAGE);
221 x += n;
222 xlen -= n;
223
224 args[7] = r + at + 1;
225 args[8] = s;
226 args[9] = aliasempty;
227 args[10] = 0;
228
229 if (fd_move(0,fdmess) == -1) _exit(QLX_SYS);
230 if (fd_move(1,fdout) == -1) _exit(QLX_SYS);
231 if (fd_copy(2,1) == -1) _exit(QLX_SYS);
232 if (prot_gid(gid) == -1) _exit(QLX_USAGE);
233 if (prot_uid(uid) == -1) _exit(QLX_USAGE);
234 if (!getuid()) _exit(QLX_ROOT);
235
236 execv(*args,args);
237 if (errno) _exit(QLX_EXECSOFT);
239 }
240 return f;
241}
char auto_qmail[]
int auto_uidp
int auto_gidn
int stralloc_copys(stralloc *, char const *)
void _exit()
struct cdb cdb
Definition: fastforward.c:119
ulongalloc uid
Definition: matchup.c:58
int prot_uid()
int prot_gid()
#define QLX_ROOT
Definition: qlx.h:8
#define QLX_EXECPW
Definition: qlx.h:15
#define QLX_CDB
Definition: qlx.h:11
#define QLX_NFS
Definition: qlx.h:9
#define QLX_SYS
Definition: qlx.h:12
#define QLX_EXECHARD
Definition: qlx.h:16
#define QLX_NOALIAS
Definition: qlx.h:10
#define QLX_NOMEM
Definition: qlx.h:13
#define QLX_USAGE
Definition: qlx.h:6
#define QLX_EXECSOFT
Definition: qlx.h:14
int fd
char * local
Definition: qmail-getpw.c:18
stralloc wildchars
Definition: qmail-lspawn.c:72
int truncreport
Definition: qmail-lspawn.c:27
void nughde_get(char *local)
Definition: qmail-lspawn.c:76
stralloc nughde
Definition: qmail-lspawn.c:71
char * aliasempty
Definition: qmail-lspawn.c:19
stralloc lower
Definition: qmail-lspawn.c:70
int fdout
Definition: qmail-todo.c:143
void initialize()
int spawn()
void report()