various updates
[exim-website.git] / config.samples / C011
1 Date: Thu, 26 Nov 1998 09:39:52 +0000
2 From: David M Walker <davidw@datamgmt.com>
3
4 Thanks to Philip and others I now have my ISP style config built and
5 therefore am posting the final configuration fragments to the list in
6 case anyone else wants to do a similar thing.
7
8 Date: Mon, 26 Jul 1999 00:02:14 +0100
9 From: David M Walker <davidw@datamgmt.com>
10
11 Some time ago I posted ISP nstyle configuration C011 and continue
12 to get mails of the form:
13
14 >   But can you please explain me how do the clients get their
15 >   email if it's placed in many directories and the password
16 >   are stored in "private" passwd files. The popper is not able
17 >   to understand it. What approach do you use?
18
19 The way I approach this is described after the configuration.
20
21
22 ######################################################################
23
24 # This configuration fragment is for use with an ISP type solution
25 # Each client has their own directory that contains their own
26 # editable passwd, alias etc type files. Furthemore if they create
27 # a local user then that user can also have a a .forward file and/or
28 # a .autoreply file.
29 #
30 # Files and Directories
31 # Password file for a domain
32 #       /clients/${domain}/etc/passwd
33 # Alias file for a domain
34 #       /clients/${domain}/etc/aliases
35 # Directory where users mail for a domain is stored
36 #       /clients/${domain}/mail/
37 # Location of file with a list of domains
38 #       /clients/utils/data/domains
39
40 ######################################################################
41 #                      TRANPORTS CONFIGURATION                       #
42 ######################################################################
43
44 # This transport is used for local delivery to user mailboxes.
45
46 virtual_localdelivery:
47   driver = appendfile
48   file = /clients/${domain}/mail/${local_part}
49   user = ${lookup{$local_part}lsearch{/etc/passwd}{$value}{exim}}
50   group = mail
51   mode = 0660
52
53 # This transport is used to handly autoreplys
54
55 auto_transport:
56   driver = autoreply
57   from = $local_part@$domain 
58   to = $sender_address
59   subject = "Reply re: $header_subject:"
60   file =
61 "${extract{5}{:}{${expand:${lookup{$local_part}lsearch{/clients/${domain}/etc/passwd}{$value}}}}}/.autoreply"
62   user = exim
63       
64 # This transport is used for handling pipe addresses generated by alias
65 # or .forward files. 
66
67 address_pipe:
68   driver = pipe
69   return_output
70
71 # This transport is used for handling file addresses generated by alias
72 # or .forward files.
73
74 address_file:
75   driver = appendfile
76
77 # This transport is used for handling file addresses generated by alias
78 # or .forward files if the path ends in "/".
79
80 address_directory:
81   driver = appendfile
82   no_from_hack
83   prefix = ""
84   suffix = ""
85
86 # This transport is used for handling autoreplies generated by the
87 filtering
88 # option of the forwardfile director.
89
90 address_reply:
91   driver = autoreply
92
93 # This transport is used for delivering messages over SMTP connections.
94
95 remote_smtp:
96   driver = smtp
97   command_timeout = 1m,
98   connect_timeout = 10s
99   
100 end
101
102 ######################################################################
103 #                      DIRECTORS CONFIGURATION                       #
104 ######################################################################
105
106 # Handles .autoreply files
107
108 auto_director:
109   driver = smartuser
110   transport = auto_transport
111   require_files =
112 root:${extract{5}{:}{${expand:${lookup{$local_part}lsearch{/clients/${domain}/etc/passwd}{$value}}}}}/.autoreply
113   condition = ${if eq{$sender_address}{}{no}{yes}}
114   unseen
115
116 # Handles any .forward files
117
118 userforward:
119   driver = forwardfile
120   check_local_user = false
121   #file_directory =
122 "${extract{5}{:}{${expand:${lookup{$local_part}lsearch{/clients/${domain}/etc/passwd}{$value}}}}}"
123   #file = .forward
124   file =
125 "${extract{5}{:}{${expand:${lookup{$local_part}lsearch{/clients/${domain}/etc/passwd}{$value}}}}}/.forward"
126   user = root
127   no_verify
128   check_ancestor
129   filter
130
131 # This director matches local user mailboxes.
132
133 virtual_localuser:
134    driver = aliasfile
135    transport = virtual_localdelivery
136    domains = lsearch;/clients/utils/data/domains
137    file = /clients/${domain}/etc/passwd
138    search_type = lsearch
139
140 # This director matches anything in the aliases
141
142 virtual_alias:
143    driver = aliasfile
144    domains = lsearch;/clients/utils/data/domains
145    file = /clients/${domain}/etc/aliases
146    search_type = lsearch*
147    qualify_preserve_domain 
148
149 end
150 ######################################################################
151
152
153 Our domains each have a unique last number from their IP address
154 in the form x.y.z.222 etc. but a simple serial number would do.
155 We prefix this domain number with an 'm' because it's a bad thing 
156 to create a username that starts with a digit. The 'm' stands for
157 nothing special - originally I think it meant mail.
158
159 As a result we get a username of the form m222.dwalker
160
161 We now use the shell script below to create the user, setup
162 symbolic links from /var/spool/mail/m222.dwalker to the user's
163 account directory etc. This is either called from a web page via
164 ssl or an ssh login.
165
166 Therefore mail sent to dwalker@datamgmt.com will be accessable
167 from a pop or imap account called m222.dwalker and uniqueness
168 across multiple domains is preserved.
169
170
171 #!/bin/ksh -
172
173 PATH=${PATH}:/usr/sbin; export PATH
174
175 # General Configuration
176 export PROGNAME=`basename $0`
177 export POPGID=198
178 export SHELL=/bin/false
179 export SYSPASS=/etc/passwd
180 export SYSSHAD=/etc/shadow
181 export PREFIX=m
182
183 # Global Parameters
184 export DOMAIN=""
185 export DOMGID=""
186 export DOMPASS=""
187 export DOMROOT=""
188 export DOMUID=""
189 export DOMUSER=""
190 export HOMEDIR=""
191 export MAILBOX=""
192 export MAILLNK=""
193 export POPUSER=""
194 export STRNGTST=""
195
196 fn_check_exit()
197 {
198 ESTATUS=$1
199 if [ "${ESTATUS}" != 0 ]
200 then
201    echo "Command exited with non-zero value (${ESTATUS})"
202    exit ${ESTATUS}
203 else
204    echo "Command successful"
205 fi
206 }
207
208 fn_getdomain()
209 {
210 DOMUID=$(id -u ${USER})
211 DOMGRP=${USER}
212 . getdomain ${DOMGRP}
213
214 # Derived Variables
215 DOMROOT=/monza/clients/${DOMAIN}
216 POPUSER=${PREFIX}${DOMUID}.${DOMUSER}
217 DOMGID=${DOMUID}
218 DOMPASS=${DOMROOT}/etc/passwd
219 HOMEDIR=${DOMROOT}/users/${DOMUSER}
220 MAILBOX=${DOMROOT}/mail/${DOMUSER}
221 MAILLNK=/var/spool/mail/${POPUSER}
222 }
223
224 fn_mkpasswd()
225 {
226 STRNGTST=`grep "^${POPUSER}:" ${SYSPASS}`
227 if [ -z "${STRNGTST}" ]
228 then
229    echo "Making ${SYSPASS} entry"
230    useradd -u ${DOMUID} -g ${DOMGRP} -d ${HOMEDIR} -s ${SHELL} -m -n ${POPUSER}
231    fn_check_exit $?
232    #echo "${POPUSER}:x:${DOMUID}:${POPGID}::${HOMEDIR}:${SHELL}" >> ${SYSPASS}
233 else
234    echo "User ${POPUSER} already in ${SYSPASS}"
235 fi
236 }
237
238 fn_mkdomuser()
239 {
240 STRNGTST=`grep "^${DOMUSER}:" ${DOMPASS}`
241 if [ -z "${STRNGTST}" ]
242 then
243    echo "Making ${DOMPASS} entry"
244    echo "${DOMUSER}:x:${DOMUID}:${DOMGID}::${HOMEDIR}:" >> ${DOMPASS}
245 else
246    echo "User ${DOMUSER} already in ${DOMPASS}"
247 fi
248 }
249
250 fn_mkmaildir()
251 {
252 if [ ! -e ${HOMEDIR}/mail ]
253 then
254     echo "Making ${HOMEDIR}/mail"
255     mkdir ${HOMEDIR}/mail
256     fn_check_exit $?
257     echo "Setting permissions on ${HOMEDIR}"
258     chown ${DOMUID}:${DOMGID} ${HOMEDIR}
259     fn_check_exit $?
260 fi
261 }
262     
263 fn_creatembox()
264 {
265 if [ ! -e ${MAILBOX} ]
266 then
267    echo "Creating empty mailbox"
268    touch ${MAILBOX}
269    fn_check_exit $?
270 fi
271 echo "Setting ownership"
272 chown ${DOMUID}.mail ${MAILBOX}
273 fn_check_exit $?
274 echo "Setting permissions"
275 chmod 660 ${MAILBOX}
276 fn_check_exit $?
277 }
278
279 fn_dellink()
280 {
281 if [ -e ${MAILLNK} ]
282 then
283    if [ -L ${MAILLNK} ]
284    then
285       echo "Removing old link"
286       rm ${MAILLNK}
287       fn_check_exit $?
288    else
289       echo "${MAILLNK} is not a link - moving to .old"
290       mv ${MAILLNK} ${MAILLNK}.old
291       fn_check_exit $?
292    fi
293 fi
294 }
295
296 fn_mklink()
297 {
298 if [ -e ${MAILLNK} ]
299 then
300    if [ -L ${MAILLNK} ]
301    then
302       echo "Removing old link"
303       rm ${MAILLNK}
304       fn_check_exit $?
305    else
306       echo "File ${MAILLNK} exists moving to .old"
307       mv ${MAILLNK} ${MAILLNK}.old
308       fn_check_exit $?
309    fi
310 fi
311 echo "Creating a new link"
312 ln -s ${MAILBOX} ${MAILLNK}
313 fn_check_exit $?
314 }
315
316 fn_setpasswd()
317 {
318 echo "Set password for ${DOMUSER}"
319 passwd ${POPUSER}
320 fn_check_exit $?
321 }
322
323 fn_delpopuser()
324 {
325 fn_getdomain
326 fn_delpass
327 fn_dellink
328 echo ""
329 echo "Pop account deleted for ${POPUSER}"
330 echo "Files in the domain user and mail directories must be deleted manually"
331 echo "The entry in the domain passwd file is also redundant"
332 echo ""
333 }
334
335 fn_connect()
336 {
337    echo ""
338    echo "E-Mail Address: ${DOMUSER}@${DOMAIN}"
339    echo "Pop username:   ${POPUSER}"
340    echo "Pop password:   ********"
341    echo "Inbound mail:   mail.${DOMAIN}"
342    echo "Inbound port:   110"
343    echo "Outbound mail:  mail.${DOMAIN}"
344    echo "Outbound mail:  25"
345    echo ""
346 }
347
348 fn_addpopuser()
349 {
350 fn_getdomain
351 fn_mkpasswd
352 fn_mkmaildir
353 fn_mkdomuser
354 fn_creatembox
355 fn_mklink
356 fn_setpasswd
357 fn_connect
358 }
359
360 fn_setuserpass()
361 {
362 fn_getdomain
363 fn_setpasswd
364 fn_connect
365 }
366
367 fn_usage()
368 {
369    echo "Usage: ${PROGNAME} -a username [add a user]"
370    echo "       ${PROGNAME} -c username [change a users password]"
371    echo "       ${PROGNAME} -d username [delete a user]"
372    echo "       ${PROGNAME} -l          [lists all user]"
373    echo ""
374    echo "There is also a -n option to set the prefix to null rather"
375    echo "than m for backward compatiblity with earlier versions"
376    echo "Note: -n must proceed any other parameters"
377    exit 1
378 }
379
380 fn_delpass()
381 {
382 STRNGTST=`grep "^${POPUSER}:" ${SYSPASS}`
383 if [ -n "${STRNGTST}" ]
384 then
385 userdel ${POPUSER}
386 fn_check_exit $?
387 else
388    echo "User ${POPUSER} already deleted from ${SYSPASS}"
389 fi
390 }
391
392 fn_listpops()
393 {
394     fn_getdomain
395     echo "Username\t/etc/passwd\t/etc/shadow\tLocal Password"
396     for POPUSER in `grep "^${PREFIX}${DOMUID}\." ${SYSPASS} | cut -d: -f1 -s`
397     do
398        echo "${POPUSER}\tOK\t\t\c"
399        OKS=`grep "^${POPUSER}:" ${SYSSHAD}`
400        if [ -n "${OKS}" ]
401        then
402           echo "OK\t\t\c"
403        else
404           echo "Bad\t\t\c"
405        fi
406        DUS=`echo ${POPUSER} | cut -d"." -f2 -s`
407        OKD=`grep "^${DUS}:" ${DOMPASS}`
408        if [ -n "${OKD}" ]
409        then
410           echo "OK\t\c"
411        else
412           echo "Bad\t\c"
413        fi
414        echo ""
415     done
416 }
417
418 DONE=""
419 while getopts a:c:d:ln PARAM
420 do
421    case ${PARAM} in
422        a) DOMUSER=${OPTARG}
423           fn_addpopuser
424           DONE=TRUE
425           ;;
426        c) DOMUSER=${OPTARG}
427           fn_setuserpass
428           DONE=TRUE
429           ;;
430        d) DOMUSER=${OPTARG}
431           fn_delpopuser
432           DONE=TRUE
433           ;;
434        l) fn_listpops
435           DONE=TRUE
436           ;;
437        n) PREFIX=""
438           POPUSER=${PREFIX}${DOMUID}.${DOMUSER}
439           ;;
440        ?) fn_usage
441    esac
442 done
443 shift $(($OPTIND -1))
444
445 if [ -z "${DONE}" ]
446 then
447    fn_usage
448 fi