Fixed for stable (1.0.3) Re: Patch for tmda-ofmipd: home script without --vdomains-path

Ben Low <[email protected]>
Newsgroups gmane.mail.spam.tmda.devel
Message-ID <[email protected]>
Hello Lloyd,

I too use a non-vpopmail virtual user setup, and also wish to avoid mucking 
about with a contrived virtualdomains file for TMDA. (BTW, tmda-ofmipd seems 
to assume the 'prepend' given in virtualdomains is a local username, which 
does not need to be true - for example, the 'prepend' could in turn be 
aliased via qmail/users/assign. e.g. refer to the example given in the 
qmail-send man page.)

I found your second, "fixed" patch seems to be reversed. It also is against 
an unstable version (includes stuf to do with pure-proxy).

I've manually decomposed your '6366-001.bin' patch to make a clean 
version against the latest stable release (1.0.3), and include it here 
in case it's useful to someone.

Rgds,
Ben

--- /usr/bin/tmda-ofmipd	2003-11-14 06:28:08.000000000 +1100
+++ /usr/local/bin/tmda-ofmipd	2006-01-27 15:47:24.000000000 +1100
@@ -159,6 +159,27 @@
         domains using the VMailMgr add-on.  It implies that you will also set
         the --vhome-script parameter above.
 
+    -H <script>
+    --home-script <script>
+        Similar --vhome-script, above, but it is meant to be used with
+        a non-VMailMgr environment, with no virtual domains file.
+
+        This script takes two arguments, the user name and the domain,
+        on its command line.  It must write the following information
+        to stdout, each item separated by white space:
+
+          homedir uid gid groups ...
+
+        where homedir is the email user's home directory
+              uid     is the user who owns homedir
+              gid     is the group who owns homedir
+              groups  is a list of groups to which uid belongs;
+                      gid is duplicated in this list of groups
+
+        NOTE: This option is only used when you have an installation
+        that's NOT structured like qmail with VMailMgr.  You cannot
+        use --vhome-script or --vdomains-path with this option.
+
     -t <script>
     --throttle-script <script>
         Full pathname of a script which can meter how much mail any user sends.
@@ -211,7 +232,9 @@
                      }
 connections = 20
 vhomescript = None
+homescript = None
 vdomainspath = '/var/qmail/control/virtualdomains'
+vdomainspathspecified = None
 throttlescript = None
 
 if os.getuid() == 0:
@@ -275,6 +298,7 @@
                                                      'foreground',
                                                      'background',
                                                      'vhome-script=',
+                                                     'home-script=',
                                                      'vdomains-path=',
                                                      'throttle-script='])
 except getopt.error, msg:
@@ -341,13 +365,20 @@
         connections = arg
     elif opt in ('-S', '--vhome-script'):
         vhomescript = arg
+    elif opt in ('-H', '--home-script'):
+        homescript = arg
     elif opt in ('-v', '--vdomains-path'):
+        vdomainspathspecified = True
         vdomainspath = arg
     elif opt in ('-t', '--throttle-script'):
         throttlescript = arg
 
-if vhomescript and configdir:
-    msg = "WARNING: --vhome-script and --config-dir are incompatible." + \
+if (vhomescript or vdomainspathspecified) and homescript:
+    raise ValueError, \
+      '--home-script is not compatible with --vhome-script or --vdomains-path.'
+
+if configdir and (vhomescript or homescript):
+    msg = "WARNING: --[v]home-script and --config-dir are incompatible." + \
           "         Ignoring --config-dir."
     configdir = None
     warning(msg, exit=0)
@@ -1164,10 +1195,32 @@
     """Using this server for outgoing smtpd, the authenticated user
     will have his mail tagged using his TMDA config file."""
     def process_message(self, peer, mailfrom, rcpttos, data, auth_username):
+        if homescript:
+            userinfo = auth_username.split('@', 1)
+            user = userinfo[0]
+            if len(userinfo) > 1:
+                domain = userinfo[1]
+            else:
+                domain = ''
+            homedir, uidstring, gidstring, groupstring = \
+              Util.getvuserhomedir(user, domain, homescript).split(' ', 3)
+            uid = int(uidstring)
+            gid = int(gidstring)
+            groups = []
+            for g in groupstring.split(' '):
+                groups += [ int(g) ]
+            print >> DEBUGSTREAM, 'user homedir: "%s"' % (homedir,)
+            # This is so "~" will work in the .tmda/* files.
+            os.environ['HOME'] = homedir
+        else:
+            gid = Util.getgid(auth_username)
+            groups = Util.getgrouplist(auth_username)
+            uid = Util.getuid(auth_username)
+            # This is so "~" will always work in the .tmda/* files.
+            os.environ['HOME'] = Util.gethomedir(auth_username)
         if configdir is None:
             # ~user/.tmda/
-            tmda_configdir = os.path.join(os.path.expanduser
-                                          ('~' + auth_username), '.tmda')
+            tmda_configdir = os.path.join(os.environ['HOME'], '.tmda')
         else:
             tmda_configdir = os.path.join(os.path.expanduser
                                           (configdir), auth_username)
@@ -1175,17 +1228,15 @@
         execdir = os.path.dirname(os.path.abspath(program))
         inject_path = os.path.join(execdir, 'tmda-inject')
         inject_cmd = [inject_path, '-c', tmda_configfile] + rcpttos
-        # This is so "~" will always work in the .tmda/* files.
-        os.environ['HOME'] = Util.gethomedir(auth_username)
         # If running as uid 0, fork the tmda-inject process, and
         # then change UID and GID to the authenticated user.
         if running_as_root:
             pid = os.fork()
             if pid == 0:
                 os.seteuid(0)
-                os.setgid(Util.getgid(auth_username))
-                os.setgroups(Util.getgrouplist(auth_username))
-                os.setuid(Util.getuid(auth_username))
+                os.setgid(gid)
+                os.setgroups(groups)
+                os.setuid(uid)
                 try:
                     Util.pipecmd(inject_cmd, data)
                 except Exception, err:
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.