mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-29 10:21:18 -06:00
56401c1abe
change default_logger_level to debug in configure_standard_logging add new ipa_log_manager module, move log_mgr there, also export root_logger from log_mgr. change all log_manager imports to ipa_log_manager and change log_manager.root_logger to root_logger. add missing import for parse_log_level()
403 lines
13 KiB
Python
Executable File
403 lines
13 KiB
Python
Executable File
#!/usr/bin/python
|
|
# Authors: Simo Sorce <ssorce@redhat.com>
|
|
#
|
|
# Copyright (C) 2008-2010 Red Hat
|
|
# see file 'COPYING' for use and warranty information
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU 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 General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
import sys
|
|
try:
|
|
import os
|
|
from ipaserver.install import service
|
|
from ipapython import services as ipaservices
|
|
from ipaserver.install.dsinstance import config_dirname, realm_to_serverid
|
|
from ipaserver.install.installutils import is_ipa_configured, wait_for_open_ports, wait_for_open_socket
|
|
from ipapython import sysrestore
|
|
from ipapython import config
|
|
from ipalib import api, errors
|
|
from ipalib.dn import DN
|
|
import ldap
|
|
import ldap.sasl
|
|
import ldapurl
|
|
import socket
|
|
except ImportError:
|
|
print >> sys.stderr, """\
|
|
There was a problem importing one of the required Python modules. The
|
|
error was:
|
|
|
|
%s
|
|
""" % sys.exc_value
|
|
sys.exit(1)
|
|
|
|
SASL_EXTERNAL = ldap.sasl.sasl({}, 'EXTERNAL')
|
|
|
|
class IpactlError(StandardError):
|
|
def __init__(self, msg = '', rval = 1):
|
|
self.msg = msg
|
|
self.rval = rval
|
|
|
|
def __str__(self):
|
|
return self.msg
|
|
|
|
def check_IPA_configuration():
|
|
if not is_ipa_configured():
|
|
# LSB status code 6: program is not configured
|
|
raise IpactlError("IPA is not configured " +
|
|
"(see man pages of ipa-server-install for help)", 6)
|
|
|
|
def is_dirsrv_debugging_enabled():
|
|
"""
|
|
Check the IPA and PKI-CA 389-ds instances to see if debugging is
|
|
enabled. If so we suppress that in our output.
|
|
|
|
returns True or False
|
|
"""
|
|
debugging = False
|
|
serverid = realm_to_serverid(api.env.realm)
|
|
for dse in ['/etc/dirsrv/slapd-PKI-IPA/', config_dirname(serverid)]:
|
|
try:
|
|
fd = open(dse + 'dse.ldif', 'r')
|
|
except IOError:
|
|
continue
|
|
lines = fd.readlines()
|
|
fd.close()
|
|
for line in lines:
|
|
if line.lower().startswith('nsslapd-errorlog-level'):
|
|
(option, value) = line.split(':')
|
|
if int(value) > 0:
|
|
debugging = True
|
|
|
|
return debugging
|
|
|
|
def get_capture_output(service, debug):
|
|
"""
|
|
We want to display any output of a start/stop command with the
|
|
exception of 389-ds when debugging is enabled because it outputs
|
|
tons and tons of information.
|
|
"""
|
|
if service == 'dirsrv' and not debug and is_dirsrv_debugging_enabled():
|
|
print ' debugging enabled, suppressing output.'
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def parse_options():
|
|
usage = "%prog start|stop|restart|status\n"
|
|
parser = config.IPAOptionParser(usage=usage,
|
|
formatter=config.IPAFormatter())
|
|
|
|
parser.add_option("-d", "--debug", action="store_true", dest="debug",
|
|
help="Display debugging information")
|
|
|
|
options, args = parser.parse_args()
|
|
safe_options = parser.get_safe_opts(options)
|
|
|
|
return safe_options, options, args
|
|
|
|
def emit_err(err):
|
|
sys.stderr.write(err + '\n')
|
|
|
|
def get_config():
|
|
base = "cn=%s,cn=masters,cn=ipa,cn=etc,%s" % (api.env.host,
|
|
api.env.basedn)
|
|
srcfilter = '(ipaConfigString=enabledService)'
|
|
attrs = ['cn', 'ipaConfigString']
|
|
|
|
try:
|
|
# systemd services are so fast that we come here before
|
|
# Directory Server actually starts listening. Wait for
|
|
# the socket/port be really available.
|
|
lurl = ldapurl.LDAPUrl(api.env.ldap_uri)
|
|
if lurl.urlscheme == 'ldapi':
|
|
wait_for_open_socket(lurl.hostport, timeout=6)
|
|
else:
|
|
(host,port) = lurl.hostport.split(':')
|
|
wait_for_open_ports(host, [int(port)], timeout=6)
|
|
con = ldap.initialize(api.env.ldap_uri)
|
|
con.sasl_interactive_bind_s('', SASL_EXTERNAL)
|
|
res = con.search_st(base,
|
|
ldap.SCOPE_SUBTREE,
|
|
filterstr=srcfilter,
|
|
attrlist=attrs,
|
|
timeout=10)
|
|
except ldap.SERVER_DOWN, e:
|
|
# LSB status code 3: program is not running
|
|
raise IpactlError("Failed to get list of services to probe status:\n" +
|
|
"Directory Server is stopped", 3)
|
|
except ldap.NO_SUCH_OBJECT:
|
|
masters_list = []
|
|
dn = str(DN('cn=masters,cn=ipa,cn=etc,%s' % api.env.basedn))
|
|
attrs = ['cn']
|
|
try:
|
|
entries = con.search_s(dn,
|
|
ldap.SCOPE_ONELEVEL,
|
|
attrlist=attrs,)
|
|
except Exception, e:
|
|
masters_list.append("No master found because of error: %s" % str(e))
|
|
else:
|
|
for dn,master_entry in entries:
|
|
masters_list.append(master_entry.get('cn', [None])[0])
|
|
|
|
masters = "\n".join(masters_list)
|
|
|
|
raise IpactlError("Failed to get list of services to probe status!\n"
|
|
"Configured hostname '%s' does not match any master server in LDAP:\n%s"
|
|
% (api.env.host, masters))
|
|
except Exception, e:
|
|
raise IpactlError("Unknown error when retrieving list of services from LDAP: " + str(e))
|
|
|
|
svc_list = []
|
|
|
|
for entry in res:
|
|
name = entry[1]['cn'][0]
|
|
for p in entry[1]['ipaConfigString']:
|
|
if p.startswith('startOrder '):
|
|
order = p.split()[1]
|
|
svc_list.append((order, name))
|
|
|
|
return svc_list
|
|
|
|
def ipa_start(options):
|
|
dirsrv = ipaservices.knownservices.dirsrv
|
|
try:
|
|
print "Starting Directory Service"
|
|
dirsrv.start(capture_output=get_capture_output('dirsrv', options.debug))
|
|
except Exception, e:
|
|
raise IpactlError("Failed to start Directory Service: " + str(e))
|
|
|
|
svc_list = []
|
|
try:
|
|
svc_list = get_config()
|
|
except Exception, e:
|
|
emit_err("Failed to read data from Directory Service: " + str(e))
|
|
emit_err("Shutting down")
|
|
try:
|
|
dirsrv.stop(capture_output=False)
|
|
except:
|
|
pass
|
|
if isinstance(e, IpactlError):
|
|
# do not display any other error message
|
|
raise IpactlError(None, e.rval)
|
|
else:
|
|
raise IpactlError(None)
|
|
|
|
if len(svc_list) == 0:
|
|
# no service to stop
|
|
return
|
|
|
|
for (order, svc) in sorted(svc_list):
|
|
svc_name = service.SERVICE_LIST[svc][0]
|
|
svchandle = ipaservices.service(svc_name)
|
|
try:
|
|
print "Starting %s Service" % svc
|
|
svchandle.start(capture_output=get_capture_output(svc_name, options.debug))
|
|
except:
|
|
emit_err("Failed to start %s Service" % svc)
|
|
emit_err("Shutting down")
|
|
for (order, svc) in sorted(svc_list):
|
|
svc_name = service.SERVICE_LIST[svc][0]
|
|
svc_off = ipaservices.service(svc_name)
|
|
try:
|
|
svc_off.stop(capture_output=False)
|
|
except:
|
|
pass
|
|
try:
|
|
dirsrv.stop(capture_output=False)
|
|
except:
|
|
pass
|
|
raise IpactlError("Aborting ipactl")
|
|
|
|
def ipa_stop(options):
|
|
dirsrv = ipaservices.knownservices.dirsrv
|
|
svc_list = []
|
|
try:
|
|
svc_list = get_config()
|
|
except Exception, e:
|
|
# ok if dirsrv died this may fail, so let's try to quickly restart it
|
|
# and see if we can get anything. If not throw our hands up and just
|
|
# exit
|
|
try:
|
|
dirsrv.start(capture_output=False)
|
|
svc_list = get_config()
|
|
except Exception, e:
|
|
emit_err("Failed to read data from Directory Service: " + str(e))
|
|
emit_err("Shutting down")
|
|
try:
|
|
# just try to stop it, do not read a result
|
|
dirsrv.stop()
|
|
finally:
|
|
raise IpactlError(None)
|
|
|
|
if len(svc_list) == 0:
|
|
# no service to stop
|
|
return
|
|
|
|
for (order, svc) in sorted(svc_list, reverse=True):
|
|
svc_name = service.SERVICE_LIST[svc][0]
|
|
svchandle = ipaservices.service(svc_name)
|
|
try:
|
|
print "Stopping %s Service" % svc
|
|
svchandle.stop(capture_output=False)
|
|
except:
|
|
emit_err("Failed to stop %s Service" % svc)
|
|
|
|
try:
|
|
print "Stopping Directory Service"
|
|
dirsrv.stop(capture_output=False)
|
|
except:
|
|
raise IpactlError("Failed to stop Directory Service")
|
|
|
|
|
|
def ipa_restart(options):
|
|
dirsrv = ipaservices.knownservices.dirsrv
|
|
try:
|
|
print "Restarting Directory Service"
|
|
dirsrv.restart(capture_output=get_capture_output('dirsrv', options.debug))
|
|
except Exception, e:
|
|
raise IpactlError("Failed to restart Directory Service: " + str(e))
|
|
|
|
svc_list = []
|
|
try:
|
|
svc_list = get_config()
|
|
except Exception, e:
|
|
emit_err("Failed to read data from Directory Service: " + str(e))
|
|
emit_err("Shutting down")
|
|
try:
|
|
dirsrv.stop(capture_output=False)
|
|
except:
|
|
pass
|
|
if isinstance(e, IpactlError):
|
|
# do not display any other error message
|
|
raise IpactlError(None, e.rval)
|
|
else:
|
|
raise IpactlError(None)
|
|
|
|
if len(svc_list) == 0:
|
|
# no service to stop
|
|
return
|
|
|
|
for (order, svc) in sorted(svc_list):
|
|
svc_name = service.SERVICE_LIST[svc][0]
|
|
svchandle = ipaservices.service(svc_name)
|
|
try:
|
|
print "Restarting %s Service" % svc
|
|
svchandle.restart(capture_output=get_capture_output(svc_name, options.debug))
|
|
except:
|
|
emit_err("Failed to restart %s Service" % svc)
|
|
emit_err("Shutting down")
|
|
for (order, svc) in sorted(svc_list):
|
|
svc_name = service.SERVICE_LIST[svc][0]
|
|
svc_off = ipaservices.service(svc_name)
|
|
try:
|
|
svc_off.stop(capture_output=False)
|
|
except:
|
|
pass
|
|
try:
|
|
dirsrv.stop(capture_output=False)
|
|
except:
|
|
pass
|
|
raise IpactlError("Aborting ipactl")
|
|
|
|
def ipa_status(options):
|
|
dirsrv = ipaservices.knownservices.dirsrv
|
|
try:
|
|
if dirsrv.is_running():
|
|
print "Directory Service: RUNNING"
|
|
else:
|
|
print "Directory Service: STOPPED"
|
|
except:
|
|
raise IpactlError("Failed to get Directory Service status")
|
|
|
|
svc_list = []
|
|
try:
|
|
svc_list = get_config()
|
|
except IpactlError, e:
|
|
raise e
|
|
except Exception, e:
|
|
raise IpactlError("Failed to get list of services to probe status: " + str(e))
|
|
|
|
if len(svc_list) == 0:
|
|
return
|
|
|
|
for (order, svc) in sorted(svc_list):
|
|
svc_name = service.SERVICE_LIST[svc][0]
|
|
svchandle = ipaservices.service(svc_name)
|
|
try:
|
|
if svchandle.is_running():
|
|
print "%s Service: RUNNING" % svc
|
|
else:
|
|
print "%s Service: STOPPED" % svc
|
|
except:
|
|
emit_err("Failed to get %s Service status" % svc)
|
|
|
|
def main():
|
|
if not os.getegid() == 0:
|
|
# LSB status code 4: user had insufficient privilege
|
|
raise IpactlError("You must be root to run ipactl.", 4)
|
|
|
|
safe_options, options, args = parse_options()
|
|
|
|
if len(args) != 1:
|
|
# LSB status code 2: invalid or excess argument(s)
|
|
raise IpactlError("You must specify one action", 2)
|
|
elif args[0] != "start" and args[0] != "stop" and args[0] != "restart" and args[0] != "status":
|
|
raise IpactlError("Unrecognized action [" + args[0] + "]", 2)
|
|
|
|
# check if IPA is configured at all
|
|
try:
|
|
check_IPA_configuration()
|
|
except IpactlError, e:
|
|
if args[0].lower() == "status":
|
|
# Different LSB return code for status command:
|
|
# 4 - program or service status is unknown
|
|
# This should differentiate uninstalled IPA from status
|
|
# code 3 - program is not running
|
|
e.rval = 4
|
|
raise e
|
|
else:
|
|
raise e
|
|
|
|
api.bootstrap(context='cli', debug=options.debug)
|
|
api.finalize()
|
|
|
|
if '.' not in api.env.host:
|
|
raise IpactlError("Invalid hostname '%s' in IPA configuration!\n"
|
|
"The hostname must be fully-qualified" % api.env.host)
|
|
|
|
if args[0].lower() == "start":
|
|
ipa_start(options)
|
|
elif args[0].lower() == "stop":
|
|
ipa_stop(options)
|
|
elif args[0].lower() == "restart":
|
|
ipa_restart(options)
|
|
elif args[0].lower() == "status":
|
|
ipa_status(options)
|
|
|
|
try:
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|
|
except IpactlError, e:
|
|
if e.msg:
|
|
emit_err(e.msg)
|
|
sys.exit(e.rval)
|
|
except RuntimeError, e:
|
|
emit_err("%s" % e)
|
|
sys.exit(1)
|
|
except SystemExit, e:
|
|
sys.exit(e)
|
|
except KeyboardInterrupt, e:
|
|
sys.exit(1)
|