2012-10-23 17:28:35 +02:00
# -*- coding: utf-8 -*-
2013-07-06 09:42:26 +02:00
""" License
Copyright ( C ) 2013 YunoHost
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU Affero General Public License for more details .
You should have received a copy of the GNU Affero General Public License
along with this program ; if not , see http : / / www . gnu . org / licenses
"""
""" yunohost_tools.py
2013-07-06 10:17:16 +02:00
Specific tools
2013-07-06 09:42:26 +02:00
"""
2012-10-26 15:26:50 +02:00
import os
import sys
2012-10-23 17:28:35 +02:00
import yaml
2012-10-26 15:26:50 +02:00
import re
2012-10-27 17:06:43 +02:00
import getpass
2013-07-06 14:58:18 +02:00
import subprocess
2013-07-07 11:30:21 +02:00
import requests
2013-07-07 11:54:10 +02:00
import json
2012-10-29 16:25:40 +01:00
from yunohost import YunoHostError , YunoHostLDAP , validate , colorize , get_required_args , win_msg
2012-10-25 21:15:37 +02:00
from yunohost_domain import domain_add
2013-06-16 14:41:29 +02:00
from yunohost_dyndns import dyndns_subscribe
2012-10-27 17:06:43 +02:00
2013-07-07 09:38:18 +02:00
def tools_ldapinit ( password = None ) :
2012-10-27 17:06:43 +02:00
"""
2013-07-06 10:17:16 +02:00
YunoHost LDAP initialization
2013-02-26 20:36:37 +01:00
2012-10-27 17:06:43 +02:00
"""
2012-11-09 18:04:15 +01:00
with YunoHostLDAP ( ) as yldap :
2012-10-26 15:26:50 +02:00
2013-02-26 20:36:37 +01:00
with open ( ' ldap_scheme.yml ' ) as f :
2012-11-09 18:04:15 +01:00
ldap_map = yaml . load ( f )
2012-10-23 17:28:35 +02:00
2012-11-09 18:04:15 +01:00
for rdn , attr_dict in ldap_map [ ' parents ' ] . items ( ) :
2013-07-06 17:27:24 +02:00
yldap . add ( rdn , attr_dict )
2012-10-23 18:10:39 +02:00
2013-06-25 13:25:18 +02:00
for rdn , attr_dict in ldap_map [ ' children ' ] . items ( ) :
2013-07-06 17:27:24 +02:00
yldap . add ( rdn , attr_dict )
2013-02-26 20:36:37 +01:00
2012-11-09 18:04:15 +01:00
admin_dict = {
' cn ' : ' admin ' ,
' uid ' : ' admin ' ,
' description ' : ' LDAP Administrator ' ,
' gidNumber ' : ' 1007 ' ,
' uidNumber ' : ' 1007 ' ,
' homeDirectory ' : ' /home/admin ' ,
' loginShell ' : ' /bin/bash ' ,
' objectClass ' : [ ' organizationalRole ' , ' posixAccount ' , ' simpleSecurityObject ' ]
}
2013-07-06 17:27:24 +02:00
yldap . update ( ' cn=admin ' , admin_dict )
os . system ( ' rm /etc/smbldap-tools/smbldap_bind.conf ' )
with open ( ' /etc/smbldap-tools/smbldap_bind.conf ' , ' w ' ) as f :
lines = [
' masterDN= " cn=admin,dc=yunohost,dc=org " ' ,
' slaveDN= " cn=admin,dc=yunohost,dc=org " ' ,
' masterPw= " yunohost " ' ,
' slavePw= " yunohost " '
]
for line in lines :
f . write ( line + ' \n ' )
os . system ( ' chmod 600 /etc/smbldap-tools/smbldap_bind.conf ' )
os . system ( ' smbpasswd -w yunohost ' )
2013-07-07 11:42:07 +02:00
sid = subprocess . check_output ( [ ' net ' , ' getlocalsid ' , ' YUNOHOST ' ] ) . strip ( ) . split ( ' : ' ) [ 1 ] [ 1 : ]
2013-07-07 09:38:18 +02:00
os . system ( ' echo \' SID= " ' + sid + ' " \' >> /etc/smbldap-tools/smbldap.conf ' )
if password is not None :
os . system ( ' echo " ' + password + ' \n ' + password + ' " | smbldap-populate ' )
2012-10-23 19:55:40 +02:00
2012-10-29 16:06:46 +01:00
win_msg ( _ ( " LDAP has been successfully initialized " ) )
2012-10-26 15:26:50 +02:00
2012-10-27 17:06:43 +02:00
2013-02-26 20:36:37 +01:00
def tools_adminpw ( old_password , new_password ) :
2012-10-27 17:06:43 +02:00
"""
Change admin password
2013-02-26 20:36:37 +01:00
2013-07-06 10:17:16 +02:00
Keyword argument :
2012-11-29 15:00:33 +01:00
old_password
new_password
2013-02-26 20:36:37 +01:00
2012-10-27 17:06:43 +02:00
"""
2012-10-26 15:26:50 +02:00
# Validate password length
2012-11-29 15:00:33 +01:00
if len ( new_password ) < 4 :
2012-10-26 15:26:50 +02:00
raise YunoHostError ( 22 , _ ( " Password is too short " ) )
2013-07-06 14:58:18 +02:00
result = os . system ( ' ldappasswd -h localhost -D cn=admin,dc=yunohost,dc=org -w " ' + old_password + ' " -a " ' + old_password + ' " -s " ' + new_password + ' " ' )
result2 = os . system ( ' smbpasswd -w " ' + new_password + ' " ' )
os . system ( ' rm /etc/smbldap-tools/smbldap_bind.conf ' )
with open ( ' /etc/smbldap-tools/smbldap_bind.conf ' , ' w ' ) as f :
lines = [
' masterDN= " cn=admin,dc=yunohost,dc=org " ' ,
' slaveDN= " cn=admin,dc=yunohost,dc=org " ' ,
' masterPw= " ' + new_password + ' " ' ,
' slavePw= " ' + new_password + ' " '
]
for line in lines :
f . write ( line + ' \n ' )
os . system ( ' chmod 600 /etc/smbldap-tools/smbldap_bind.conf ' )
2012-10-27 17:06:43 +02:00
2013-07-06 14:58:18 +02:00
if result == result2 == 0 :
2012-10-29 16:06:46 +01:00
win_msg ( _ ( " Admin password has been changed " ) )
2012-10-25 21:17:26 +02:00
else :
raise YunoHostError ( 22 , _ ( " Invalid password " ) )
2012-10-27 17:06:43 +02:00
2013-07-07 11:13:21 +02:00
def tools_maindomain ( old_domain , new_domain , dyndns = False ) :
2012-10-27 17:06:43 +02:00
"""
2013-07-06 10:17:16 +02:00
Main domain change tool
2013-02-26 20:36:37 +01:00
2013-07-06 10:17:16 +02:00
Keyword argument :
2012-11-29 15:00:33 +01:00
old_domain
new_domain
2013-02-26 20:36:37 +01:00
2012-10-27 17:06:43 +02:00
"""
2013-06-08 19:46:15 +02:00
2012-11-29 15:00:33 +01:00
if not old_domain :
2013-04-29 11:54:57 +02:00
with open ( ' /etc/yunohost/current_host ' , ' r ' ) as f :
2012-11-29 15:00:33 +01:00
old_domain = f . readline ( ) . rstrip ( )
2012-10-27 17:06:43 +02:00
2012-11-29 15:00:33 +01:00
validate ( r ' ^([a-zA-Z0-9] {1} ([a-zA-Z0-9 \ -]*[a-zA-Z0-9])*)( \ .[a-zA-Z0-9] {1} ([a-zA-Z0-9 \ -]*[a-zA-Z0-9])*)*( \ .[a-zA-Z] {1} ([a-zA-Z0-9 \ -]*[a-zA-Z0-9])*)$ ' , old_domain )
2012-10-26 15:26:50 +02:00
config_files = [
2013-06-09 22:44:23 +02:00
' /etc/postfix/main.cf ' ,
2013-06-10 22:06:02 +02:00
' /etc/metronome/metronome.cfg.lua ' ,
2012-10-27 17:06:43 +02:00
' /etc/dovecot/dovecot.conf ' ,
2012-10-26 15:26:50 +02:00
' /etc/lemonldap-ng/lemonldap-ng.ini ' ,
' /etc/hosts ' ,
2013-05-03 12:10:39 +02:00
' /usr/share/yunohost/yunohost-config/others/startup ' ,
2012-10-26 15:26:50 +02:00
]
2013-02-28 11:24:48 +01:00
config_dir = [ ]
2012-10-26 15:26:50 +02:00
for dir in config_dir :
for file in os . listdir ( dir ) :
config_files . append ( dir + ' / ' + file )
for file in config_files :
with open ( file , " r " ) as sources :
lines = sources . readlines ( )
with open ( file , " w " ) as sources :
for line in lines :
2012-11-29 15:00:33 +01:00
sources . write ( re . sub ( r ' ' + old_domain + ' ' , new_domain , line ) )
2012-10-26 15:26:50 +02:00
2013-06-22 13:37:44 +02:00
domain_add ( [ new_domain ] , raw = False , main = True )
2013-02-27 22:11:10 +01:00
2013-02-26 20:36:37 +01:00
lemon_conf_lines = [
2013-02-28 15:26:35 +01:00
" $tmp-> { ' domain ' } = ' " + new_domain + " ' ; " , # Replace Lemon domain
2013-02-26 20:36:37 +01:00
" $tmp-> { ' ldapBase ' } = ' dc=yunohost,dc=org ' ; " , # Set ldap basedn
" $tmp-> { ' portal ' } = ' https:// " + new_domain + " /sso/ ' ; " , # Set SSO url
2013-06-01 10:55:44 +02:00
" $tmp-> { ' locationRules ' }-> { ' " + new_domain + " ' }-> { ' (?#0ynh_admin)^/ynh-admin/ ' } = ' $uid eq \" admin \" ' ; " ,
2013-06-01 11:00:35 +02:00
" $tmp-> { ' locationRules ' }-> { ' " + new_domain + " ' }-> { ' (?#0ynh_user)^/ynh-user/ ' } = ' $uid ne \" admin \" ' ; "
2013-02-26 20:36:37 +01:00
]
2013-06-07 13:44:23 +02:00
2013-06-02 20:52:17 +02:00
if old_domain is not ' yunohost.org ' :
lemon_conf_lines . extend ( [
2013-06-03 12:08:39 +02:00
" delete $tmp-> { ' locationRules ' }-> { ' " + old_domain + " ' }-> { ' (?#0ynh_admin)^/ynh-admin/ ' }; " ,
" delete $tmp-> { ' locationRules ' }-> { ' " + old_domain + " ' }-> { ' (?#0ynh_user)^/ynh-user/ ' }; "
2013-06-02 20:52:17 +02:00
] )
2013-02-26 20:36:37 +01:00
2013-06-08 12:17:25 +02:00
with open ( ' /tmp/tmplemonconf ' , ' w ' ) as lemon_conf :
2013-02-26 20:36:37 +01:00
for line in lemon_conf_lines :
lemon_conf . write ( line + ' \n ' )
2013-05-30 16:38:42 +02:00
os . system ( ' rm /etc/yunohost/apache/domains/ ' + old_domain + ' .d/*.fixed.conf ' ) # remove SSO apache conf dir from old domain conf (fail if postinstall)
2013-06-08 20:26:23 +02:00
os . system ( ' rm /etc/ssl/private/yunohost_key.pem ' )
os . system ( ' rm /etc/ssl/certs/yunohost_crt.pem ' )
2013-02-26 20:36:37 +01:00
2013-02-28 12:03:51 +01:00
command_list = [
2013-05-30 16:41:42 +02:00
' cp /etc/yunohost/apache/templates/sso.fixed.conf /etc/yunohost/apache/domains/ ' + new_domain + ' .d/sso.fixed.conf ' , # add SSO apache conf dir to new domain conf
' cp /etc/yunohost/apache/templates/admin.fixed.conf /etc/yunohost/apache/domains/ ' + new_domain + ' .d/admin.fixed.conf ' ,
2013-06-02 20:31:43 +02:00
' cp /etc/yunohost/apache/templates/user.fixed.conf /etc/yunohost/apache/domains/ ' + new_domain + ' .d/user.fixed.conf ' ,
2013-02-28 14:18:10 +01:00
' /usr/share/lemonldap-ng/bin/lmYnhMoulinette ' ,
2013-02-28 12:03:51 +01:00
' /etc/init.d/hostname.sh ' ,
2013-06-09 15:27:17 +02:00
' cp /etc/yunohost/certs/ ' + new_domain + ' /key.pem /etc/metronome/certs/yunohost_key.pem ' ,
2013-06-09 15:47:47 +02:00
' chown metronome: /etc/metronome/certs/yunohost_key.pem ' ,
2013-06-08 19:46:15 +02:00
' ln -s /etc/yunohost/certs/ ' + new_domain + ' /key.pem /etc/ssl/private/yunohost_key.pem ' ,
' ln -s /etc/yunohost/certs/ ' + new_domain + ' /crt.pem /etc/ssl/certs/yunohost_crt.pem ' ,
2013-04-29 11:54:57 +02:00
' echo ' + new_domain + ' > /etc/yunohost/current_host ' ,
2013-07-06 19:36:19 +02:00
' service apache2 restart ' ,
2013-06-09 15:47:47 +02:00
' service metronome restart ' ,
2013-07-06 19:36:19 +02:00
' service postfix restart ' ,
' service dovecot restart '
2013-02-28 12:03:51 +01:00
]
for command in command_list :
if os . system ( command ) != 0 :
raise YunoHostError ( 17 , _ ( " There were a problem during domain changing " ) )
2013-07-07 11:13:21 +02:00
if dyndns : dyndns_subscribe ( domain = new_domain )
elif len ( new_domain . split ( ' . ' ) ) > = 3 :
r = requests . get ( ' http://dyndns.yunohost.org/domains ' )
dyndomains = json . loads ( r . text )
dyndomain = ' . ' . join ( new_domain . split ( ' . ' ) [ 1 : ] )
if dyndomain in dyndomains :
dyndns_subscribe ( domain = new_domain )
2013-02-28 12:03:51 +01:00
win_msg ( _ ( " Main domain has been successfully changed " ) )
2012-10-27 17:06:43 +02:00
2012-10-26 15:26:50 +02:00
2013-06-16 14:41:29 +02:00
def tools_postinstall ( domain , password , dyndns = False ) :
2012-10-27 17:06:43 +02:00
"""
2013-07-06 10:17:16 +02:00
YunoHost post - install
2013-02-26 20:36:37 +01:00
2013-07-06 10:17:16 +02:00
Keyword argument :
dyndns - - Subscribe domain to a DynDNS service
domain - - YunoHost main domain
2013-07-06 12:59:06 +02:00
password - - YunoHost admin password
2012-10-27 17:06:43 +02:00
"""
2012-11-09 18:04:15 +01:00
with YunoHostLDAP ( password = ' yunohost ' ) as yldap :
try :
2013-05-03 12:10:39 +02:00
with open ( ' /etc/yunohost/installed ' ) as f : pass
2012-11-09 18:04:15 +01:00
except IOError :
print ( ' Installing YunoHost ' )
else :
raise YunoHostError ( 17 , _ ( " YunoHost is already installed " ) )
2012-10-25 19:50:14 +02:00
2013-06-08 19:46:15 +02:00
# Create required folders
folders_to_create = [
' /etc/yunohost/apps ' ,
2013-06-13 14:20:22 +02:00
' /etc/yunohost/certs ' ,
' /var/cache/yunohost/repo '
2013-06-08 19:46:15 +02:00
]
for folder in folders_to_create :
try : os . listdir ( folder )
except OSError : os . makedirs ( folder )
# Create SSL CA
ssl_dir = ' /usr/share/yunohost/yunohost-config/ssl/yunoCA '
command_list = [
' echo " 01 " > ' + ssl_dir + ' /serial ' ,
' rm ' + ssl_dir + ' /index.txt ' ,
' touch ' + ssl_dir + ' /index.txt ' ,
' openssl req -x509 -new -config ' + ssl_dir + ' /openssl.cnf -days 3650 -out ' + ssl_dir + ' /ca/cacert.pem -keyout ' + ssl_dir + ' /ca/cakey.pem -nodes -batch ' ,
2013-06-23 19:09:30 +02:00
' cp ' + ssl_dir + ' /ca/cacert.pem /etc/ssl/certs/ca-yunohost_crt.pem ' ,
' update-ca-certificates '
2013-06-08 19:46:15 +02:00
]
for command in command_list :
if os . system ( command ) != 0 :
raise YunoHostError ( 17 , _ ( " There were a problem during CA creation " ) )
2012-11-09 18:04:15 +01:00
# Initialize YunoHost LDAP base
2013-07-07 09:38:18 +02:00
tools_ldapinit ( password )
2012-10-26 15:26:50 +02:00
2013-02-27 22:34:16 +01:00
# New domain config
2013-07-07 11:13:21 +02:00
tools_maindomain ( old_domain = ' yunohost.org ' , new_domain = domain , dyndns = dyndns )
2013-02-27 22:34:16 +01:00
2012-11-09 18:04:15 +01:00
# Change LDAP admin password
2012-11-29 15:00:33 +01:00
tools_adminpw ( old_password = ' yunohost ' , new_password = password )
2012-10-26 15:26:50 +02:00
2013-05-03 12:10:39 +02:00
os . system ( ' touch /etc/yunohost/installed ' )
2013-07-06 15:39:30 +02:00
os . system ( ' service samba restart ' )
2013-02-26 20:36:37 +01:00
2012-10-29 16:06:46 +01:00
win_msg ( _ ( " YunoHost has been successfully configured " ) )