Branch 'pykolab-0.6' - 4 commits - pykolab/auth pykolab/cli pykolab/imap pykolab/logger.py pykolab/plugins saslauthd/__init__.py

Jeroen van Meeuwen vanmeeuwen at kolabsys.com
Thu Feb 13 12:22:30 CET 2014


 pykolab/auth/ldap/__init__.py         |   26 ++++----
 pykolab/cli/sieve/cmd_refresh.py      |    4 -
 pykolab/imap/__init__.py              |   30 +++++++++
 pykolab/logger.py                     |  104 ++++++++++++++++++++++++++++++----
 pykolab/plugins/sievemgmt/__init__.py |    4 -
 saslauthd/__init__.py                 |   75 ++++++++++++++++++++++++
 6 files changed, 218 insertions(+), 25 deletions(-)

New commits:
commit 8a2d66c45f1de4a1c7326372a96a022eae202171
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Thu Feb 13 12:04:24 2014 +0100

    Make sure permissions on log files are OK, and saslauthd itself switches uid/gid too

diff --git a/pykolab/logger.py b/pykolab/logger.py
index 6f82d5d..10fa8a2 100644
--- a/pykolab/logger.py
+++ b/pykolab/logger.py
@@ -37,6 +37,8 @@ class Logger(logging.Logger):
     debuglevel = 0
     fork = False
     loglevel = logging.CRITICAL
+    process_username = 'kolab'
+    process_groupname = 'kolab-n'
 
     if hasattr(sys, 'argv'):
         for arg in sys.argv:
@@ -66,6 +68,26 @@ class Logger(logging.Logger):
                 else:
                     loglevel = logging.DEBUG
 
+            if '-u' == arg or '--user' == arg:
+                process_username = -1
+                continue
+
+            if arg.startswith('--user='):
+                process_username = arg.split('=')[1]
+
+            if process_username == -1:
+                process_username = arg
+
+            if '-g' == arg or '--group' == arg:
+                process_groupname = -1
+                continue
+
+            if arg.startswith('--group='):
+                process_groupname = arg.split('=')[1]
+
+            if process_groupname == -1:
+                process_groupname = arg
+
     def __init__(self, *args, **kw):
         if kw.has_key('name'):
             name = kw['name']
@@ -91,23 +113,81 @@ class Logger(logging.Logger):
 
         # Make sure (read: attempt to change) the permissions
         try:
-            (ruid, euid, suid) = os.getresuid()
-            (rgid, egid, sgid) = os.getresgid()
-        except AttributeError, errmsg:
-            ruid = os.getuid()
-            rgid = os.getgid()
-
-        if ruid == 0 or rgid == 0:
-            if os.path.isfile(self.logfile):
+            try:
+                (ruid, euid, suid) = os.getresuid()
+                (rgid, egid, sgid) = os.getresgid()
+            except AttributeError, errmsg:
+                ruid = os.getuid()
+                rgid = os.getgid()
+
+            if ruid == 0:
+                # Means we can setreuid() / setregid() / setgroups()
+                if rgid == 0:
+                    # Get group entry details
+                    try:
+                        (
+                                group_name,
+                                group_password,
+                                group_gid,
+                                group_members
+                            ) = grp.getgrnam(self.process_groupname)
+
+                    except KeyError:
+                        print >> sys.stderr, _("Group %s does not exist") % (
+                                self.process_groupname
+                            )
+
+                        sys.exit(1)
+
+                    # Set real and effective group if not the same as current.
+                    if not group_gid == rgid:
+                        self.debug(
+                                _("Switching real and effective group id to %d") % (
+                                        group_gid
+                                    ),
+                                level=8
+                            )
+
+                        os.setregid(group_gid, group_gid)
+
+                if ruid == 0:
+                    # Means we haven't switched yet.
+                    try:
+                        (
+                                user_name,
+                                user_password,
+                                user_uid,
+                                user_gid,
+                                user_gecos,
+                                user_homedir,
+                                user_shell
+                            ) = pwd.getpwnam(self.process_username)
+
+                    except KeyError:
+                        print >> sys.stderr, _("User %s does not exist") % (
+                                self.process_username
+                            )
+
+                        sys.exit(1)
+
                 try:
                     os.chown(
                             self.logfile,
-                            pwd.getpwnam('kolab')[2],
-                            grp.getgrnam('kolab-n')[2]
+                            user_uid,
+                            group_gid
                         )
                     os.chmod(self.logfile, 0660)
-                except:
-                    pass
+                except Exception, errmsg:
+                    self.error(_("Could not change permissions on %s: %r") % (self.logfile, errmsg))
+                    if self.debuglevel > 8:
+                        import traceback
+                        traceback.print_exc()
+
+        except Exception, errmsg:
+            self.error(_("Could not change permissions on %s: %r") % (self.logfile, errmsg))
+            if self.debuglevel > 8:
+                import traceback
+                traceback.print_exc()
 
         # Make sure the log file exists
         try:
diff --git a/saslauthd/__init__.py b/saslauthd/__init__.py
index 90a7413..69accce 100644
--- a/saslauthd/__init__.py
+++ b/saslauthd/__init__.py
@@ -28,7 +28,9 @@
 from optparse import OptionParser
 from ConfigParser import SafeConfigParser
 
+import grp
 import os
+import pwd
 import shutil
 import sys
 import time
@@ -107,6 +109,79 @@ class SASLAuthDaemon(object):
         exitcode = 0
 
         try:
+            try:
+                (ruid, euid, suid) = os.getresuid()
+                (rgid, egid, sgid) = os.getresgid()
+            except AttributeError, errmsg:
+                ruid = os.getuid()
+                rgid = os.getgid()
+
+            if ruid == 0:
+                # Means we can setreuid() / setregid() / setgroups()
+                if rgid == 0:
+                    # Get group entry details
+                    try:
+                        (
+                                group_name,
+                                group_password,
+                                group_gid,
+                                group_members
+                            ) = grp.getgrnam(conf.process_groupname)
+
+                    except KeyError:
+                        print >> sys.stderr, _("Group %s does not exist") % (
+                                conf.process_groupname
+                            )
+
+                        sys.exit(1)
+
+                    # Set real and effective group if not the same as current.
+                    if not group_gid == rgid:
+                        log.debug(
+                                _("Switching real and effective group id to %d") % (
+                                        group_gid
+                                    ),
+                                level=8
+                            )
+
+                        os.setregid(group_gid, group_gid)
+
+                if ruid == 0:
+                    # Means we haven't switched yet.
+                    try:
+                        (
+                                user_name,
+                                user_password,
+                                user_uid,
+                                user_gid,
+                                user_gecos,
+                                user_homedir,
+                                user_shell
+                            ) = pwd.getpwnam(conf.process_username)
+
+                    except KeyError:
+                        print >> sys.stderr, _("User %s does not exist") % (
+                                conf.process_username
+                            )
+
+                        sys.exit(1)
+
+
+                    # Set real and effective user if not the same as current.
+                    if not user_uid == ruid:
+                        log.debug(
+                                _("Switching real and effective user id to %d") % (
+                                        user_uid
+                                    ),
+                                level=8
+                            )
+
+                        os.setreuid(user_uid, user_uid)
+
+        except:
+            log.error(_("Could not change real and effective uid and/or gid"))
+
+        try:
             pid = 1
             if conf.fork_mode:
                 pid = os.fork()


commit 4aa15736969edcf354155f36d99cd53f17be66c1
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Wed Feb 12 17:06:08 2014 +0100

    Match messages without an X-Spam-Status header set, too

diff --git a/pykolab/cli/sieve/cmd_refresh.py b/pykolab/cli/sieve/cmd_refresh.py
index 6c10dfa..b610e2d 100644
--- a/pykolab/cli/sieve/cmd_refresh.py
+++ b/pykolab/cli/sieve/cmd_refresh.py
@@ -344,7 +344,9 @@ def execute(*args, **kw):
             mgmt_script.addfilter(rule_name, ['true'], forward_rules)
 
         else:
-            mgmt_script.addfilter(rule_name, [("X-Spam-Status", ":matches", "No,*")], forward_rules)
+            # NOTE: Messages with no X-Spam-Status header need to be matched
+            # too, and this does exactly that.
+            mgmt_script.addfilter(rule_name, [("not", ("X-Spam-Status", ":matches", "Yes,*"))], forward_rules)
 
     if sdf_filter:
         mgmt_script.addfilter('spam_delivery_folder', [("X-Spam-Status", ":matches", "Yes,*")], [("fileinto", "INBOX/Spam"), ("stop")])
diff --git a/pykolab/plugins/sievemgmt/__init__.py b/pykolab/plugins/sievemgmt/__init__.py
index 42297a4..ade829d 100644
--- a/pykolab/plugins/sievemgmt/__init__.py
+++ b/pykolab/plugins/sievemgmt/__init__.py
@@ -356,7 +356,9 @@ class KolabSievemgmt(object):
                 mgmt_script.addfilter(rule_name, ['true'], forward_rules)
 
             else:
-                mgmt_script.addfilter(rule_name, [("X-Spam-Status", ":matches", "No,*")], forward_rules)
+                # NOTE: Messages with no X-Spam-Status header need to be matched
+                # too, and this does exactly that.
+                mgmt_script.addfilter(rule_name, [("not", ("X-Spam-Status", ":matches", "Yes,*"))], forward_rules)
 
         if sdf_filter:
             mgmt_script.addfilter('spam_delivery_folder', [("X-Spam-Status", ":matches", "Yes,*")], [("fileinto", "INBOX/Spam"), ("stop")])


commit 455e9b73874b8f58c055e331f0db2bbba1e4ef20
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Wed Feb 12 15:38:03 2014 +0100

    Make sure a shared folder with an inbound address can be delivered mail to

diff --git a/pykolab/auth/ldap/__init__.py b/pykolab/auth/ldap/__init__.py
index e7c4dd2..ec7e9fe 100644
--- a/pykolab/auth/ldap/__init__.py
+++ b/pykolab/auth/ldap/__init__.py
@@ -1265,10 +1265,6 @@ class LDAP(pykolab.base.Base):
                     entry['kolabfoldertype']
                 )
 
-        if entry.has_key(delivery_address_attribute) and \
-                not entry[delivery_address_attribute] == None:
-            self.imap.set_acl(folder_path, 'anyone', 'p')
-
         if entry.has_key('kolabmailfolderaclentry') and \
                 not entry['kolabmailfolderaclentry'] == None:
 
@@ -1276,6 +1272,10 @@ class LDAP(pykolab.base.Base):
                     entry['kolabmailfolderaclentry']
                 )
 
+        if entry.has_key(delivery_address_attribute) and \
+                not entry[delivery_address_attribute] == None:
+            self.imap.set_acl(folder_path, 'anyone', '+p')
+
         #if server == None:
             #self.entry_set_attribute(mailserver_attribute, server)
 
@@ -1782,12 +1782,16 @@ class LDAP(pykolab.base.Base):
                     entry['kolabfoldertype']
                 )
 
-        #if entry.has_key('kolabmailfolderaclentry') and \
-                #not entry['kolabmailfolderaclentry'] == None:
+        if entry.has_key('kolabmailfolderaclentry') and \
+                not entry['kolabmailfolderaclentry'] == None:
+
+            self.imap._set_kolab_mailfolder_acls(
+                    entry['kolabmailfolderaclentry']
+                )
 
-            #self.imap._set_kolab_mailfolder_acls(
-                    #entry['kolabmailfolderaclentry']
-                #)
+        if entry.has_key(delivery_address_attribute) and \
+                not entry[delivery_address_attribute] == None:
+            self.imap.set_acl(folder_path, 'anyone', '+p')
 
         #if server == None:
             #self.entry_set_attribute(mailserver_attribute, server)
diff --git a/pykolab/imap/__init__.py b/pykolab/imap/__init__.py
index 9995292..fbe515d 100644
--- a/pykolab/imap/__init__.py
+++ b/pykolab/imap/__init__.py
@@ -328,6 +328,36 @@ class IMAP(object):
         if short_rights.has_key(acl):
             acl = short_rights[acl]
 
+        # Special treatment for '-' and '+' characters
+        if '+' in acl or '-' in acl:
+            acl_map = {
+                    'set': '',
+                    'subtract': '',
+                    'add': ''
+                }
+
+            mode = 'set'
+            for char in acl:
+                if char == '-':
+                    mode = 'subtract'
+                    continue
+                if char == '+':
+                    continue
+                    mode = 'add'
+
+                acl_map[mode] += char
+
+            current_acls = self.imap.lam(self.folder_utf7(folder))
+            for current_acl in current_acls.keys():
+                if current_acl == identifier:
+                    _acl = current_acls[current_acl]
+                    break
+
+            _acl = _acl + acl_map['set'] + acl_map['add']
+
+            _acl = [x for x in _acl.split() if x not in acl_map['subtract'].split()]
+            acl = ''.join(list(set(_acl)))
+
         self.imap.sam(self.folder_utf7(folder), identifier, acl)
 
     def set_metadata(self, folder, metadata_path, metadata_value, shared=True):


commit 0c9a2496db76e7f68a05d08b66cd88f9a109dcff
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Wed Feb 12 14:32:12 2014 +0100

    Replace get_user_attribute call with the appropriate get_entry_attribute call

diff --git a/pykolab/auth/ldap/__init__.py b/pykolab/auth/ldap/__init__.py
index 1ba0f3d..e7c4dd2 100644
--- a/pykolab/auth/ldap/__init__.py
+++ b/pykolab/auth/ldap/__init__.py
@@ -1163,7 +1163,7 @@ class LDAP(pykolab.base.Base):
         foldertype_attribute = self.config_get('sharedfolder_type_attribute')
         if not foldertype_attribute == None:
             if not entry.has_key(foldertype_attribute):
-                entry[foldertype_attribute] = self.get_user_attribute(
+                entry[foldertype_attribute] = self.get_entry_attribute(
                         entry['id'],
                         foldertype_attribute
                     )
@@ -1532,7 +1532,7 @@ class LDAP(pykolab.base.Base):
         foldertype_attribute = self.config_get('sharedfolder_type_attribute')
         if not foldertype_attribute == None:
             if not entry.has_key(foldertype_attribute):
-                entry[foldertype_attribute] = self.get_user_attribute(
+                entry[foldertype_attribute] = self.get_entry_attribute(
                         entry['id'],
                         foldertype_attribute
                     )




More information about the commits mailing list