]> git.llucax.com Git - z.facultad/75.52/sercom.git/commitdiff
Agregar soporte para nombres de usuario/grupo .
authorLeandro Lucarella <llucax@gmail.com>
Sat, 10 Mar 2007 16:57:59 +0000 (16:57 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Sat, 10 Mar 2007 16:57:59 +0000 (16:57 +0000)
Ahora en el archivo de configuración se pueden especificar nombres de
usuario/grupo (en vez de ids) que se resuelven buscando en /etc/passwd y
/etc/groups (via módulos pwd y grp).

doc/config-examples/dev.cfg
doc/config-examples/sample-prod.cfg
doc/config-examples/test.cfg
sercom/tester.py

index 5eb0918e66df5c6a16b8b4e3675faff85c5fd468..6dfe490eabe985274e0335d15221d023f7d8d415 100644 (file)
@@ -7,10 +7,10 @@
 # SERCOM
 
 # Usuario con el cual ejecutar cuando no se necesitan privilegios
-#sercom.tester.uid = 65534 # usualmente 'nobody'
+#sercom.tester.user = 65534 # usualmente 'nobody'
 
 # Grupo con el cual ejecutar cuando no se necesitan privilegios
-#sercom.tester.gid = 65534 # usualmente 'nogroup'
+#sercom.tester.group = 65534 # usualmente 'nogroup'
 
 # Máxima cantidad de tiempo de CPU que puede estar ejecutandose el comando
 # (en segundos)
 #sercom.tester.limits.max_locks_memoria = 0
 
 # Usuario con el cual ejecutar comandos
-#sercom.tester.chroot.uid = 65534 # usualmente 'nobody'
+#sercom.tester.chroot.user = 65534 # usualmente 'nobody'
 
 # Grupo con el cual ejecutar comandos
-#sercom.tester.chroot.gid = 65534 # usualmente 'nogroup'
+#sercom.tester.chroot.group = 65534 # usualmente 'nogroup'
 
 
 # DATABASE
index 1dd6cab52df38ffd1467f7bc1153c8f9b475c10f..744dbc2391bf8585cc7ebd82b6a0398e385e9bb9 100644 (file)
 # SERCOM
 
 # Usuario con el cual ejecutar cuando no se necesitan privilegios
-#sercom.tester.uid = 65534 # usualmente 'nobody'
+#sercom.tester.user = 65534 # usualmente 'nobody'
 
 # Grupo con el cual ejecutar cuando no se necesitan privilegios
-#sercom.tester.gid = 65534 # usualmente 'nogroup'
+#sercom.tester.group = 65534 # usualmente 'nogroup'
 
 # Máxima cantidad de tiempo de CPU que puede estar ejecutandose el comando
 # (en segundos)
 #sercom.tester.limits.max_locks_memoria = 0
 
 # Usuario con el cual ejecutar comandos
-#sercom.tester.chroot.uid = 65534 # usualmente 'nobody'
+#sercom.tester.chroot.user = 65534 # usualmente 'nobody'
 
 # Grupo con el cual ejecutar comandos
-#sercom.tester.chroot.gid = 65534 # usualmente 'nogroup'
+#sercom.tester.chroot.group = 65534 # usualmente 'nogroup'
 
 
 # DATABASE
index f24867355b04b987373c02122141d202399a80eb..898bf1acaad6ab8a1c77a56ac3430abd94495dc6 100644 (file)
@@ -6,10 +6,10 @@ sqlobject.dburi = "sqlite:///:memory:"
 # SERCOM
 
 # Usuario con el cual ejecutar cuando no se necesitan privilegios
-#sercom.tester.uid = 65534 # usualmente 'nobody'
+#sercom.tester.user = 65534 # usualmente 'nobody'
 
 # Grupo con el cual ejecutar cuando no se necesitan privilegios
-#sercom.tester.gid = 65534 # usualmente 'nogroup'
+#sercom.tester.group = 65534 # usualmente 'nogroup'
 
 # Máxima cantidad de tiempo de CPU que puede estar ejecutandose el comando
 # (en segundos)
@@ -32,9 +32,9 @@ sqlobject.dburi = "sqlite:///:memory:"
 #sercom.tester.limits.max_locks_memoria = 0
 
 # Usuario con el cual ejecutar comandos
-#sercom.tester.chroot.uid = 65534 # usualmente 'nobody'
+#sercom.tester.chroot.user = 65534 # usualmente 'nobody'
 
 # Grupo con el cual ejecutar comandos
-#sercom.tester.chroot.gid = 65534 # usualmente 'nogroup'
+#sercom.tester.chroot.group = 65534 # usualmente 'nogroup'
 
 
index 05ea4b6381ce43c684c60ea79f6ac08e39ae5dbd..a77c573bf4e040fa3ff89bc2941d824cd03ca4c1 100644 (file)
@@ -9,16 +9,10 @@ from datetime import datetime
 from subprocess import Popen, PIPE, call #, check_call XXX Python 2.5
 from os.path import join
 from turbogears import config
-import os
+import os, sys, pwd, grp
 import resource as rsrc
 import logging
 
-# Ahora somos mortales
-euid = config.get('sercom.tester.uid', 65534)
-egid = config.get('sercom.tester.gid', 65534)
-os.setegid(egid)
-os.seteuid(euid)
-
 log = logging.getLogger('sercom.tester')
 
 class CalledProcessError(Exception): #{{{ Python 2.5 forward-compatibility
@@ -75,6 +69,22 @@ def unzip(bytes, dst): # {{{
             file(join(dst, f), 'w').write(zfile.read(f))
 #}}}
 
+def get_pwdgrp(unam, gnam): #{{{
+    def do(type, funcnam, funcid, name):
+        try:
+            id = funcnam(name)[2]
+        except:
+            try:
+                id = int(name)
+                name = funcid(id)[0]
+            except Exception, e:
+                log.critical(_(u'No existe el %s %s (%s)'), type, name, e)
+                sys.exit(1)
+        return (id, name)
+    return do('usuario', pwd.getpwnam, pwd.getpwuid, unam) \
+        + do('grupo', grp.getgrnam, grp.getgrgid, gnam)
+#}}}
+
 class SecureProcess(object): #{{{
     default = dict(
         max_tiempo_cpu      = 120,
@@ -84,8 +94,8 @@ class SecureProcess(object): #{{{
         max_cant_procesos   = 0,
         max_locks_memoria   = 0,
     )
-    gid = config.get('sercom.tester.chroot.gid', 65534)
-    uid = config.get('sercom.tester.chroot.uid', 65534)
+    uid = config.get('sercom.tester.chroot.user', 65534)
+    gid = config.get('sercom.tester.chroot.group', 65534)
     MB = 1048576
     # XXX probar! make de un solo archivo lleva nproc=100 y nofile=15
     def __init__(self, comando, chroot, cwd):
@@ -100,8 +110,9 @@ class SecureProcess(object): #{{{
         x2 = lambda x: (x, x)
         os.chroot(self.chroot)
         os.chdir(self.cwd)
-        os.setgid(self.gid)
-        os.setuid(self.uid)
+        (uid, unam, gid, gnam) = get_pwdgrp(self.uid, self.gid)
+        os.setgid(gid)
+        os.setuid(uid)
         rsrc.setrlimit(rsrc.RLIMIT_CPU, x2(self.max_tiempo_cpu))
         rsrc.setrlimit(rsrc.RLIMIT_AS, x2(self.max_memoria*self.MB))
         rsrc.setrlimit(rsrc.RLIMIT_FSIZE, x2(self.max_tam_archivo*self.MB)) # XXX calcular en base a archivos esperados?
@@ -109,10 +120,10 @@ class SecureProcess(object): #{{{
         rsrc.setrlimit(rsrc.RLIMIT_NPROC, x2(self.max_cant_procesos))
         rsrc.setrlimit(rsrc.RLIMIT_MEMLOCK, x2(self.max_locks_memoria))
         rsrc.setrlimit(rsrc.RLIMIT_CORE, x2(0))
-        log.debug('Proceso segurizado: chroot=%s, cwd=%s, uid=%s, gid=%s, '
-            'cpu=%s, as=%s, fsize=%s, nofile=%s, nproc=%s, memlock=%s',
-            self.chroot, self.cwd, self.uid, self.gid, self.max_tiempo_cpu,
-            self.max_memoria*self.MB, self.max_tam_archivo*self.MB,
+        log.debug('Proceso segurizado: chroot=%s, cwd=%s, user=%s(%s), '
+            'group=%s(%s), cpu=%s, as=%sMiB, fsize=%sMiB, nofile=%s, nproc=%s, '
+            'memlock=%s', self.chroot, self.cwd, unam, uid, gnam, gid,
+            self.max_tiempo_cpu, self.max_memoria, self.max_tam_archivo,
             self.max_cant_archivos, self.max_cant_procesos,
             self.max_locks_memoria)
         # Tratamos de forzar un sync para que entre al sleep del padre FIXME
@@ -127,6 +138,14 @@ class Tester(object): #{{{
         self.path = path
         self.home = home
         self.queue = queue
+        # Ahora somos mortales (oid mortales)
+        euid = config.get('sercom.tester.user', 65534)
+        egid = config.get('sercom.tester.group', 65534)
+        (self.euid, self.eunam, self.egid, self.egnam) = get_pwdgrp(euid, egid)
+        log.debug(_(u'Cambiando usuario y grupo efectivos a %s:%s (%s:%s)'),
+            self.eunam, self.egnam, self.euid, self.egid)
+        os.setegid(self.egid)
+        os.seteuid(self.euid)
 
     @property
     def build_path(self):
@@ -187,14 +206,16 @@ class Tester(object): #{{{
         rsync = ('rsync', '--stats', '--itemize-changes', '--human-readable',
             '--archive', '--acls', '--delete-during', '--force', # TODO config
             join(self.orig_chroot, ''), self.chroot)
-        log.debug(_(u'Ejecutando: %s'), ' '.join(rsync))
+        log.debug(_(u'Ejecutando como root: %s'), ' '.join(rsync))
         os.seteuid(0) # Dios! (para chroot)
         os.setegid(0)
         try:
             check_call(rsync)
         finally:
-            os.setegid(egid) # Mortal de nuevo
-            os.seteuid(euid)
+            log.debug(_(u'Cambiando usuario y grupo efectivos a %s:%s (%s:%s)'),
+                self.eunam, self.egnam, self.euid, self.egid)
+            os.setegid(self.egid) # Mortal de nuevo
+            os.seteuid(self.euid)
         unzip(entrega.archivos, self.build_path)
 
     def clean_chroot(self, entrega):
@@ -278,15 +299,19 @@ def ejecutar_comando_fuente(self, path, entrega): #{{{
     # Abro archivos para fds básicos (FIXME)
     options = dict(close_fds=True, stdin=None, stdout=None, stderr=None,
         preexec_fn=SecureProcess(self, 'var/chroot_pepe', '/home/sercom/build'))
-    log.debug(_(u'Ejecutando %s'), ' '.join(self.comando))
+    log.debug(_(u'Ejecutando como root: %s'), ' '.join(self.comando))
+    uid = os.geteuid()
+    gid = os.getegid()
     os.seteuid(0) # Dios! (para chroot)
     os.setegid(0)
     try:
         try:
             proc = Popen(self.comando, **options)
         finally:
-            os.setegid(egid) # Mortal de nuevo
-            os.seteuid(euid)
+            log.debug(_(u'Cambiando usuario y grupo efectivos a %s:%s'),
+                uid, gid)
+            os.setegid(gid) # Mortal de nuevo
+            os.seteuid(uid)
     except Exception, e: # FIXME poner en el manejo de exceptiones estandar
         if hasattr(e, 'child_traceback'):
             log.error(_(u'Error en el hijo: %s'), e.child_traceback)