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
);
70 char *dashcolon
= "-:";
74 /* 2: skip if home does not exist; skip if home is not owned by user */
75 /* 1: stop if home does not exist; skip if home is not owned by user */
76 /* 0: don't worry about home */
78 int okincl
; stralloc incl
= {0}; struct constmap mapincl
;
79 int okexcl
; stralloc excl
= {0}; struct constmap mapexcl
;
80 int okmana
; stralloc mana
= {0}; struct constmap mapmana
;
82 stralloc allusers
= {0}; struct constmap mapuser
;
86 stralloc uidstr
= {0};
87 stralloc gidstr
= {0};
101 if (byte_chr(line
.s
,line
.len
,'\0') < line
.len
) return;
103 x
= line
.s
; xlen
= line
.len
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
104 if (!stralloc_copyb(&user
,x
,i
)) die_nomem();
105 if (!stralloc_0(&user
)) die_nomem();
106 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
107 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
108 if (!stralloc_copyb(&uidstr
,x
,i
)) die_nomem();
109 if (!stralloc_0(&uidstr
)) die_nomem();
110 scan_ulong(uidstr
.s
,&uid
);
111 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
112 if (!stralloc_copyb(&gidstr
,x
,i
)) die_nomem();
113 if (!stralloc_0(&gidstr
)) die_nomem();
114 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
115 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
116 if (!stralloc_copyb(&home
,x
,i
)) die_nomem();
117 if (!stralloc_0(&home
)) die_nomem();
121 for (i
= 0;i
< user
.len
;++i
)
122 if ((user
.s
[i
] >= 'A') && (user
.s
[i
] <= 'Z'))
125 if (!constmap(&mapincl
,user
.s
,user
.len
- 1))
128 if (constmap(&mapexcl
,user
.s
,user
.len
- 1))
131 if (stat(home
.s
,&st
) == -1) {
132 if (errno
!= error_noent
) die_home(home
.s
);
133 if (homestrategy
== 1) die_home(home
.s
);
136 if (st
.st_uid
!= uid
) return;
139 if (!stralloc_copys(&uugh
,":")) die_nomem();
140 if (!stralloc_cats(&uugh
,user
.s
)) die_nomem();
141 if (!stralloc_cats(&uugh
,":")) die_nomem();
142 if (!stralloc_cats(&uugh
,uidstr
.s
)) die_nomem();
143 if (!stralloc_cats(&uugh
,":")) die_nomem();
144 if (!stralloc_cats(&uugh
,gidstr
.s
)) die_nomem();
145 if (!stralloc_cats(&uugh
,":")) die_nomem();
146 if (!stralloc_cats(&uugh
,home
.s
)) die_nomem();
147 if (!stralloc_cats(&uugh
,":")) die_nomem();
149 /* XXX: avoid recording in allusers unless sub actually needs it */
150 if (!stralloc_cats(&allusers
,user
.s
)) die_nomem();
151 if (!stralloc_cats(&allusers
,":")) die_nomem();
152 if (!stralloc_catb(&allusers
,uugh
.s
,uugh
.len
)) die_nomem();
153 if (!stralloc_0(&allusers
)) die_nomem();
155 if (str_equal(user
.s
,auto_usera
)) {
156 if (substdio_puts(subfdout
,"+") == -1) die_write();
157 if (substdio_put(subfdout
,uugh
.s
,uugh
.len
) == -1) die_write();
158 if (substdio_puts(subfdout
,dashcolon
) == -1) die_write();
159 if (substdio_puts(subfdout
,":\n") == -1) die_write();
165 mailnames
= constmap(&mapmana
,user
.s
,user
.len
- 1);
170 while (*mailnames
== ':') ++mailnames
;
171 if (!*mailnames
) break;
173 i
= str_chr(mailnames
,':');
175 if (substdio_puts(subfdout
,"=") == -1) die_write();
176 if (substdio_put(subfdout
,mailnames
,i
) == -1) die_write();
177 if (substdio_put(subfdout
,uugh
.s
,uugh
.len
) == -1) die_write();
178 if (substdio_puts(subfdout
,"::\n") == -1) die_write();
181 if (substdio_puts(subfdout
,"+") == -1) die_write();
182 if (substdio_put(subfdout
,mailnames
,i
) == -1) die_write();
183 if (substdio_put(subfdout
,auto_break
,1) == -1) die_write();
184 if (substdio_put(subfdout
,uugh
.s
,uugh
.len
) == -1) die_write();
185 if (substdio_puts(subfdout
,dashcolon
) == -1) die_write();
186 if (substdio_puts(subfdout
,":\n") == -1) die_write();
202 x
= line
.s
; xlen
= line
.len
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
203 if (!stralloc_copyb(&sub
,x
,i
)) die_nomem();
204 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
205 uugh
= constmap(&mapuser
,x
,i
);
206 if (!uugh
) die_user(x
,i
);
207 ++i
; x
+= i
; xlen
-= i
; i
= byte_chr(x
,xlen
,':'); if (i
== xlen
) return;
209 if (substdio_puts(subfdout
,"=") == -1) die_write();
210 if (substdio_put(subfdout
,sub
.s
,sub
.len
) == -1) die_write();
211 if (substdio_puts(subfdout
,uugh
) == -1) die_write();
212 if (substdio_puts(subfdout
,dashcolon
) == -1) die_write();
213 if (substdio_put(subfdout
,x
,i
) == -1) die_write();
214 if (substdio_puts(subfdout
,":\n") == -1) die_write();
217 if (substdio_puts(subfdout
,"+") == -1) die_write();
218 if (substdio_put(subfdout
,sub
.s
,sub
.len
) == -1) die_write();
219 if (substdio_put(subfdout
,auto_break
,1) == -1) die_write();
220 if (substdio_puts(subfdout
,uugh
) == -1) die_write();
221 if (substdio_puts(subfdout
,dashcolon
) == -1) die_write();
222 if (substdio_put(subfdout
,x
,i
) == -1) die_write();
223 if (substdio_puts(subfdout
,"-:\n") == -1) die_write();
229 char ssbuf
[SUBSTDIO_INSIZE
];
238 while ((opt
= getopt(argc
,argv
,"/ohHuUc:C")) != opteof
)
240 case '/': dashcolon
= "-/:"; break;
241 case 'o': homestrategy
= 2; break;
242 case 'h': homestrategy
= 1; break;
243 case 'H': homestrategy
= 0; break;
244 case 'u': flagnoupper
= 0; break;
245 case 'U': flagnoupper
= 1; break;
246 case 'c': *auto_break
= *optarg
; break;
247 case 'C': *auto_break
= 0; break;
253 if (chdir(auto_qmail
) == -1) die_chdir();
255 /* no need for control_init() */
257 okincl
= control_readfile(&incl
,"users/include",0);
258 if (okincl
== -1) die_control();
259 if (okincl
) if (!constmap_init(&mapincl
,incl
.s
,incl
.len
,0)) die_nomem();
261 okexcl
= control_readfile(&excl
,"users/exclude",0);
262 if (okexcl
== -1) die_control();
263 if (okexcl
) if (!constmap_init(&mapexcl
,excl
.s
,excl
.len
,0)) die_nomem();
265 okmana
= control_readfile(&mana
,"users/mailnames",0);
266 if (okmana
== -1) die_control();
267 if (okmana
) if (!constmap_init(&mapmana
,mana
.s
,mana
.len
,1)) die_nomem();
269 if (!stralloc_copys(&allusers
,"")) die_nomem();
272 if (getln(subfdin
,&line
,&match
,'\n') == -1) die_read();
276 if (!flagalias
) die_alias();
278 fd
= open_read("users/subusers");
280 if (errno
!= error_noent
) die_control();
283 substdio_fdbuf(&ss
,read
,fd
,ssbuf
,sizeof(ssbuf
));
285 if (!constmap_init(&mapuser
,allusers
.s
,allusers
.len
,1)) die_nomem();
288 if (getln(&ss
,&line
,&match
,'\n') == -1) die_read();
296 fd
= open_read("users/append");
298 if (errno
!= error_noent
) die_control();
301 substdio_fdbuf(&ss
,read
,fd
,ssbuf
,sizeof(ssbuf
));
303 if (getln(&ss
,&line
,&match
,'\n') == -1) die_read();
304 if (substdio_put(subfdout
,line
.s
,line
.len
) == -1) die_write();
309 if (substdio_puts(subfdout
,".\n") == -1) die_write();
310 if (substdio_flush(subfdout
) == -1) die_write();