16 #include "auto_break.h"
17 #include "auto_qmail.h"
18 #include "auto_usera.h"
22 substdio_putsflush(subfderr
,"qmail-pw2u: fatal: unable to chdir\n");
27 substdio_putsflush(subfderr
,"qmail-pw2u: fatal: out of memory\n");
32 substdio_putsflush(subfderr
,"qmail-pw2u: fatal: unable to read input\n");
37 substdio_putsflush(subfderr
,"qmail-pw2u: fatal: unable to write output\n");
42 substdio_putsflush(subfderr
,"qmail-pw2u: fatal: unable to read controls\n");
47 substdio_puts(subfderr
,"qmail-pw2u: fatal: unable to find ");
48 substdio_puts(subfderr
,auto_usera
);
49 substdio_puts(subfderr
," user\n");
50 substdio_flush(subfderr
);
53 void die_home(fn
) char *fn
;
55 substdio_puts(subfderr
,"qmail-pw2u: fatal: unable to stat ");
56 substdio_puts(subfderr
,fn
);
57 substdio_puts(subfderr
,"\n");
58 substdio_flush(subfderr
);
61 void die_user(s
,len
) char *s
; unsigned int len
;
63 substdio_puts(subfderr
,"qmail-pw2u: fatal: unable to find ");
64 substdio_put(subfderr
,s
,len
);
65 substdio_puts(subfderr
," user for subuser\n");
66 substdio_flush(subfderr
);
73 /* 2: skip if home does not exist; skip if home is not owned by user */
74 /* 1: stop if home does not exist; skip if home is not owned by user */
75 /* 0: don't worry about home */
77 int okincl
; stralloc incl
= {0}; struct constmap mapincl
;
78 int okexcl
; stralloc excl
= {0}; struct constmap mapexcl
;
79 int okmana
; stralloc mana
= {0}; struct constmap mapmana
;
81 stralloc allusers
= {0}; struct constmap mapuser
;
85 stralloc uidstr
= {0};
86 stralloc gidstr
= {0};
100 if (byte_chr(line
.s
,line
.len
,'\0') < line
.len
) return;
102 x
= line
.s
; xlen
= line
.len
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
103 if (!stralloc_copyb(&user
,x
,i
)) die_nomem();
104 if (!stralloc_0(&user
)) die_nomem();
105 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
106 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
107 if (!stralloc_copyb(&uidstr
,x
,i
)) die_nomem();
108 if (!stralloc_0(&uidstr
)) die_nomem();
109 scan_ulong(uidstr
.s
,&uid
);
110 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
111 if (!stralloc_copyb(&gidstr
,x
,i
)) die_nomem();
112 if (!stralloc_0(&gidstr
)) die_nomem();
113 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
114 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
115 if (!stralloc_copyb(&home
,x
,i
)) die_nomem();
116 if (!stralloc_0(&home
)) die_nomem();
120 for (i
= 0;i
< user
.len
;++i
)
121 if ((user
.s
[i
] >= 'A') && (user
.s
[i
] <= 'Z'))
124 if (!constmap(&mapincl
,user
.s
,user
.len
- 1))
127 if (constmap(&mapexcl
,user
.s
,user
.len
- 1))
130 if (stat(home
.s
,&st
) == -1) {
131 if (errno
!= error_noent
) die_home(home
.s
);
132 if (homestrategy
== 1) die_home(home
.s
);
135 if (st
.st_uid
!= uid
) return;
138 if (!stralloc_copys(&uugh
,":")) die_nomem();
139 if (!stralloc_cats(&uugh
,user
.s
)) die_nomem();
140 if (!stralloc_cats(&uugh
,":")) die_nomem();
141 if (!stralloc_cats(&uugh
,uidstr
.s
)) die_nomem();
142 if (!stralloc_cats(&uugh
,":")) die_nomem();
143 if (!stralloc_cats(&uugh
,gidstr
.s
)) die_nomem();
144 if (!stralloc_cats(&uugh
,":")) die_nomem();
145 if (!stralloc_cats(&uugh
,home
.s
)) die_nomem();
146 if (!stralloc_cats(&uugh
,":")) die_nomem();
148 /* XXX: avoid recording in allusers unless sub actually needs it */
149 if (!stralloc_cats(&allusers
,user
.s
)) die_nomem();
150 if (!stralloc_cats(&allusers
,":")) die_nomem();
151 if (!stralloc_catb(&allusers
,uugh
.s
,uugh
.len
)) die_nomem();
152 if (!stralloc_0(&allusers
)) die_nomem();
154 if (str_equal(user
.s
,auto_usera
)) {
155 if (substdio_puts(subfdout
,"+") == -1) die_write();
156 if (substdio_put(subfdout
,uugh
.s
,uugh
.len
) == -1) die_write();
157 if (substdio_puts(subfdout
,"-::\n") == -1) die_write();
163 mailnames
= constmap(&mapmana
,user
.s
,user
.len
- 1);
168 while (*mailnames
== ':') ++mailnames
;
169 if (!*mailnames
) break;
171 i
= str_chr(mailnames
,':');
173 if (substdio_puts(subfdout
,"=") == -1) die_write();
174 if (substdio_put(subfdout
,mailnames
,i
) == -1) die_write();
175 if (substdio_put(subfdout
,uugh
.s
,uugh
.len
) == -1) die_write();
176 if (substdio_puts(subfdout
,"::\n") == -1) die_write();
179 if (substdio_puts(subfdout
,"+") == -1) die_write();
180 if (substdio_put(subfdout
,mailnames
,i
) == -1) die_write();
181 if (substdio_put(subfdout
,auto_break
,1) == -1) die_write();
182 if (substdio_put(subfdout
,uugh
.s
,uugh
.len
) == -1) die_write();
183 if (substdio_puts(subfdout
,"-::\n") == -1) die_write();
199 x
= line
.s
; xlen
= line
.len
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
200 if (!stralloc_copyb(&sub
,x
,i
)) die_nomem();
201 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
202 uugh
= constmap(&mapuser
,x
,i
);
203 if (!uugh
) die_user(x
,i
);
204 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
206 if (substdio_puts(subfdout
,"=") == -1) die_write();
207 if (substdio_put(subfdout
,sub
.s
,sub
.len
) == -1) die_write();
208 if (substdio_puts(subfdout
,uugh
) == -1) die_write();
209 if (substdio_puts(subfdout
,"-:") == -1) die_write();
210 if (substdio_put(subfdout
,x
,i
) == -1) die_write();
211 if (substdio_puts(subfdout
,":\n") == -1) die_write();
214 if (substdio_puts(subfdout
,"+") == -1) die_write();
215 if (substdio_put(subfdout
,sub
.s
,sub
.len
) == -1) die_write();
216 if (substdio_put(subfdout
,auto_break
,1) == -1) die_write();
217 if (substdio_puts(subfdout
,uugh
) == -1) die_write();
218 if (substdio_puts(subfdout
,"-:") == -1) die_write();
219 if (substdio_put(subfdout
,x
,i
) == -1) die_write();
220 if (substdio_puts(subfdout
,"-:\n") == -1) die_write();
226 char ssbuf
[SUBSTDIO_INSIZE
];
235 while ((opt
= getopt(argc
,argv
,"ohHuUc:C")) != opteof
)
237 case 'o': homestrategy
= 2; break;
238 case 'h': homestrategy
= 1; break;
239 case 'H': homestrategy
= 0; break;
240 case 'u': flagnoupper
= 0; break;
241 case 'U': flagnoupper
= 1; break;
242 case 'c': *auto_break
= *optarg
; break;
243 case 'C': *auto_break
= 0; break;
249 if (chdir(auto_qmail
) == -1) die_chdir();
251 /* no need for control_init() */
253 okincl
= control_readfile(&incl
,"users/include",0);
254 if (okincl
== -1) die_control();
255 if (okincl
) if (!constmap_init(&mapincl
,incl
.s
,incl
.len
,0)) die_nomem();
257 okexcl
= control_readfile(&excl
,"users/exclude",0);
258 if (okexcl
== -1) die_control();
259 if (okexcl
) if (!constmap_init(&mapexcl
,excl
.s
,excl
.len
,0)) die_nomem();
261 okmana
= control_readfile(&mana
,"users/mailnames",0);
262 if (okmana
== -1) die_control();
263 if (okmana
) if (!constmap_init(&mapmana
,mana
.s
,mana
.len
,1)) die_nomem();
265 if (!stralloc_copys(&allusers
,"")) die_nomem();
268 if (getln(subfdin
,&line
,&match
,'\n') == -1) die_read();
272 if (!flagalias
) die_alias();
274 fd
= open_read("users/subusers");
276 if (errno
!= error_noent
) die_control();
279 substdio_fdbuf(&ss
,read
,fd
,ssbuf
,sizeof(ssbuf
));
281 if (!constmap_init(&mapuser
,allusers
.s
,allusers
.len
,1)) die_nomem();
284 if (getln(&ss
,&line
,&match
,'\n') == -1) die_read();
292 fd
= open_read("users/append");
294 if (errno
!= error_noent
) die_control();
297 substdio_fdbuf(&ss
,read
,fd
,ssbuf
,sizeof(ssbuf
));
299 if (getln(&ss
,&line
,&match
,'\n') == -1) die_read();
300 if (substdio_put(subfdout
,line
.s
,line
.len
) == -1) die_write();
305 if (substdio_puts(subfdout
,".\n") == -1) die_write();
306 if (substdio_flush(subfdout
) == -1) die_write();