"Fossies" - the Fresh Open Source Software Archive

Member "jailkit-2.21/py/jk_init.in" (26 Aug 2019, 9901 Bytes) of package /linux/privat/jailkit-2.21.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "jk_init.in": 2.20_vs_2.21.

    1 #!/usr/bin/python
    2 #
    3 #Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014 Olivier Sessink
    4 #All rights reserved.
    5 #
    6 #Redistribution and use in source and binary forms, with or without
    7 #modification, are permitted provided that the following conditions 
    8 #are met:
    9 #  * Redistributions of source code must retain the above copyright 
   10 #    notice, this list of conditions and the following disclaimer.
   11 #  * Redistributions in binary form must reproduce the above 
   12 #    copyright notice, this list of conditions and the following 
   13 #    disclaimer in the documentation and/or other materials provided 
   14 #    with the distribution.
   15 #  * The names of its contributors may not be used to endorse or 
   16 #    promote products derived from this software without specific 
   17 #    prior written permission.
   18 #
   19 #THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   20 #"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   21 #LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
   22 #FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
   23 #COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
   24 #INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
   25 #BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
   26 #LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
   27 #CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
   28 #LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
   29 #ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
   30 #POSSIBILITY OF SUCH DAMAGE.
   31 #
   32 
   33 from __future__ import print_function
   34 
   35 import sys
   36 if sys.version_info > (3, 0):                       #Python 3
   37     from configparser import ConfigParser
   38 else:                                   #Python 2
   39     from ConfigParser import ConfigParser
   40 import os
   41 import os.path
   42 import string
   43 import getopt
   44 import shutil
   45 import stat
   46 
   47 dir_mode = 493                              #octal 755, "rwxr-xr-x"
   48 
   49 INIPREFIX='/etc/jailkit'
   50 LIBDIR='/usr/share/jailkit'
   51 sys.path.append(LIBDIR)
   52 import jk_lib
   53 
   54 class jk_init:
   55     
   56     def __init__(self):
   57         self.didfiles = []
   58         self.didsections = []
   59         self.diddevices = []
   60         self.didusers = []
   61         self.didgroups = []
   62 
   63     def logsocket(self,config,chroot):
   64         if (not os.path.exists(chroot+'/dev')):
   65             os.mkdir(chroot+'/dev')
   66         fd = open(INIPREFIX+'/jk_socketd.ini', 'r')
   67         line = fd.readline()
   68         if sys.version_info > (3, 0) and isinstance(line, bytes):                                               #Python 3
   69             line = line.decode('utf-8', 'replace')
   70         while (line):
   71             if (line[:-1] == '['+chroot+'/dev/log]'):
   72                 if (config['verbose']):
   73                     print('we already have '+chroot+'/dev/log in '+INIPREFIX+'/jk_socketd.ini')
   74                 return
   75             line = fd.readline()
   76             if sys.version_info > (3, 0) and isinstance(line, bytes):                                               #Python 3
   77                 line = line.decode('utf-8', 'replace')
   78         fd = open(INIPREFIX+'/jk_socketd.ini', 'a')
   79         fd.write('\n['+chroot+'/dev/log]\nbase=512\npeak=2048\ninterval=10\n')
   80         fd.close()
   81     
   82     def proc_mount(self,config, chroot):
   83         if (sys.platform[:5] == 'linux'):
   84             if (config['verbose']):
   85                 print('appending proc mount '+chroot+'proc to /etc/fstab')
   86             fd = open('/etc/fstab', 'a')
   87             fd.write("proc  "+chroot+"proc  proc    defaults    0   0\n")
   88             fd.close()
   89             if (config['verbose']):
   90                 print('executing mount '+chroot+'proc')
   91             os.spawnlp(os.P_WAIT, 'mount','mount', chroot+'proc')
   92         else:
   93             print('Not processing proc mount; proc mounts are Linux specific')
   94     
   95     def add_jk_socketd_entry(self,config, chroot):
   96         print('not yet implemented')
   97     
   98     def handle_cfg_section(self,config,chroot,cfg,section):
   99         if(chroot[-1] == '/'):
  100             chroot = chroot[:-1]
  101         # first create the chroot jail itself if it does not yet exist
  102         if (not os.path.exists(chroot)):
  103             print('Creating jail '+chroot)
  104             os.makedirs(chroot, mode=dir_mode)
  105             # if the parent is setuid or setgid that is not covered by the umask set above, so we remove that
  106             os.chmod(chroot, dir_mode)
  107         sections = jk_lib.config_get_option_as_list(cfg,section,'includesections')
  108         for tmp in sections:
  109             if (tmp not in self.didsections):
  110                 self.handle_cfg_section(config,chroot,cfg,tmp)
  111                 self.didsections.append(tmp)
  112         #libraries, executables, regularfiles and directories are now all handled as 'paths'
  113         paths = jk_lib.config_get_option_as_list(cfg,section,'paths')
  114         paths = paths + jk_lib.config_get_option_as_list(cfg,section,'libraries')
  115         paths = paths + jk_lib.config_get_option_as_list(cfg,section,'executables')
  116         paths = paths + jk_lib.config_get_option_as_list(cfg,section,'regularfiles')
  117         paths = paths + jk_lib.config_get_option_as_list(cfg,section,'directories')
  118         paths2 = jk_lib.find_files_in_path(paths)
  119         self.didfiles = jk_lib.copy_binaries_and_libs(chroot, paths2, config['force'], config['verbose'], 1, try_hardlink=config['hardlink'],try_glob_matching=1,handledfiles=self.didfiles)
  120         
  121         paths_w_owner = jk_lib.config_get_option_as_list(cfg,section,'paths_w_owner')
  122         if (len(paths_w_owner)>0):
  123             self.didfiles = jk_lib.copy_binaries_and_libs(chroot, paths_w_owner, config['force'], config['verbose'], check_libs=1, try_hardlink=config['hardlink'], retain_owner=1,try_glob_matching=1, handledfiles=self.didfiles)
  124         
  125         paths_w_setuid = jk_lib.config_get_option_as_list(cfg,section,'paths_w_setuid')
  126         if (len(paths_w_setuid)>0):
  127             self.didfiles = jk_lib.copy_binaries_and_libs(chroot, paths_w_setuid, config['force'], config['verbose'], check_libs=1, try_hardlink=config['hardlink'], allow_suid=1, retain_owner=1, try_glob_matching=3, handledfiles=self.didfiles)
  128         
  129         emptydirs = jk_lib.config_get_option_as_list(cfg,section,'emptydirs')
  130         for edir in emptydirs:
  131     #       print('DEBUG emptydir='+edir)
  132             jk_lib.create_parent_path(chroot,edir, config['verbose'], copy_permissions=0, allow_suid=0, copy_ownership=0)
  133         users = []
  134         groups = []
  135         tmplist = jk_lib.config_get_option_as_list(cfg,section,'users')
  136         for tmp in tmplist:
  137             if (tmp not in self.didusers):
  138                 users.append(tmp)
  139         tmplist = jk_lib.config_get_option_as_list(cfg,section,'groups')
  140         for tmp in tmplist:
  141             if (tmp not in self.didusers):
  142                 groups.append(tmp)
  143         jk_lib.init_passwd_and_group(chroot,users,groups,config['verbose'])
  144         self.didusers = self.didusers + users
  145         self.didgroups = self.didusers + groups
  146         if (cfg.has_option(section,'need_proc')):
  147             do_proc = cfg.get(section,'need_proc')
  148             if (do_proc):
  149                 self.proc_mount(config,chroot)
  150         if (cfg.has_option(section,'need_logsocket')):
  151             do_logsocket = cfg.get(section,'need_logsocket')
  152             if (do_logsocket):
  153                 self.logsocket(config,chroot)
  154         devices = jk_lib.config_get_option_as_list(cfg,section,'devices')
  155         for tmp in devices:
  156             if (tmp not in self.diddevices):
  157                 jk_lib.create_parent_path(chroot,os.path.dirname(tmp), config['verbose'], copy_permissions=0, allow_suid=0, copy_ownership=0)
  158                 jk_lib.copy_device(chroot,tmp,config['verbose'])
  159                 self.diddevices.append(tmp)
  160         
  161 
  162 def activateConfig(config, jail, args):
  163     cfg = ConfigParser()
  164     cfg.read([config['file']])
  165     start = 0
  166     if (jail == None):
  167         jail = args[0]
  168         start = 1
  169         
  170     ji = jk_init()
  171     for section in args[start:]:
  172         if (cfg.has_section(section)):
  173             ji.handle_cfg_section(config,jail,cfg,section)
  174         else:
  175             print('WARNING: section '+section+' does not exist in '+config['file'])
  176     jk_lib.gen_library_cache(jail)
  177     
  178 def usage():
  179     print('')
  180     print("Usage: "+sys.argv[0]+" [OPTIONS]")
  181     print("Usage: "+sys.argv[0]+" [OPTIONS] -j jaildir sections...")
  182     print('')
  183     print("-h --help              : this help screen")
  184     print("-c, --configfile=FILE  : specify configfile location")
  185     print('-l, --list             : list all available sections in the configfile')
  186     print('-j, --jail=             : specify the jail to use.')
  187     print('     For backwards compatibility, if no jail is specified, the first')
  188     print('     argument after the options will be used as jail')
  189     print("-v, --verbose          : show what is being done")
  190     print("-f, --force            : force overwriting of existing files")
  191     print("-k, --hardlink         : use hardlinks if possible")
  192     print('')
  193 
  194 def listsections(file):
  195     cfg = ConfigParser()
  196     cfg.read(file)
  197     sections = cfg.sections()
  198     sections.sort()
  199     print('\n** Available sections in '+file+' **\n')
  200     for sec in sections:
  201         if cfg.has_option(sec, 'comment'):
  202             print(sec+' - '+cfg.get(sec, 'comment'))
  203         else:
  204             print(sec)
  205     print('')
  206 
  207 def testargs(config,jail,args):
  208     if ((len(args)<2 and jail == None) or (jail != None and len(args)<1)):
  209         jk_lib.clean_exit(2,'need at least a jail directory and a configfile-section',usage)
  210     if (jail == None):
  211         jail = args[0]
  212     if (jail[0] != '/'):
  213         jail = os.path.abspath(jail)
  214     else:
  215         jail = os.path.normpath(jail)
  216     if (jk_lib.chroot_is_safe(jail) != 1):
  217         jk_lib.clean_exit(3,'jail directory '+args[0]+' is not safe',usage)
  218     if (not os.path.isfile(config['file'])):
  219         jk_lib.clean_exit(3,'configfile '+config['file']+' does not exist',usage)
  220     return jail
  221 
  222 def main():
  223     if (os.getuid()!=0):
  224         print('Cannot create chroot jail without root privileges. Abort.')
  225         sys.exit(5)
  226     try:
  227         opts, args = getopt.getopt(sys.argv[1:], "vhflc:kj:", ["help", "configfile=", "verbose", "force", 'list', 'hardlink', 'jail'])
  228     except getopt.GetoptError:
  229         usage()
  230         sys.exit(1)
  231     config = {}
  232     config['file'] = INIPREFIX+'/jk_init.ini'
  233     config['verbose'] = 0
  234     config['force'] = 0
  235     config['hardlink'] = 0
  236     jail = None
  237     list = 0
  238     for o, a in opts:
  239         if o in ("-h", "--help"):
  240             usage()
  241             sys.exit()
  242         if o in ("-c", "--configfile"):
  243             config['file'] = a
  244         if  o in ("-l", "--list"):
  245             list = 1
  246         if o in ("-v", "--verbose"):
  247             config['verbose'] = 1
  248         if o in ("-f", "--force"):
  249             config['force'] = 1
  250         if o in ("-k", "--hardlink"):
  251             config['hardlink'] = 1
  252         if o in ("-j", "--jail="):
  253             jail = a
  254     if (list ==1):
  255         listsections(config['file'])
  256         sys.exit()
  257     jail = testargs(config,jail,args)
  258     activateConfig(config, jail, args)
  259  
  260 if __name__ == "__main__":
  261     main()