-
Notifications
You must be signed in to change notification settings - Fork 0
/
initplatform.py
executable file
·188 lines (164 loc) · 6.07 KB
/
initplatform.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/usr/bin/python
# Copyright (c) 2010 William Leszczuk
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
'''
Initializes or reinitializes the `evolve' platform:
- creates /var/log/evolve and /var/lib/evolve.uid, if they don't exist
- logs to /var/log/evolve/platform.log
- creates the `evolve' user account
- changes the owner of the `evolve' bootstrapper to that user and adds the
setuid permission
'''
__author__ = 'Will Leszczuk'
import os, pwd, random, logging
from optparse import OptionParser
from evolve.shared.util import do_or_die
from evolve.cli import evolvecli
_LogPath = '/var/log/evolve'
_LogFilePath = _LogPath + '/platform.log'
_Bootstrapper = '/usr/bin/evolve'
_logger = None
def _gen_phrase(length=20):
phrasechars = \
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' \
'1234567890-=!@#$%^&*()_+'
return ''.join(
[phrasechars[random.randint(0,len(phrasechars) - 1)] for i in range(length)]
)
class _AccountManager:
__UidPath = '/var/lib/evolve.uid'
def __init__(self, username):
self.username = username
self.initialized = self._is_initialized()
def _is_initialized(self):
result = True
try: self.uid = pwd.getpwnam(self.username).pw_uid
except KeyError: result = False
return result
def create(self):
assert(not self.initialized)
self._add_user()
self._set_cli_permissions()
def _add_user(self):
olduid = self._read_old_uid()
do_or_die(
"useradd %s -d '/home/%s' -mp '%s' -K PASS_MAX_DAYS=-1 -K UMASK=0133 %s"
% (
'' if None is olduid else ('-u %d' % olduid),
self.username,
_gen_phrase(),
self.username
)
)
self.uid = pwd.getpwnam(self.username).pw_uid
self._write_old_uid(self.uid)
_logger.info('created user [%s] ([%d])' % (self.username, self.uid))
def _read_old_uid(self):
if os.path.exists(_AccountManager._AccountManager__UidPath):
with open(_AccountManager._AccountManager__UidPath, 'r') as uidfile:
olduid = int(uidfile.readline())
_logger.info(
'recovered uid [%d] from [%s]'
% (olduid, _AccountManager._AccountManager__UidPath)
)
return olduid
def _write_old_uid(self, uid):
with open(_AccountManager._AccountManager__UidPath, 'w') as uidfile:
uidfile.write(str(uid))
def _set_cli_permissions(self):
assert(hasattr(self, 'uid'))
cli = _Bootstrapper
os.chown(cli, self.uid, self.uid)
_logger.info(
'changed owner of [%s] to %s:%s ([%d])'
% (cli, self.username, self.username, self.uid)
)
os.chmod(cli, 04755)
_logger.info('set mod to [4755] on [%s]' % cli)
def delete(self, transferuser):
self._revert_cli_permissions(transferuser)
self._delete_user()
def _delete_user(self):
do_or_die('userdel %s' % self.username)
_logger.info('deleted user [%s] ([%d])' % (self.username, self.uid))
del self.uid
self.initialized = False
def _revert_cli_permissions(self, transferuser):
transferuid = pwd.getpwnam(transferuser).pw_uid
cli = _Bootstrapper
os.chmod(cli, 0755)
_logger.info('set mod to [0755] on [%s]' % cli)
os.chown(cli, transferuid, transferuid)
_logger.info(
'changed owner of [%s] to %s:%s ([%d])'
% (cli, transferuser, transferuser, transferuid)
)
def _init_logging():
global _logger
_logger = logging.getLogger()
_logger.setLevel(logging.INFO)
consolehandler = logging.StreamHandler()
_logger.addHandler(consolehandler)
filehandler = logging.FileHandler(_LogFilePath)
filehandler.setFormatter(
logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
)
_logger.addHandler(filehandler)
def _init_directory_structure():
if not os.path.exists(_LogPath): os.mkdir(_LogPath, 0744)
def _set_directory_permissions(username):
do_or_die('chown -R %s:%s \'%s\'' % (username, username, _LogPath))
_logger.info(
'recursively changed owner of [%s] to %s:%s'
% (_LogPath, username, username)
)
do_or_die('chmod -R 744 \'%s\'' % _LogPath)
_logger.info('recursively set mod to 744 on [%s]' % _LogPath)
def _get_options():
parser = OptionParser(description=__doc__, usage='usage: %prog [OPTIONS]')
parser.add_option(
'-f', '--force', action='store_true', dest='force', default=False,
help='force account reinitialization if the evolve user exists'
)
return parser.parse_args()[0]
if '__main__' == __name__:
sudouser = os.getenv('SUDO_USER')
if 0 != os.geteuid() or None is sudouser:
print 'this script must be run as root via sudo'
else:
options = _get_options()
_init_directory_structure()
_init_logging()
acctmgr = _AccountManager(evolvecli.EvolveUser)
if acctmgr.initialized:
if not options.force:
print 'account already initialized (use --force to reinit)'
else:
confstring = '!' + _gen_phrase(7)
if confstring == raw_input(
'type [%s] to reinitialize the `evolve\' user account: ' % confstring
):
acctmgr.delete(sudouser)
if not acctmgr.initialized:
acctmgr.create()
_set_directory_permissions(evolvecli.EvolveUser)