11# -*- coding: utf-8 -*-
22"""
3- © 2019 Sebastian Wagner <wagner @cert.at>
3+ © 2019-2021 nic.at GmbH <intelmq-team @cert.at>
44
5- SPDX-License-Identifier: AGPL-3.0
5+ SPDX-License-Identifier: AGPL-3.0-only
66
77Sets up an intelmq environment after installation or upgrade by
88 * creating needed directories
2020import sys
2121import pkg_resources
2222
23- from pwd import getpwuid
23+ from grp import getgrnam
24+ from pwd import getpwuid , getpwnam
25+ from typing import Optional
2426
27+ try :
28+ import intelmq_api
29+ except ImportError :
30+ intelmq_api = None
31+
32+ from termstyle import red
2533from intelmq import (CONFIG_DIR , DEFAULT_LOGGING_PATH , ROOT_DIR , VAR_RUN_PATH ,
2634 VAR_STATE_PATH , BOTS_FILE , STATE_FILE_PATH )
2735from intelmq .bin .intelmqctl import IntelMQController
2836
2937
30- def intelmqsetup ( ownership = True , state_file = STATE_FILE_PATH ):
31- if os .geteuid () != 0 and ownership :
32- sys . exit ( 'You need to run this program as root (for setting file ownership)' )
38+ MANAGER_CONFIG_DIR = os . path . join ( CONFIG_DIR , 'manager/' )
39+ FILE_OUTPUT_PATH = os .path . join ( VAR_STATE_PATH , 'file-output/' )
40+
3341
42+ def basic_checks (skip_ownership ):
43+ if os .geteuid () != 0 and not skip_ownership :
44+ sys .exit (red ('You need to run this program as root for setting file ownership!' ))
3445 if not ROOT_DIR :
35- sys .exit ('Not a pip-installation of IntelMQ, nothing to initialize.' )
36-
37- create_dirs = ('%s/file-output' % VAR_STATE_PATH ,
38- VAR_RUN_PATH ,
39- DEFAULT_LOGGING_PATH ,
40- CONFIG_DIR )
41- for create_dir in create_dirs :
42- if not os .path .isdir (create_dir ):
43- os .makedirs (create_dir , mode = 0o755 ,
44- exist_ok = True )
45- print ('Created directory %r.' % create_dir )
46+ sys .exit (red ('Not a pip-installation of IntelMQ, nothing to initialize.' ))
47+
48+ if skip_ownership :
49+ return
50+ try :
51+ getpwnam ('intelmq' )
52+ except KeyError :
53+ sys .exit (red ("User 'intelmq' does not exist. Please create it and then re-run this program." ))
54+ try :
55+ getgrnam ('intelmq' )
56+ except KeyError :
57+ sys .exit (red ("Group 'intelmq' does not exist. Please create it and then re-run this program." ))
58+
59+
60+ def create_directory (directory : str , octal_mode : int , readable_mode : str ):
61+ if not os .path .isdir (directory ):
62+ os .makedirs (directory , mode = octal_mode ,
63+ exist_ok = True )
64+ print (f'Created directory { directory !r} with permissions { readable_mode } .' )
65+ else :
66+ actual_mode = stat .filemode (os .stat (directory ).st_mode )
67+ if actual_mode != readable_mode :
68+ print (f'Fixed wrong permissions of { directory !r} : { actual_mode !r} -> { readable_mode !r} .' )
69+ os .chmod (directory , octal_mode )
70+
71+
72+ def change_owner (file : str , owner = None , group = None ):
73+ if owner and getpwuid (os .stat (file ).st_uid ).pw_name != owner :
74+ print (f'Fixing owner of directory { file !r} .' )
75+ shutil .chown (file , user = owner )
76+ if group and getpwuid (os .stat (file ).st_gid ).pw_name != group :
77+ print (f'Fixing group of directory { file !r} .' )
78+ shutil .chown (file , group = group )
79+
80+
81+ def intelmqsetup_core (ownership = True , state_file = STATE_FILE_PATH ):
82+ directories_modes = ((FILE_OUTPUT_PATH , 0o755 , 'drwxr-xr-x' ),
83+ (VAR_RUN_PATH , 0o755 , 'drwxr-xr-x' ),
84+ (DEFAULT_LOGGING_PATH , 0o755 , 'drwxr-xr-x' ),
85+ (CONFIG_DIR , 0o775 , 'drwxrwxr-x' ),
86+ )
87+ for directory , octal_mode , readable_mode in directories_modes :
88+ create_directory (directory , octal_mode , readable_mode )
4689
4790 example_confs = glob .glob (pkg_resources .resource_filename ('intelmq' , 'etc/*.conf' ))
4891 for example_conf in example_confs :
4992 fname = os .path .split (example_conf )[- 1 ]
5093 if os .path .exists (os .path .join (CONFIG_DIR , fname )):
51- print ('Not overwriting existing %r with example.' % fname )
94+ print (f 'Not overwriting existing { fname !r } with example.' )
5295 else :
5396 shutil .copy (example_conf , CONFIG_DIR )
54- print ('Use example %r.' % fname )
97+ print (f 'Use example { fname !r } .' )
5598
56- print ('Writing BOTS file.' )
57- shutil .copy (pkg_resources .resource_filename ('intelmq' , 'bots/BOTS' ),
58- BOTS_FILE )
99+ if os .path .islink (BOTS_FILE ):
100+ print ('Skip writing BOTS file as it is a link.' )
101+ else :
102+ print ('Writing BOTS file.' )
103+ shutil .copy (pkg_resources .resource_filename ('intelmq' , 'bots/BOTS' ),
104+ BOTS_FILE )
59105
60106 if ownership :
61107 print ('Setting intelmq as owner for it\' s directories.' )
62108 for obj in (CONFIG_DIR , DEFAULT_LOGGING_PATH , ROOT_DIR , VAR_RUN_PATH ,
63- VAR_STATE_PATH , VAR_STATE_PATH + 'file-output' ):
64- if getpwuid (os .stat (obj ).st_uid ).pw_name != 'intelmq' :
65- shutil .chown (obj , user = 'intelmq' )
109+ VAR_STATE_PATH , FILE_OUTPUT_PATH ):
110+ change_owner (obj , owner = 'intelmq' )
66111
67112 print ('Calling `intelmqctl upgrade-config to update/create state file' )
68113 controller = IntelMQController (interactive = False , no_file_logging = True ,
@@ -79,8 +124,10 @@ def main():
79124 help = 'The state file location to use.' ,
80125 default = STATE_FILE_PATH )
81126 args = parser .parse_args ()
82- intelmqsetup (ownership = not args .skip_ownership ,
83- state_file = args .state_file )
127+
128+ basic_checks (skip_ownership = args .skip_ownership )
129+ intelmqsetup_core (ownership = not args .skip_ownership ,
130+ state_file = args .state_file )
84131
85132
86133if __name__ == '__main__' :
0 commit comments