Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # Copyright (C) 2006-2007 Red Hat, Inc.
- import sys, os, pwd
- from select import select
- from stat import S_ISREG
- import types
- import xml
- import xml.dom
- sys.path.extend((
- '/usr/lib/luci/zope/lib/python',
- '/usr/lib/luci/zope/lib/python/Products',
- '/usr/lib64/luci/zope/lib/python',
- '/usr/lib64/luci/zope/lib/python/Products',
- '/usr/lib64/luci/zope/lib64/python',
- '/usr/lib64/luci/zope/lib64/python/Products',
- '/usr/lib64/zope/lib64/python',
- '/usr/lib64/zope/lib/python',
- '/usr/lib/zope/lib/python',
- '/usr/lib64/zope/lib/python/Products',
- '/usr/lib64/zope/lib64/python/Products',
- '/usr/lib/zope/lib/python/Products'
- ))
- from Products import __path__
- for pdir in ['/usr/lib/luci/zope/lib/python/Products',
- '/usr/lib64/luci/zope/lib/python/Products',
- '/usr/lib64/luci/zope/lib64/python/Products',
- '/usr/lib64/zope/lib/python/Products',
- '/usr/lib64/zope/lib64/python/Products',
- '/usr/lib/zope/lib/python/Products']:
- if os.path.isdir(pdir):
- __path__.append(pdir)
- LUCI_INIT_DEBUG = 0
- LUCI_USER = 'luci'
- LUCI_GROUP = 'luci'
- LUCI_HOME_DIR = '/var/lib/luci'
- LUCI_DB_PATH = LUCI_HOME_DIR + '/var/Data.fs'
- LUCI_CERT_DIR = LUCI_HOME_DIR + '/var/certs/'
- LUCI_PEERS_DIR = LUCI_CERT_DIR + 'peers/'
- LUCI_BACKUP_DIR = LUCI_HOME_DIR + '/var'
- LUCI_BACKUP_PATH = LUCI_BACKUP_DIR + '/luci_backup.xml'
- LUCI_ADMIN_SET_PATH = LUCI_HOME_DIR + '/.default_password_has_been_reset'
- SSL_PRIVKEY_NAME = 'privkey.pem'
- SSL_PUBKEY_NAME = 'cacert.pem'
- SSL_HTTPS_PRIVKEY_NAME = 'https.key.pem'
- SSL_HTTPS_PUBKEY_NAME = 'https.pem'
- SSL_KEYCONFIG_NAME = 'cacert.config'
- SSL_PRIVKEY_PATH = LUCI_CERT_DIR + SSL_PRIVKEY_NAME
- SSL_PUBKEY_PATH = LUCI_CERT_DIR + SSL_PUBKEY_NAME
- SSL_HTTPS_PRIVKEY_PATH = LUCI_CERT_DIR + SSL_HTTPS_PRIVKEY_NAME
- SSL_HTTPS_PUBKEY_PATH = LUCI_CERT_DIR + SSL_HTTPS_PUBKEY_NAME
- SSL_KEYCONFIG_PATH = LUCI_CERT_DIR + SSL_KEYCONFIG_NAME
- # only root should run this
- if os.getuid() != 0:
- sys.stderr.write('Only the \'root\' user can run %s\n' % sys.argv[0])
- sys.stderr.write('Try again with root privileges.\n')
- sys.exit(2)
- ssl_key_data = [
- { 'id' : SSL_PRIVKEY_PATH,
- 'name': SSL_PRIVKEY_NAME,
- 'type': 'private',
- 'mode': 0600 },
- { 'id' : SSL_HTTPS_PRIVKEY_PATH,
- 'name': SSL_HTTPS_PRIVKEY_NAME,
- 'type': 'private',
- 'mode': 0600 },
- { 'id' : SSL_PUBKEY_PATH,
- 'name': SSL_PUBKEY_NAME,
- 'type': 'public',
- 'mode': 0644 },
- { 'id' : SSL_HTTPS_PUBKEY_PATH,
- 'name': SSL_HTTPS_PUBKEY_NAME,
- 'type': 'public',
- 'mode': 0644 },
- { 'id' : SSL_KEYCONFIG_PATH,
- 'name': SSL_KEYCONFIG_NAME,
- 'type': 'config',
- 'mode': 0644 }
- ]
- for name in os.listdir(LUCI_PEERS_DIR):
- cert_path = LUCI_PEERS_DIR + name
- if S_ISREG(os.stat(cert_path).st_mode):
- ssl_key_data.append({
- 'id' : cert_path,
- 'name' : cert_path.lstrip(LUCI_CERT_DIR),
- 'type' : 'public',
- 'mode' : 0644})
- #null = file(os.devnull, 'rwb+', 0) - available on python 2.4 and above!!!
- null = file('/dev/null', 'rwb+', 0)
- orig_stderr = sys.stderr
- if LUCI_INIT_DEBUG:
- verbose = sys.stderr
- else:
- verbose = null
- def get_luci_uid_gid():
- try:
- luci = pwd.getpwnam(LUCI_USER)[2:4]
- if not luci:
- raise
- if len(luci) != 2:
- raise
- return luci
- except:
- msg = 'Cannot find the "%s" user.\n' % LUCI_USER
- sys.stderr.write(msg)
- raise Exception, msg
- def set_default_passwd_reset_flag():
- # set flag marking admin password has been set
- try:
- uid, gid = get_luci_uid_gid()
- except:
- sys.stderr.write('Unable to find the luci user\'s UID\n')
- return False
- try:
- open(LUCI_ADMIN_SET_PATH, 'w').write('True')
- except IOError, e:
- if e[0] != 2:
- sys.stderr.write('Unable to open "%s" for writing: %s\n' \
- % (LUCI_ADMIN_SET_PATH, e[1]))
- return False
- except Exception, e:
- sys.stderr.write('Unable to open "%s" for writing: %s\n' \
- % (LUCI_ADMIN_SET_PATH, str(e)))
- return False
- os.chown(LUCI_ADMIN_SET_PATH, uid, gid)
- os.chmod(LUCI_ADMIN_SET_PATH, 0640)
- return True
- def get_default_passwd_reset_flag():
- try:
- return open(LUCI_ADMIN_SET_PATH, 'r').read(16).strip() == 'True'
- except:
- return False
- return False
- def read_passwd(prompt, confirm_prompt):
- from getpass import getpass
- while True:
- s1 = getpass(prompt)
- if len(s1) < 6:
- print 'Password has to be at least 6 characters long'
- continue
- if ' ' in s1:
- print 'Spaces are not allowed in passwords'
- continue
- s2 = getpass(confirm_prompt)
- if s1 != s2:
- print 'Password mismatch, try again'
- continue
- return s1
- def restore_luci_db_fsattr():
- uid, gid = -1, -1
- try:
- uid, gid = get_luci_uid_gid()
- except:
- return -1
- try:
- os.chown(LUCI_DB_PATH, uid, gid)
- os.chmod(LUCI_DB_PATH, 0600)
- for fext in [ '.tmp', '.old', '.index', '.lock' ]:
- try:
- os.chown('%s%s' % (LUCI_DB_PATH, fext), uid, gid)
- os.chmod('%s%s' % (LUCI_DB_PATH, fext), 0600)
- except:
- pass
- except Exception, e:
- sys.stderr.write('Unable to change ownership of the Luci database back to user "%s": %s\n' % (LUCI_USER, str(e)))
- return -1
- def set_zope_passwd(user, passwd):
- sys.stderr = null
- from ZODB.FileStorage import FileStorage
- from ZODB.DB import DB
- from OFS.Application import AppInitializer
- import AccessControl
- import AccessControl.User
- from AccessControl.AuthEncoding import SSHADigestScheme
- from AccessControl.SecurityManagement import newSecurityManager
- import transaction
- import App.ImageFile
- # Zope wants to open a www/ok.gif and images/error.gif
- # when you initialize the application object. This keeps
- # the AppInitializer(app).initialize() call below from failing.
- App.ImageFile.__init__ = lambda x, y: None
- sys.stderr = orig_stderr
- try:
- fs = FileStorage(LUCI_DB_PATH)
- db = DB(fs)
- conn = db.open()
- except IOError, e:
- if e[0] == 11:
- sys.stderr.write('It appears that Luci is running. Please stop Luci before attempting to reset passwords.\n')
- return -1
- else:
- sys.stderr.write('Unable to open the Luci database \"' + LUCI_DB_PATH + '\":' + str(e) + '\n')
- return -1
- except Exception, e:
- sys.stderr.write('Unable to open the Luci database \"' + LUCI_DB_PATH + '\":' + str(e) + '\n')
- return -1
- try:
- sys.stderr = null
- tempuser = AccessControl.User.UnrestrictedUser('admin', '',
- ('manage','Manager', 'Owner', 'View', 'Authenticated'), [])
- newSecurityManager(None, tempuser)
- app = conn.root()['Application']
- AppInitializer(app).initialize()
- sys.stderr = orig_stderr
- except:
- sys.stderr = orig_stderr
- sys.stderr.write('An error occurred while setting the password for user \"' + user + '\"\n')
- return -1
- ret = -1
- try:
- pwd_scheme = SSHADigestScheme
- pwd_hash = '{SSHA}' + pwd_scheme.encrypt(SSHADigestScheme(), passwd)
- acl_users = app.acl_users.users
- if len(acl_users):
- acl_users._user_passwords[user] = pwd_hash
- transaction.commit()
- ret = 0
- else:
- raise
- except:
- sys.stderr.write('Unable to set the password for user \"' + user + '\"\n')
- conn.close()
- db.pack()
- db.close()
- fs.close()
- if restore_luci_db_fsattr():
- return -1
- if user == 'admin' and ret == 0:
- set_default_passwd_reset_flag()
- return ret
- def luci_restore_certs(certList):
- if not certList or len(certList) < 1:
- sys.stderr.write('Your backup file contains no certificate data. Please check that your backup file is not corrupt.\n')
- return -1
- certList = certList[0].getElementsByTagName('certificate')
- if not certList or len(certList) < 1:
- sys.stderr.write('Your backup file contains no certificate data. Please check that your backup file is not corrupt.\n')
- return -1
- uid, gid = -1, -1
- try:
- uid, gid = get_luci_uid_gid()
- except:
- return -1
- for c in certList:
- path = c.getAttribute('name')
- if not path:
- sys.stderr.write('Missing \"name\" field for certificate.\n')
- return -1
- path = LUCI_CERT_DIR + str(path)
- mode = c.getAttribute('mode')
- if not mode:
- mode = 0600
- else:
- mode = int(mode, 8)
- data = c.firstChild
- if not data or not data.wholeText:
- sys.stderr.write('\"' + path + '\" has no certificate data.')
- return -1
- # Because .prettyprint() was called to write the backup..
- data = data.wholeText.strip()
- if len(data) < 1:
- sys.stderr.write('\"' + path + '\" has no certificate data.')
- return -1
- data = str(data)
- try:
- f = file(path, 'wb+')
- except:
- sys.stderr.write('Unable to create \" ' + path + '\" for writing.\n')
- return -1
- os.chmod(path, mode)
- f.write(data + '\n')
- os.chown(path, uid, gid)
- f.close()
- return None
- def luci_restore(argv):
- sys.stderr = null
- from ZODB.FileStorage import FileStorage
- from ZODB.DB import DB
- from OFS.Application import AppInitializer
- import AccessControl
- import AccessControl.User
- from AccessControl.SecurityManagement import newSecurityManager
- import transaction
- import App.ImageFile
- from DateTime import DateTime
- App.ImageFile.__init__ = lambda x, y: None
- sys.stderr = orig_stderr
- if len(argv) > 0:
- dbfn = argv[0]
- else:
- dbfn = LUCI_DB_PATH
- if len(argv) > 1:
- backupfn = argv[1]
- else:
- backupfn = LUCI_BACKUP_PATH
- try:
- fs = FileStorage(dbfn)
- db = DB(fs)
- db.pack()
- conn = db.open()
- except IOError, e:
- if e[0] == 11:
- sys.stderr.write('It appears that Luci is running. Please stop Luci before attempting to restore your installation.\n')
- return -1
- else:
- sys.stderr.write('Unable to open the Luci database \"' + dbfn + '\":' + str(e) + '\n')
- return -1
- except Exception, e:
- sys.stderr.write('Unable to open the Luci database \"' + dbfn + '\":' + str(e) + '\n')
- return -1
- try:
- node = xml.dom.minidom.parse(backupfn)
- except:
- sys.stderr.write('Unable to open the Luci backup file \"'+ backupfn +'\"\n')
- return -1
- node = node.getElementsByTagName('luci')
- if not node or len(node) < 1:
- sys.stderr.write('Backup file is missing the \'luci\' tag\n')
- return -1
- node = node[0].getElementsByTagName('backupData')
- if not node or len(node) < 1:
- sys.stderr.write('Backup file is missing the \'backupData\' tag\n')
- return -1
- node = node[0]
- try:
- sys.stderr = null
- tempuser = AccessControl.User.UnrestrictedUser('admin', '',
- ('manage','Manager', 'Owner', 'View', 'Authenticated'), [])
- newSecurityManager(None, tempuser)
- app = conn.root()['Application']
- AppInitializer(app).initialize()
- sys.stderr = orig_stderr
- except:
- sys.stderr = orig_stderr
- sys.stderr.write('An error occurred while initializing the Luci installation for restoration from backup\n')
- return -1
- try:
- acl_users = app.acl_users.users
- portal_mem = app.luci.portal_membership
- portal_reg = app.luci.portal_registration
- if not (acl_users and len(acl_users) and portal_mem and portal_reg):
- raise
- except:
- sys.stderr.write('Your Luci installation appears to be corrupt.\n')
- return -1
- userList = node.getElementsByTagName('userList')
- if not userList or len(userList) < 1:
- sys.stderr.write('Your backup file contains no users. At the very least, the admin user must exist. Please check that your backup file is not
- corrupt.\n')
- return -1
- userList = userList[0].getElementsByTagName('user')
- if not userList or len(userList) < 1:
- sys.stderr.write('Your backup file contains no users. At the very least, the admin user must exist. Please check that your backup file is not
- corrupt.\n')
- return -1
- for u in userList:
- id = u.getAttribute('id')
- if not id:
- transaction.abort()
- sys.stderr.write('Missing ID for user\n')
- return -1
- id = str(id)
- passwd = u.getAttribute('passwd')
- if not passwd:
- transaction.abort()
- sys.stderr.write('Missing password for user \"' + id + '\"\n')
- return -1
- passwd = str(passwd)
- if id == 'admin':
- try:
- acl_users._user_passwords['admin'] = passwd
- except:
- transaction.abort()
- sys.stderr.write('Unable to restore admin password.')
- return -1
- else:
- email = u.getAttribute('email')
- if not email:
- email = id + '@luci.example.org'
- else:
- email = str(email)
- props = {
- 'username': id,
- 'roles': [ 'Member' ],
- 'domains': [],
- 'email': email,
- 'must_change_password': False
- }
- login_time = u.getAttribute('login_time')
- if login_time:
- props['login_time'] = DateTime(str(login_time))
- last_login_time = u.getAttribute('last_login_time')
- if last_login_time:
- props['last_login_time'] = DateTime(str(last_login_time))
- must_change_passwd = u.getAttribute('must_change_password')
- if must_change_passwd:
- must_change_passwd = str(must_change_passwd)
- if must_change_passwd == 'True' or '1':
- props['must_change_password'] = True
- portal_reg.addMember(id, passwd, props)
- member = portal_mem.getMemberById(id)
- if not member:
- transaction.abort()
- sys.stderr.write('An error occurred while restoring the user \"' + id + '\"\n')
- return -1
- try:
- aclu = app.luci.acl_users.source_users
- if aclu and len(aclu):
- aclu._user_passwords[id] = passwd
- else:
- raise
- except:
- transaction.abort()
- sys.stderr.write('An error occurred while restoring the password for user \"' + id + '\"\n')
- return -1
- verbose.write('Added user \"' + id + '\"\n')
- transaction.commit()
- try:
- x = app.luci.systems.storage
- if not x:
- raise
- except:
- transaction.abort()
- sys.stderr.write('Cannot find the Luci storage systems directory. Your Luci installation may be corrupt.\n')
- return -1
- systemList = node.getElementsByTagName('systemList')
- if not systemList or len(systemList) < 1:
- verbose.write('No storage systems to add\n')
- else:
- systemList = systemList[0].getElementsByTagName('system')
- if len(systemList) < 1:
- verbose.write('No storage systems to add\n')
- for s in systemList:
- id = s.getAttribute('id')
- if not id:
- transaction.abort()
- sys.stderr.write('Missing ID for storage system. Your backup may be corrupt.\n')
- return -1
- id = str(id)
- try:
- title = str(s.getAttribute('title'))
- except:
- title = ''
- x.manage_addFolder(id, title)
- try:
- new_system = app.luci.systems.storage.get(id)
- if not new_system:
- raise
- new_system.manage_acquiredPermissions([])
- new_system.manage_role('View',
- ['Access contents information', 'View'])
- except:
- transaction.abort()
- sys.stderr.write('An error occurred while restoring storage system \"' + id + '\"\n')
- return -1
- userPerms = s.getElementsByTagName('permList')
- if not userPerms or len(userPerms) < 1:
- verbose.write('Added storage system \"' + id + '\"\n')
- continue
- userPerms = userPerms[0].getElementsByTagName('ref')
- for i in userPerms:
- newuser = i.getAttribute('name')
- if not newuser:
- continue
- try:
- new_system.manage_setLocalRoles(newuser, ['View'])
- verbose.write('Added view permission to storage system \"' + id + '\" for \"' + newuser + '\"\n')
- except:
- sys.stderr.write('An error occurred while restoring permission for storage system \"' + id + '\" for user \"' + newuser + '\"\
- n')
- verbose.write('Added storage system \"' + id + '\"\n')
- transaction.commit()
- try:
- x = app.luci.systems.cluster
- if not x:
- raise
- except:
- transaction.abort()
- sys.stderr.write('Cannot find the Luci cluster directory. Your Luci installation may be corrupt.\n')
- return -1
- clusterList = node.getElementsByTagName('clusterList')
- if not clusterList or len(clusterList) < 1:
- verbose.write('No clusters to add\n')
- else:
- clusterList = clusterList[0].getElementsByTagName('cluster')
- if len(clusterList) < 1:
- verbose.write('No clusters to add\n')
- for c in clusterList:
- id = c.getAttribute('id')
- if not id:
- transaction.abort()
- sys.stderr.write('Cluster element is missing id\n')
- return -1
- id = str(id)
- title = c.getAttribute('title')
- if not title:
- title = ''
- else:
- title = str(title)
- try:
- x.manage_addFolder(id, title)
- new_cluster = app.luci.systems.cluster.get(id)
- if not new_cluster:
- raise
- new_cluster.manage_acquiredPermissions([])
- new_cluster.manage_role('View',
- ['Access contents information', 'View'])
- except:
- transaction.abort()
- sys.stderr.write('An error occurred while restoring the cluster \"' + id + '\"\n')
- return -1
- viewperm = list()
- userPerms = c.getElementsByTagName('permList')
- if userPerms and len(userPerms) > 0:
- userPerms = userPerms[0].getElementsByTagName('ref')
- for i in userPerms:
- newuser = i.getAttribute('name')
- if not newuser:
- continue
- newuser = str(newuser)
- try:
- new_cluster.manage_setLocalRoles(newuser, ['View'])
- verbose.write('Added view permission to cluster \"' + id + '\" for \"' + newuser + '\"\n')
- except:
- sys.stderr.write('An error occurred while restoring permission for cluster \"' + id + '\" for user \"' + newuser + '\"
- \n')
- viewperm.append(newuser)
- clusterSystems = c.getElementsByTagName('csystemList')
- if not clusterSystems or len(clusterSystems) < 1:
- verbose.write('Cluster \"' + id + '\" has no storage systems\n')
- else:
- clusterSystems = clusterSystems[0].getElementsByTagName('csystem')
- for i in clusterSystems:
- newsys = i.getAttribute('id')
- if not newsys:
- transaction.abort()
- sys.stderr.write('Storage system missing name for cluster \"' + id + '\"\n')
- return -1
- newsys = str(newsys)
- stitle = i.getAttribute('title')
- if not stitle:
- stitle = ''
- else:
- stitle = str(stitle)
- try:
- new_cluster.manage_addFolder(newsys, stitle)
- newcs = app.luci.systems.cluster.get(id).get(newsys)
- if not newcs:
- raise
- newcs.manage_acquiredPermissions([])
- newcs.manage_role('View',
- ['Access contents information', 'View'])
- except:
- transaction.abort()
- sys.stderr.write('An error occurred while restoring the storage system \"' + newsys + '\" for cluster \"' + id + '\"\n
- ')
- return -1
- transaction.commit()
- try:
- for i in viewperm:
- newcs.manage_setLocalRoles(i, ['View'])
- verbose.write('Added view permission to cluster system \"' + newsys + '\" for \"' + i + '\"\n')
- except:
- transaction.abort()
- sys.stderr.write('An error occurred while restoring permissions for cluster system \"' + newsys + '\" in cluster \"' +
- id + '\" for user \"' + i + '\"\n')
- return -1
- verbose.write('Added storage system \"' + newsys + '\" for cluster \"' + id + '\"\n')
- verbose.write('Added cluster \"' + id + '\"\n')
- transaction.commit()
- transaction.commit()
- conn.close()
- db.pack()
- db.close()
- fs.close()
- certList = node.getElementsByTagName('certificateList')
- if not certList or len(certList) < 1:
- sys.stderr.write('No certificate data was found.\n')
- return -1
- if luci_restore_certs(certList):
- sys.stderr.write('An error occurred while restoring certificate data.\n')
- return -1
- return 0
- # This function's ability to work is dependent
- # upon the structure of @obj_dict
- def dataToXML(doc, obj_dict, tltag):
- node = doc.createElement(tltag)
- for i in obj_dict:
- if isinstance(obj_dict[i], types.DictType):
- if i[-4:] == 'List':
- tagname = i
- else:
- tagname = tltag[:-4]
- temp = dataToXML(doc, obj_dict[i], tagname)
- node.appendChild(temp)
- elif isinstance(obj_dict[i], types.StringType) or isinstance(obj_dict[i], types.IntType):
- node.setAttribute(i, str(obj_dict[i]))
- elif isinstance(obj_dict[i], types.ListType):
- if len(obj_dict[i]) < 1:
- continue
- temp = doc.createElement(i)
- for x in obj_dict[i]:
- t = doc.createElement('ref')
- t.setAttribute('name', x)
- temp.appendChild(t.cloneNode(True))
- node.appendChild(temp.cloneNode(True))
- return node.cloneNode(True)
- def luci_backup(argv):
- sys.stderr = null
- from ZODB.FileStorage import FileStorage
- from ZODB.DB import DB
- from OFS.Application import AppInitializer
- import AccessControl
- import AccessControl.User
- from AccessControl.SecurityManagement import newSecurityManager
- import transaction
- from CMFPlone.utils import getToolByName
- import App.ImageFile
- App.ImageFile.__init__ = lambda x, y: None
- sys.stderr = orig_stderr
- if len(argv) > 0:
- dbfn = argv[0]
- else:
- dbfn = LUCI_DB_PATH
- try:
- fs = FileStorage(dbfn)
- db = DB(fs)
- db.pack()
- conn = db.open()
- except IOError, e:
- if e[0] == 11:
- sys.stderr.write('It appears that Luci is running. Please stop Luci before attempting to backup your installation.\n')
- return -1
- else:
- sys.stderr.write('Unable to open the Luci database \"' + dbfn + '\":' + str(e) + '\n')
- return -1
- except Exception, e:
- sys.stderr.write('Unable to open the Luci database \"' + dbfn + '\":' + str(e) + '\n')
- return -1
- try:
- sys.stderr = null
- tempuser = AccessControl.User.UnrestrictedUser('admin', '',
- ('manage','Manager', 'Owner', 'View', 'Authenticated'), [])
- newSecurityManager(None, tempuser)
- app = conn.root()['Application']
- AppInitializer(app).initialize()
- sys.stderr = orig_stderr
- except:
- sys.stderr = orig_stderr
- sys.stderr.write('An error occurred while initializing the Luci installation for restoration from backup\n')
- return -1
- app.luci.portal_memberdata.pruneMemberDataContents()
- transaction.commit()
- try:
- acl_users = app.acl_users.users
- if not (acl_users and len(acl_users)):
- raise
- except:
- sys.stderr.write('Your Luci installation appears to be corrupt.\n')
- return -1
- users = {}
- systems = {}
- clusters = {}
- try:
- acl_users = app.acl_users.users
- if len(acl_users) < 1:
- raise
- users['admin'] = {
- 'id': 'admin',
- 'name': 'admin',
- 'passwd': app.acl_users.users._user_passwords['admin']
- }
- except:
- sys.stderr.write('Unable to find the admin user.\n')
- return -1
- acl_users = app.luci.acl_users.source_users
- if acl_users and len(acl_users):
- for i in app.luci.acl_users.source_users._user_passwords.items():
- try:
- users[i[0]] = {
- 'id': i[0],
- 'name': i[0],
- 'passwd': i[1]
- }
- except:
- try:
- sys.stderr.write('An error occurred while saving details for user \"' + i[0] + '\"\n')
- except:
- sys.stderr.write('An error occurred while saving user information.')
- return -1
- try:
- membertool = getToolByName(app.luci, 'portal_membership')
- if not membertool:
- raise
- for mem in membertool.listMembers():
- try:
- for i in [ 'login_time', 'last_login_time', 'must_change_password', 'email' ]:
- prop = mem.getProperty(i)
- if prop != '':
- users[mem.id][i] = str(prop)
- except:
- continue
- except:
- pass
- try:
- storagedir = app.luci.systems.storage
- clusterdir = app.luci.systems.cluster
- except:
- sys.stderr.write('Your Luci installation appears to be corrupt.')
- return -1
- if storagedir and len(storagedir):
- for i in storagedir.objectItems():
- systems[i[0]] = { 'id': i[0] }
- if hasattr(i[1], 'title'):
- systems[i[0]]['title'] = getattr(i[1], 'title')
- else:
- systems[i[0]]['title'] = '__luci__:system'
- if hasattr(i[1], '__ac_local_roles__'):
- roles = getattr(i[1], '__ac_local_roles__')
- if roles:
- systems[i[0]]['permList'] = map(lambda x: x[0], filter(lambda x: len(x) > 1 and 'View' in x[1], roles.items()))
- else:
- systems[i[0]]['permList'] = {}
- if clusterdir and len(clusterdir):
- for i in clusterdir.objectItems():
- cluster_name = i[0]
- clusters[cluster_name] = { 'id': cluster_name, 'csystemList': {} }
- if hasattr(i[1], 'title'):
- clusters[cluster_name]['title'] = getattr(i[1], 'title')
- else:
- clusters[cluster_name]['title'] = '__luci__:cluster'
- if hasattr(i[1], '__ac_local_roles__'):
- roles = getattr(i[1], '__ac_local_roles__')
- if roles:
- clusters[cluster_name]['permList'] = map(lambda x: x[0], filter(lambda x: len(x) > 1 and 'View' in x[1], roles.items()
- ))
- else:
- clusters[cluster_name]['permList'] = {}
- for csystem in i[1].objectItems():
- csystem_hash = { 'id': csystem[0] }
- if hasattr(csystem[1], 'title'):
- csystem_hash['title'] = getattr(csystem[1], 'title')
- else:
- csystem_hash['title'] = '__luci__:csystem:' + cluster_name
- clusters[cluster_name]['csystemList'][csystem[0]] = csystem_hash
- transaction.commit()
- conn.close()
- db.pack()
- db.close()
- fs.close()
- backup_data = {
- 'userList': users,
- 'systemList': systems,
- 'clusterList': clusters
- }
- doc = xml.dom.minidom.Document()
- luciData = doc.createElement('luci')
- doc.appendChild(luciData)
- dataNode = dataToXML(doc, backup_data, 'backupData')
- certList = doc.createElement('certificateList')
- for i in ssl_key_data:
- try:
- certfile = file(i['id'], 'rb')
- output = certfile.read()
- certfile.close()
- if len(output) < 1:
- raise
- except:
- sys.stderr.write('Unable to read \"' + i['id'] + '\"\n')
- # An error backing up anything other than the config
- # is fatal.
- if i['type'] != 'config':
- return None
- certNode = doc.createElement('certificate')
- certNode.setAttribute('id', i['id'])
- certNode.setAttribute('name', i['name'])
- certNode.setAttribute('type', i['type'])
- certNode.setAttribute('mode', str(oct(i['mode'])))
- textNode = doc.createTextNode('\n' + output)
- certNode.appendChild(textNode)
- certList.appendChild(certNode)
- dataNode.appendChild(certList.cloneNode(True))
- luciData.appendChild(dataNode)
- return doc
- def _execWithCaptureErrorStatus(command, argv, searchPath = 0, root = '/', stdin = 0, catchfd = 1, catcherrfd = 2, closefd = -1):
- if not os.access (root + command, os.X_OK):
- raise RuntimeError, '%s is not executable' % command
- (read, write) = os.pipe()
- (read_err, write_err) = os.pipe()
- childpid = os.fork()
- if (not childpid):
- # child
- if (root and root != '/'):
- os.chroot (root)
- if isinstance(catchfd, tuple):
- for fd in catchfd:
- os.dup2(write, fd)
- else:
- os.dup2(write, catchfd)
- os.close(write)
- os.close(read)
- if isinstance(catcherrfd, tuple):
- for fd in catcherrfd:
- os.dup2(write_err, fd)
- else:
- os.dup2(write_err, catcherrfd)
- os.close(write_err)
- os.close(read_err)
- if closefd != -1:
- os.close(closefd)
- if stdin:
- os.dup2(stdin, 0)
- os.close(stdin)
- if (searchPath):
- os.execvp(command, argv)
- else:
- os.execv(command, argv)
- # will never come here
- os.close(write)
- os.close(write_err)
- rc = ""
- rc_err = ""
- in_list = [read, read_err]
- while len(in_list) != 0:
- i, o, e = select(in_list, [], [], 0.1)
- for fd in i:
- if fd == read:
- s = os.read(read, 1000)
- if s == '':
- in_list.remove(read)
- rc = rc + s
- if fd == read_err:
- s = os.read(read_err, 1000)
- if s == '':
- in_list.remove(read_err)
- rc_err = rc_err + s
- os.close(read)
- os.close(read_err)
- status = -1
- try:
- (pid, status) = os.waitpid(childpid, 0)
- except OSError, (errno, msg):
- sys.stderr.write(__name__ + 'waitpid: ' + msg + '\n')
- if os.WIFEXITED(status):
- status = os.WEXITSTATUS(status)
- else:
- status = -1
- return (rc, rc_err, status)
- def luci_initialized():
- # existence of privkey.pem file and
- # admin password (not the one Data.fs comes with)
- # mean that luci has been initialized
- b1 = get_default_passwd_reset_flag()
- b2 = os.access(SSL_PRIVKEY_PATH, os.F_OK)
- return b1 and b2
- def generate_ssl_certs():
- command = '/bin/rm'
- args = [command, '-f', SSL_PRIVKEY_PATH, SSL_PUBKEY_PATH]
- _execWithCaptureErrorStatus(command, args)
- # /usr/bin/openssl genrsa -out /var/lib/luci/var/certs/privkey.pem 2048 > /dev/null 2>&1
- command = '/usr/bin/openssl'
- args = [command, 'genrsa', '-out', SSL_PRIVKEY_PATH, '2048']
- _execWithCaptureErrorStatus(command, args)
- # /usr/bin/openssl req -new -x509 -key /var/lib/luci/var/certs/privkey.pem -out /var/lib/luci/var/certs/cacert.pem -days 1825 -config /var/lib/luci/var/ce
- rts/cacert.config
- command = '/usr/bin/openssl'
- args = [command, 'req', '-new', '-x509', '-key', SSL_PRIVKEY_PATH, '-out', SSL_PUBKEY_PATH, '-days', '1825', '-config', SSL_KEYCONFIG_PATH]
- _execWithCaptureErrorStatus(command, args)
- # take ownership and restrict access
- try:
- uid, gid = get_luci_uid_gid()
- os.chown(SSL_PRIVKEY_PATH, uid, gid)
- os.chown(SSL_PUBKEY_PATH, uid, gid)
- os.chmod(SSL_PRIVKEY_PATH, 0600)
- os.chmod(SSL_PUBKEY_PATH, 0644)
- except:
- command = '/bin/rm'
- args = [command, '-f', SSL_PRIVKEY_PATH, SSL_PUBKEY_PATH]
- _execWithCaptureErrorStatus(command, args)
- return False
- return True
- def restart_message():
- print
- print
- print 'Restart the Luci server for changes to take effect'
- print 'eg. service luci restart'
- print
- return
- def init(argv):
- if luci_initialized():
- sys.stderr.write('Luci site has been already initialized.\n')
- sys.stderr.write('If you want to reset admin password, execute\n')
- sys.stderr.write('\t' + argv[0] + ' password\n')
- sys.exit(1)
- print 'Initializing the Luci server\n'
- print '\nCreating the \'admin\' user\n'
- new_password = read_passwd('Enter password: ', 'Confirm password: ')
- print '\nPlease wait...'
- if not set_zope_passwd('admin', new_password):
- restore_luci_db_fsattr()
- print 'The admin password has been successfully set.'
- else:
- sys.stderr.write('Unable to set the admin user\'s password.\n')
- sys.exit(1)
- print 'Generating SSL certificates...'
- if generate_ssl_certs() == False:
- sys.stderr.write('failed. exiting ...\n')
- sys.exit(1)
- print 'Luci server has been successfully initialized'
- restart_message()
- return
- def password(argv):
- passwd = None
- if '--random' in argv:
- print 'Resetting the admin user\'s password to some random value\n'
- try:
- rand = open('/dev/urandom', 'r')
- passwd = rand.read(16)
- rand.close()
- except:
- sys.stderr.write('Unable to read from /dev/urandom\n')
- sys.exit(1)
- else:
- if not luci_initialized():
- sys.stderr.write('The Luci site has not been initialized.\n')
- sys.stderr.write('To initialize it, execute\n')
- sys.stderr.write('\t' + argv[0] + ' init\n')
- sys.exit(1)
- print 'Resetting the admin user\'s password\n'
- passwd = read_passwd('Enter new password: ', 'Confirm password: ')
- print '\nPlease wait...'
- if not set_zope_passwd('admin', passwd):
- print 'The admin password has been successfully reset.'
- else:
- sys.stderr.write('Unable to set the admin user\'s password.\n')
- sys.exit(1)
- restart_message()
- return
- def backup(argv):
- # If the site hasn't been initialized, there's nothing to
- # save, and luci_backup() will fail
- if not luci_initialized():
- print 'The Luci site has not been initialized\n'
- print 'Nothing to backup\n'
- sys.exit(0)
- print 'Backing up the Luci server...'
- try:
- os.umask(077)
- except: pass
- doc = luci_backup(argv[2:])
- restore_luci_db_fsattr()
- if doc == -1:
- sys.stderr.write('The Luci backup failed. Exiting.\n')
- sys.exit(1)
- try:
- # The LUCI_BACKUP_DIR must not be world-writable
- # as the code below is obviously not safe against
- # races.
- os.stat(LUCI_BACKUP_PATH)
- trynum = 1
- basename = '/luci_backup-'
- while True:
- oldbackup = LUCI_BACKUP_DIR + basename + str(trynum) + '.xml'
- if not os.path.exists(oldbackup):
- try:
- os.rename(LUCI_BACKUP_PATH, oldbackup)
- except:
- sys.stderr.write('Unable to rename the existing backup file.\n')
- sys.stderr.write('The Luci backup failed.\n')
- break
- trynum += 1
- except OSError, e:
- #if e[0] == 2:
- pass
- try:
- f = file(LUCI_BACKUP_PATH, 'wb+')
- except:
- sys.stderr.write('Unable to open \"' + LUCI_BACKUP_PATH + '\" to write backup.\n')
- sys.stderr.write('The Luci backup failed.\n')
- sys.exit(1)
- try:
- os.chmod(LUCI_BACKUP_PATH, 0600)
- except OSError, e:
- sys.stderr.write('An error occurred while making \"' + LUCI_BACKUP_PATH + '\" read-only: ' + e + '\n')
- sys.stderr.write('Please check that this file is not world-readable.\n')
- try:
- f.write(doc.toprettyxml())
- f.close()
- except:
- sys.stderr.write('The Luci backup failed.\n')
- sys.exit(1)
- print 'Luci backup was successful.\nThe backup data is contained in the file \"' + LUCI_BACKUP_PATH + '\"'
- def restore(argv):
- print 'Restoring the Luci server...'
- try:
- os.umask(077)
- except:
- pass
- if luci_restore(argv[2:]):
- ret = False
- sys.stderr.write('The Luci restore failed. Try reinstalling Luci, then restoring again.\n')
- else:
- set_default_passwd_reset_flag()
- ret = True
- print 'Restore was successful.'
- restart_message()
- if restore_luci_db_fsattr():
- return False
- return ret
- def luci_help(argv):
- print 'Usage:'
- print argv[0] + ' [init|backup|restore|password|help]'
- print
- print '\tinit: initialize Luci site'
- print '\tpassword: reset admin password'
- print '\t\t--random: reset admin password to random value (disable account)'
- print '\tbackup: backup Luci site to a file'
- print '\trestore: restore Luci site from backup'
- print '\thelp: this help message'
- print
- def test_luci_installation():
- # perform basic checks
- # TODO: do more tests
- # check if luci user and group are present on the system
- try:
- get_luci_uid_gid()
- except:
- sys.stderr.write('There is a problem with luci installation!\n')
- sys.stderr.write('Mising luci\'s system account and group')
- sys.stderr.write('Recommended action: reinstall luci\n\n')
- sys.exit(3)
- return True
- def main(argv):
- if len(argv) < 2:
- luci_help(argv)
- sys.exit(1)
- test_luci_installation()
- if 'init' in argv:
- init(argv)
- elif 'backup' in argv:
- backup(argv)
- elif 'restore' in argv:
- restore(argv)
- elif 'password' in argv:
- password(argv)
- elif 'help' in argv:
- luci_help(argv)
- else:
- sys.stderr.write('Unknown command\n\n')
- luci_help(argv)
- sys.exit(1)
- # If called from the command line
- if __name__ == '__main__':
- main(sys.argv)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement