[CalendarServer-changes] [9987] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Thu Oct 25 10:58:27 PDT 2012


Revision: 9987
          http://trac.calendarserver.org//changeset/9987
Author:   sagen at apple.com
Date:     2012-10-25 10:58:27 -0700 (Thu, 25 Oct 2012)
Log Message:
-----------
Allow the spawned db username to be specified in config (12574208)

Modified Paths:
--------------
    CalendarServer/trunk/calendarserver/tap/caldav.py
    CalendarServer/trunk/calendarserver/tap/test/test_caldav.py
    CalendarServer/trunk/calendarserver/tap/util.py
    CalendarServer/trunk/twistedcaldav/stdconfig.py
    CalendarServer/trunk/txdav/base/datastore/subpostgres.py

Modified: CalendarServer/trunk/calendarserver/tap/caldav.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/caldav.py	2012-10-25 16:46:19 UTC (rev 9986)
+++ CalendarServer/trunk/calendarserver/tap/caldav.py	2012-10-25 17:58:27 UTC (rev 9987)
@@ -32,6 +32,7 @@
 from grp import getgrnam
 import OpenSSL
 from OpenSSL.SSL import Error as SSLError
+from os import getuid, getgid
 
 from zope.interface import implements
 
@@ -1023,9 +1024,11 @@
         """
         def slaveSvcCreator(pool, store):
             return self.requestProcessingService(options, store)
-        return self.storageService(slaveSvcCreator)
 
+        uid, gid = getSystemIDs(config.UserName, config.GroupName)
+        return self.storageService(slaveSvcCreator, uid=uid, gid=gid)
 
+
     def makeService_Utility(self, options):
         """
         Create a service to be used in a command-line utility
@@ -1037,7 +1040,8 @@
         def toolServiceCreator(pool, store):
             return config.UtilityServiceClass(store)
 
-        return self.storageService(toolServiceCreator)
+        uid, gid = getSystemIDs(config.UserName, config.GroupName)
+        return self.storageService(toolServiceCreator, uid=uid, gid=gid)
 
 
     def storageService(self, createMainService, uid=None, gid=None):
@@ -2026,3 +2030,35 @@
                 return output.strip()
 
     return None
+
+def getSystemIDs(userName, groupName):
+    """
+    Return the system ID numbers corresponding to either:
+    A) the userName and groupName if non-empty, or
+    B) the real user ID and group ID of the process
+    @param userName: The name of the user to look up the ID of.  An empty
+        value indicates the real user ID of the process should be returned
+        instead.
+    @type userName: C{str}
+    @param groupName: The name of the group to look up the ID of.  An empty
+        value indicates the real group ID of the process should be returned
+        instead.
+    @type groupName: C{str}
+    """
+    if userName:
+        try:
+            uid = getpwnam(userName).pw_uid
+        except KeyError:
+           raise ConfigurationError("Invalid user name: %s" % (userName,))
+    else:
+        uid = getuid()
+
+    if groupName:
+        try:
+            gid = getgrnam(groupName).gr_gid
+        except KeyError:
+            raise ConfigurationError("Invalid group name: %s" % (groupName,))
+    else:
+        gid = getgid()
+
+    return uid, gid

Modified: CalendarServer/trunk/calendarserver/tap/test/test_caldav.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/test/test_caldav.py	2012-10-25 16:46:19 UTC (rev 9986)
+++ CalendarServer/trunk/calendarserver/tap/test/test_caldav.py	2012-10-25 17:58:27 UTC (rev 9987)
@@ -20,6 +20,7 @@
 import grp
 
 from os.path import dirname, abspath
+from collections import namedtuple
 
 from zope.interface import implements
 
@@ -46,7 +47,7 @@
 from twext.python.plistlib import writePlist #@UnresolvedImport
 from twext.internet.tcp import MaxAcceptTCPServer, MaxAcceptSSLServer
 
-from twistedcaldav.config import config, ConfigDict
+from twistedcaldav.config import config, ConfigDict, ConfigurationError
 from twistedcaldav.stdconfig import DEFAULT_CONFIG
 
 from twistedcaldav.directory.aggregate import AggregateDirectoryService
@@ -58,7 +59,7 @@
 from calendarserver.tap.caldav import (
     CalDAVOptions, CalDAVServiceMaker, CalDAVService, GroupOwnedUNIXServer,
     DelayedStartupProcessMonitor, DelayedStartupLineLogger, TwistdSlaveProcess,
-    _CONTROL_SERVICE_NAME
+    _CONTROL_SERVICE_NAME, getSystemIDs
 )
 from calendarserver.provision.root import RootResource
 from StringIO import StringIO
@@ -1197,3 +1198,73 @@
         self.assertEquals(output.count("START"), 2)
         self.assertEquals(output.count("STOP"), 2)
 
+
+class SystemIDsTests(TestCase):
+    """
+    Verifies the behavior of calendarserver.tap.caldav.getSystemIDs
+    """
+
+    def _wrappedFunction(self):
+        """
+        Return a copy of the getSystemIDs function with test implementations
+        of the ID lookup functions swapped into the namespace.
+        """
+
+        def _getpwnam(name):
+            if name == "exists":
+                Getpwnam = namedtuple("Getpwnam", ("pw_uid"))
+                return Getpwnam(42)
+            else:
+                raise KeyError(name)
+
+        def _getgrnam(name):
+            if name == "exists":
+                Getgrnam = namedtuple("Getgrnam", ("gr_gid"))
+                return Getgrnam(43)
+            else:
+                raise KeyError(name)
+
+        def _getuid():
+            return 44
+
+        def _getgid():
+            return 45
+
+        return type(getSystemIDs)(getSystemIDs.func_code,
+            {
+                "getpwnam" : _getpwnam,
+                "getgrnam" : _getgrnam,
+                "getuid" : _getuid,
+                "getgid" : _getgid,
+                "KeyError" : KeyError,
+                "ConfigurationError" : ConfigurationError,
+            }
+        )
+
+    def test_getSystemIDs_UserNameNotFound(self):
+        """
+        If userName is passed in but is not found on the system, raise a
+        ConfigurationError
+        """
+        self.assertRaises(ConfigurationError, self._wrappedFunction(),
+            "nonexistent", "exists")
+
+    def test_getSystemIDs_GroupNameNotFound(self):
+        """
+        If groupName is passed in but is not found on the system, raise a
+        ConfigurationError
+        """
+        self.assertRaises(ConfigurationError, self._wrappedFunction(),
+            "exists", "nonexistent")
+
+    def test_getSystemIDs_NamesNotSpecified(self):
+        """
+        If names are not provided, use the IDs of the process
+        """
+        self.assertEquals(self._wrappedFunction()("", ""), (44, 45))
+
+    def test_getSystemIDs_NamesSpecified(self):
+        """
+        If names are provided, use the IDs corresponding to those names
+        """
+        self.assertEquals(self._wrappedFunction()("exists", "exists"), (42, 43))

Modified: CalendarServer/trunk/calendarserver/tap/util.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/util.py	2012-10-25 16:46:19 UTC (rev 9986)
+++ CalendarServer/trunk/calendarserver/tap/util.py	2012-10-25 17:58:27 UTC (rev 9987)
@@ -130,7 +130,8 @@
         sharedBuffers=config.Postgres.SharedBuffers,
         maxConnections=config.Postgres.MaxConnections,
         options=config.Postgres.Options,
-        uid=uid, gid=gid
+        uid=uid, gid=gid,
+        spawnedDBUser=config.SpawnedDBUser
     )
 
 

Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py	2012-10-25 16:46:19 UTC (rev 9986)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py	2012-10-25 17:58:27 UTC (rev 9987)
@@ -283,6 +283,8 @@
                            # configuration key.  Will support more values in
                            # the future.
 
+    "SpawnedDBUser" : "caldav", # The username to use when DBType is empty
+
     "DSN"          : "", # Data Source Name.  Used to connect to an external
                            # database if DBType is non-empty.  Format varies
                            # depending on database type.

Modified: CalendarServer/trunk/txdav/base/datastore/subpostgres.py
===================================================================
--- CalendarServer/trunk/txdav/base/datastore/subpostgres.py	2012-10-25 16:46:19 UTC (rev 9986)
+++ CalendarServer/trunk/txdav/base/datastore/subpostgres.py	2012-10-25 17:58:27 UTC (rev 9987)
@@ -164,7 +164,8 @@
                  listenAddresses=[], sharedBuffers=30,
                  maxConnections=20, options=[],
                  testMode=False,
-                 uid=None, gid=None):
+                 uid=None, gid=None,
+                 spawnedDBUser="caldav"):
         """
         Initialize a L{PostgresService} pointed at a data store directory.
 
@@ -223,6 +224,7 @@
 
         self.uid = uid
         self.gid = gid
+        self.spawnedDBUser = spawnedDBUser
         self.schema = schema
         self.monitor = None
         self.openConnections = []
@@ -254,7 +256,9 @@
         if databaseName is None:
             databaseName = self.databaseName
 
-        if self.uid is not None:
+        if self.spawnedDBUser:
+            dsn = "%s:dbname=%s:%s" % (self.host, databaseName, self.spawnedDBUser)
+        elif self.uid is not None:
             dsn = "%s:dbname=%s:%s" % (self.host, databaseName,
                 pwd.getpwuid(self.uid).pw_name)
         else:
@@ -398,7 +402,8 @@
         workingDir = self.dataStoreDirectory.child("working")
         env = self.env = os.environ.copy()
         env.update(PGDATA=clusterDir.path,
-                   PGHOST=self.host)
+                   PGHOST=self.host,
+                   PGUSER=self.spawnedDBUser)
         initdb = which("initdb")[0]
         if self.socketDir:
             if not self.socketDir.isdir():
@@ -418,7 +423,7 @@
             dbInited = Deferred()
             reactor.spawnProcess(
                 CapturingProcessProtocol(dbInited, None),
-                initdb, [initdb, "-E", "UTF8"], env, workingDir.path,
+                initdb, [initdb, "-E", "UTF8", "-U", self.spawnedDBUser], env, workingDir.path,
                 uid=self.uid, gid=self.gid,
             )
             def doCreate(result):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20121025/5d2c465e/attachment-0001.html>


More information about the calendarserver-changes mailing list