/
0006_migrate_pwd.py
132 lines (102 loc) · 4.58 KB
/
0006_migrate_pwd.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
import spwd
import crypt
import random
import string
import subprocess
from moulinette import m18n
from moulinette.core import MoulinetteError
from moulinette.utils.log import getActionLogger
from moulinette.utils.process import run_commands
from moulinette.utils.filesystem import append_to_file
from moulinette.authenticators.ldap import Authenticator
from yunohost.tools import Migration
logger = getActionLogger('yunohost.migration')
SMALL_PWD_LIST = ["yunohost", "olinux"]
class MyMigration(Migration):
"Migrate password"
def migrate(self):
if self._is_root_pwd_listed(SMALL_PWD_LIST):
new_hash = self._get_admin_hash()
self._replace_root_hash(new_hash)
def backward(self):
pass
def _get_admin_hash(self):
"""
Ask for admin hash the ldap db
Note: to do that like we don't know the admin password we add a second
password
"""
logger.debug('Generate a random temporary password')
tmp_password = ''.join(random.choice(string.ascii_letters +
string.digits) for i in range(12))
# Generate a random temporary password (won't be valid after this
# script ends !) and hash it
logger.debug('Hash temporary password')
tmp_hash = subprocess.check_output(["slappasswd", "-h", "{SSHA}","-s",
tmp_password])
try:
logger.debug('Stop slapd and backup its conf')
run_commands([
# Stop slapd service...
'systemctl stop slapd',
# Backup slapd.conf (to be restored at the end of script)
'cp /etc/ldap/slapd.conf /root/slapd.conf.bkp'
])
logger.debug('Add password to the conf')
# Append lines to slapd.conf to manually define root password hash
append_to_file("/etc/ldap/slapd.conf", 'rootdn "cn=admin,dc=yunohost,dc=org"')
append_to_file("/etc/ldap/slapd.conf", "\n")
append_to_file("/etc/ldap/slapd.conf", 'rootpw ' + tmp_hash)
logger.debug('Start slapd with new password')
run_commands([
# Test conf (might not be entirely necessary though :P)
'slaptest -Q -u -f /etc/ldap/slapd.conf',
# Regenerate slapd.d directory
'rm -Rf /etc/ldap/slapd.d',
'mkdir /etc/ldap/slapd.d',
'slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d/ 2>&1',
# Set permissions to slapd.d
'chown -R openldap:openldap /etc/ldap/slapd.d/',
# Restore slapd.conf
'mv /root/slapd.conf.bkp /etc/ldap/slapd.conf',
# Restart slapd service
'service slapd start'
])
logger.debug('Authenticate on ldap')
auth = Authenticator('default', 'ldap://localhost:389',
'dc=yunohost,dc=org', 'cn=admin')
auth.authenticate( tmp_password)
logger.debug('Ask for the admin hash')
admin_hash = auth.search('cn=admin,dc=yunohost,dc=org', 'cn=admin',
['userPassword'])[0]['userPassword'][0]
admin_hash = admin_hash.replace('{CRYPT}', '')
finally:
logger.debug('Remove tmp_password from ldap db')
# Remove tmp_password from ldap db
run_commands([
# Stop slapd service
'service slapd stop || true',
'if [ -f /root/slapd.conf.bkp ]; then mv /root/slapd.conf.bkp /etc/ldap/slapd.conf; fi',
# Regenerate slapd.d directory
'rm -Rf /etc/ldap/slapd.d',
'mkdir /etc/ldap/slapd.d',
'slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d/ 2>&1',
# Set permissions to slapd.d
'chown -R openldap:openldap /etc/ldap/slapd.d/',
# Restart slapd service
'service slapd start'
])
return admin_hash
def _replace_root_hash(self, new_hash):
hash_root = spwd.getspnam("root").sp_pwd
with open('/etc/shadow', 'r') as before_file:
before = before_file.read()
with open('/etc/shadow', 'w') as after_file:
after_file.write(before.replace("root:" + hash_root,
"root:" + new_hash))
def _is_root_pwd_listed(self, pwd_list):
hash_root = spwd.getspnam("root").sp_pwd
for password in pwd_list:
if hash_root == crypt.crypt(password, hash_root):
return True
return False