s/qmail 4.2.29a
Next generation secure email transport
Loading...
Searching...
No Matches
qmail-pw2u.c
Go to the documentation of this file.
1#include <unistd.h>
2#include <sys/types.h>
3#include <sys/stat.h>
4#include "buffer.h"
5#include "getoptb.h"
6#include "control.h"
7#include "constmap.h"
8#include "stralloc.h"
9#include "fmt.h"
10#include "str.h"
11#include "scan.h"
12#include "open.h"
13#include "logmsg.h"
14#include "exit.h"
15#include "getln.h"
16#include "byte.h"
17#include "auto_break.h"
18#include "auto_qmail.h"
19#include "auto_usera.h"
20
21#define WHO "qmail-pw2u"
22
24{
25 buffer_putsflush(buffer_2,"qmail-pw2u: fatal: unable to chdir\n");
26 _exit(111);
27}
28
30{
31 buffer_putsflush(buffer_2,"qmail-pw2u: fatal: out of memory\n");
32 _exit(111);
33}
34
36{
37 buffer_putsflush(buffer_2,"qmail-pw2u: fatal: unable to read input\n");
38 _exit(111);
39}
40
42{
43 buffer_putsflush(buffer_2,"qmail-pw2u: fatal: unable to write output\n");
44 _exit(111);
45}
46
48{
49 buffer_putsflush(buffer_2,"qmail-pw2u: fatal: unable to read controls\n");
50 _exit(111);
51}
52
54{
55 buffer_puts(buffer_2,"qmail-pw2u: fatal: unable to find ");
56 buffer_puts(buffer_2,auto_usera);
57 buffer_puts(buffer_2," user\n");
58 buffer_flush(buffer_2);
59 _exit(111);
60}
61
62void die_home(char *fn)
63{
64 buffer_puts(buffer_2,"qmail-pw2u: fatal: unable to stat ");
65 buffer_puts(buffer_2,fn);
66 buffer_puts(buffer_2,"\n");
67 buffer_flush(buffer_2);
68 _exit(111);
69}
70
71void die_user(char *s,unsigned int len)
72{
73 buffer_puts(buffer_2,"qmail-pw2u: fatal: unable to find ");
74 buffer_put(buffer_2,s,len);
75 buffer_puts(buffer_2," user for subuser\n");
76 buffer_flush(buffer_2);
77 _exit(111);
78}
79
80char *dashcolon = "-:";
81int flagalias = 0;
84/* 2: skip if home does not exist; skip if home is not owned by user */
85/* 1: stop if home does not exist; skip if home is not owned by user */
86/* 0: don't worry about home */
87
88int okincl; stralloc incl = {0}; struct constmap mapincl;
89int okexcl; stralloc excl = {0}; struct constmap mapexcl;
90int okmana; stralloc mana = {0}; struct constmap mapmana;
91
92stralloc allusers = {0}; struct constmap mapuser;
93
94stralloc uugh = {0};
95stralloc user = {0};
96stralloc uidstr = {0};
97stralloc gidstr = {0};
98stralloc home = {0};
99unsigned long uid;
100
101stralloc line = {0};
102
104{
105 struct stat st;
106 int i;
107 char *mailnames;
108 char *x;
109 unsigned int xlen;
110
111 if (byte_chr(line.s,line.len,'\0') < line.len) return;
112
113 x = line.s; xlen = line.len; i = byte_chr(x,xlen,':'); if (i == xlen) return;
114 if (!stralloc_copyb(&user,x,i)) die_nomem();
115 if (!stralloc_0(&user)) die_nomem();
116 ++i; x += i; xlen -= i; i = byte_chr(x,xlen,':'); if (i == xlen) return;
117 ++i; x += i; xlen -= i; i = byte_chr(x,xlen,':'); if (i == xlen) return;
118 if (!stralloc_copyb(&uidstr,x,i)) die_nomem();
119 if (!stralloc_0(&uidstr)) die_nomem();
120 scan_ulong(uidstr.s,&uid);
121 ++i; x += i; xlen -= i; i = byte_chr(x,xlen,':'); if (i == xlen) return;
122 if (!stralloc_copyb(&gidstr,x,i)) die_nomem();
123 if (!stralloc_0(&gidstr)) die_nomem();
124 ++i; x += i; xlen -= i; i = byte_chr(x,xlen,':'); if (i == xlen) return;
125 ++i; x += i; xlen -= i; i = byte_chr(x,xlen,':'); if (i == xlen) return;
126 if (!stralloc_copyb(&home,x,i)) die_nomem();
127 if (!stralloc_0(&home)) die_nomem();
128
129 if (!uid) return;
130 if (flagnoupper)
131 for (i = 0; i < user.len; ++i)
132 if ((user.s[i] >= 'A') && (user.s[i] <= 'Z'))
133 return;
134 if (okincl)
135 if (!constmap(&mapincl,user.s,user.len - 1))
136 return;
137 if (okexcl)
138 if (constmap(&mapexcl,user.s,user.len - 1))
139 return;
140 if (homestrategy) {
141 if (stat(home.s,&st) == -1) {
142 if (errno != ENOENT) die_home(home.s);
143 if (homestrategy == 1) die_home(home.s);
144 return;
145 }
146 if (st.st_uid != uid) return;
147 }
148
149 if (!stralloc_copys(&uugh,":")) die_nomem();
150 if (!stralloc_cats(&uugh,user.s)) die_nomem();
151 if (!stralloc_cats(&uugh,":")) die_nomem();
152 if (!stralloc_cats(&uugh,uidstr.s)) die_nomem();
153 if (!stralloc_cats(&uugh,":")) die_nomem();
154 if (!stralloc_cats(&uugh,gidstr.s)) die_nomem();
155 if (!stralloc_cats(&uugh,":")) die_nomem();
156 if (!stralloc_cats(&uugh,home.s)) die_nomem();
157 if (!stralloc_cats(&uugh,":")) die_nomem();
158
159 /* XXX: avoid recording in allusers unlein sub actually needs it */
160 if (!stralloc_cats(&allusers,user.s)) die_nomem();
161 if (!stralloc_cats(&allusers,":")) die_nomem();
162 if (!stralloc_catb(&allusers,uugh.s,uugh.len)) die_nomem();
163 if (!stralloc_0(&allusers)) die_nomem();
164
165 if (str_equal(user.s,auto_usera)) {
166 if (buffer_puts(buffer_1,"+") == -1) die_write();
167 if (buffer_put(buffer_1,uugh.s,uugh.len) == -1) die_write();
168 if (buffer_puts(buffer_1,dashcolon) == -1) die_write();
169 if (buffer_puts(buffer_1,":\n") == -1) die_write();
170 flagalias = 1;
171 }
172
173 mailnames = 0;
174 if (okmana)
175 mailnames = constmap(&mapmana,user.s,user.len - 1);
176 if (!mailnames)
177 mailnames = user.s;
178
179 for (;;) {
180 while (*mailnames == ':') ++mailnames;
181 if (!*mailnames) break;
182
183 i = str_chr(mailnames,':');
184
185 if (buffer_puts(buffer_1,"=") == -1) die_write();
186 if (buffer_put(buffer_1,mailnames,i) == -1) die_write();
187 if (buffer_put(buffer_1,uugh.s,uugh.len) == -1) die_write();
188 if (buffer_puts(buffer_1,"::\n") == -1) die_write();
189
190 if (*auto_break) {
191 if (buffer_puts(buffer_1,"+") == -1) die_write();
192 if (buffer_put(buffer_1,mailnames,i) == -1) die_write();
193 if (buffer_put(buffer_1,auto_break,1) == -1) die_write();
194 if (buffer_put(buffer_1,uugh.s,uugh.len) == -1) die_write();
195 if (buffer_puts(buffer_1,dashcolon) == -1) die_write();
196 if (buffer_puts(buffer_1,":\n") == -1) die_write();
197 }
198
199 mailnames += i;
200 }
201}
202
203stralloc sub = {0};
204
206{
207 int i;
208 char *x;
209 unsigned int xlen;
210 char *uugh;
211
212 x = line.s; xlen = line.len; i = byte_chr(x,xlen,':'); if (i == xlen) return;
213 if (!stralloc_copyb(&sub,x,i)) die_nomem();
214 ++i; x += i; xlen -= i; i = byte_chr(x,xlen,':'); if (i == xlen) return;
215 uugh = constmap(&mapuser,x,i);
216 if (!uugh) die_user(x,i);
217 ++i; x += i; xlen -= i; i = byte_chr(x,xlen,':'); if (i == xlen) return;
218
219 if (buffer_puts(buffer_1,"=") == -1) die_write();
220 if (buffer_put(buffer_1,sub.s,sub.len) == -1) die_write();
221 if (buffer_puts(buffer_1,uugh) == -1) die_write();
222 if (buffer_puts(buffer_1,dashcolon) == -1) die_write();
223 if (buffer_put(buffer_1,x,i) == -1) die_write();
224 if (buffer_puts(buffer_1,":\n") == -1) die_write();
225
226 if (*auto_break) {
227 if (buffer_puts(buffer_1,"+") == -1) die_write();
228 if (buffer_put(buffer_1,sub.s,sub.len) == -1) die_write();
229 if (buffer_put(buffer_1,auto_break,1) == -1) die_write();
230 if (buffer_puts(buffer_1,uugh) == -1) die_write();
231 if (buffer_puts(buffer_1,dashcolon) == -1) die_write();
232 if (buffer_put(buffer_1,x,i) == -1) die_write();
233 if (buffer_puts(buffer_1,"-:\n") == -1) die_write();
234 }
235}
236
237int fd;
238char inbuf[BUFFER_INSIZE];
239buffer in;
240
241int main(int argc,char **argv)
242{
243 int opt;
244 int match;
245
246 while ((opt = getopt(argc,argv,"/ohHuUc:C")) != opteof)
247 switch (opt) {
248 case '/': dashcolon = "-/:"; break;
249 case 'o': homestrategy = 2; break;
250 case 'h': homestrategy = 1; break;
251 case 'H': homestrategy = 0; break;
252 case 'u': flagnoupper = 0; break;
253 case 'U': flagnoupper = 1; break;
254 case 'c': *auto_break = *optarg; break;
255 case 'C': *auto_break = 0; break;
256 case '?':
257 default:
258 _exit(100);
259 }
260
261 if (chdir(auto_qmail) == -1) die_chdir();
262
263 /* no need for control_init() */
264
265 okincl = control_readfile(&incl,"users/include",0);
266 if (okincl == -1) die_control();
267 if (okincl) if (!constmap_init(&mapincl,incl.s,incl.len,0)) die_nomem();
268
269 okexcl = control_readfile(&excl,"users/exclude",0);
270 if (okexcl == -1) die_control();
271 if (okexcl) if (!constmap_init(&mapexcl,excl.s,excl.len,0)) die_nomem();
272
273 okmana = control_readfile(&mana,"users/mailnames",0);
274 if (okmana == -1) die_control();
275 if (okmana) if (!constmap_init(&mapmana,mana.s,mana.len,1)) die_nomem();
276
277 if (!stralloc_copys(&allusers,"")) die_nomem();
278
279 for (;;) {
280 if (getln(buffer_0,&line,&match,'\n') == -1) die_read();
281 doaccount();
282 if (!match) break;
283 }
284 if (!flagalias) die_alias();
285
286 fd = open_read("users/subusers");
287 if (fd == -1) {
288 if (errno != ENOENT) die_control();
289 }
290 else {
291 buffer_init(&in,read,fd,inbuf,sizeof(inbuf));
292
294
295 for (;;) {
296 if (getln(&in,&line,&match,'\n') == -1) die_read();
297 dosubuser();
298 if (!match) break;
299 }
300
301 close(fd);
302 }
303
304 fd = open_read("users/append");
305 if (fd == -1) {
306 if (errno != ENOENT) die_control();
307 }
308 else {
309 buffer_init(&in,read,fd,inbuf,sizeof(inbuf));
310 for (;;) {
311 if (getln(&in,&line,&match,'\n') == -1) die_read();
312 if (buffer_put(buffer_1,line.s,line.len) == -1) die_write();
313 if (!match) break;
314 }
315 }
316
317 if (buffer_puts(buffer_1,".\n") == -1) die_write();
318 if (buffer_flush(buffer_1) == -1) die_write();
319 _exit(0);
320}
char auto_break[]
char auto_qmail[]
char auto_usera[]
int main()
Definition: chkshsgr.c:6
int constmap_init(struct constmap *cm, char *s, int len, int flagcolon)
Definition: constmap.c:35
int control_readfile(stralloc *sa, char *fn, int flagme)
Definition: control.c:86
int stralloc_copys(stralloc *, char const *)
void _exit()
int match
Definition: matchup.c:195
void die_control()
Definition: qmail-pw2u.c:47
stralloc incl
Definition: qmail-pw2u.c:88
stralloc sub
Definition: qmail-pw2u.c:203
stralloc mana
Definition: qmail-pw2u.c:90
struct constmap mapuser
Definition: qmail-pw2u.c:92
void die_nomem()
Definition: qmail-pw2u.c:29
int homestrategy
Definition: qmail-pw2u.c:83
int flagnoupper
Definition: qmail-pw2u.c:82
char inbuf[BUFFER_INSIZE]
Definition: qmail-pw2u.c:238
stralloc home
Definition: qmail-pw2u.c:98
stralloc gidstr
Definition: qmail-pw2u.c:97
void die_alias()
Definition: qmail-pw2u.c:53
unsigned long uid
Definition: qmail-pw2u.c:99
void dosubuser()
Definition: qmail-pw2u.c:205
stralloc user
Definition: qmail-pw2u.c:95
int fd
Definition: qmail-pw2u.c:237
int okexcl
Definition: qmail-pw2u.c:89
void die_write()
Definition: qmail-pw2u.c:41
void doaccount()
Definition: qmail-pw2u.c:103
struct constmap mapmana
Definition: qmail-pw2u.c:90
struct constmap mapincl
Definition: qmail-pw2u.c:88
int okincl
Definition: qmail-pw2u.c:88
stralloc excl
Definition: qmail-pw2u.c:89
stralloc uugh
Definition: qmail-pw2u.c:94
void die_read()
Definition: qmail-pw2u.c:35
stralloc line
Definition: qmail-pw2u.c:101
void die_chdir()
Definition: qmail-pw2u.c:23
buffer in
Definition: qmail-pw2u.c:239
struct constmap mapexcl
Definition: qmail-pw2u.c:89
void die_user(char *s, unsigned int len)
Definition: qmail-pw2u.c:71
char * dashcolon
Definition: qmail-pw2u.c:80
int okmana
Definition: qmail-pw2u.c:90
int flagalias
Definition: qmail-pw2u.c:81
stralloc allusers
Definition: qmail-pw2u.c:92
stralloc uidstr
Definition: qmail-pw2u.c:96
stralloc fn
Definition: qmail-qmaint.c:483
void die_home()
Definition: qmail-qmqpc.c:31