Fix traceback in ipa-nis-manage.

The root user cannot use ldapi because of the autobind configuration.
Fall back to a standard GSSAPI sasl bind if the external bind fails.
With --ldapi a regular user may be trying this as well, catch that
and report a reasonable error message.

This also gives priority to the DM password if it is passed in.

Also require the user be root to run the ipa-nis-manage command.
We enable/disable and start/stop services which need to be done as root.

Add a new option to ipa-ldap-updater to prompt for the DM password.
Remove restriction to be run as root except when doing an upgrade.

Ticket 1157
This commit is contained in:
Rob Crittenden 2011-04-11 15:30:11 -04:00
parent 68ff18ed10
commit d42bf3f530
4 changed files with 42 additions and 31 deletions

View File

@ -58,6 +58,9 @@ def parse_options():
default=False, help="Connect to the LDAP server using the ldapi socket")
parser.add_option("-u", '--upgrade', action="store_true", dest="upgrade",
default=False, help="Upgrade an installed server in offline mode")
parser.add_option("-W", '--password', action="store_true",
dest="ask_password",
help="Prompt for the Directory Manager password")
options, args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
@ -92,7 +95,7 @@ def main():
pw = ipautil.template_file(options.password, [])
dirman_password = pw.strip()
else:
if not options.ldapi and not options.upgrade:
if (options.ask_password or not options.ldapi) and not options.upgrade:
dirman_password = get_dirman_password()
files = []
@ -112,8 +115,6 @@ def main():
modified = upgrade.modified
badsyntax = upgrade.badsyntax
else:
if os.getegid() == 0 and options.ldapi:
sys.exit('ldapi cannot be used by root')
# Clear all existing log handlers, this is need to log as root
loggers = logging.getLogger()
if loggers.handlers:

View File

@ -83,6 +83,9 @@ def main():
files = ['/usr/share/ipa/nis.uldif']
servicemsg = ""
if os.getegid() != 0:
sys.exit('Must be root to use this tool.')
options, args = parse_options()
if options.debug:
loglevel = logging.DEBUG

View File

@ -79,6 +79,9 @@ Connect to the LDAP server using the ldapi socket
.TP
\fB\-u\fR, \fB\-\-\-upgrade\fR
Upgrade an installed server in offline mode (implies \-\-ldapi)
.TP
\fB\-W\fR, \fB\-\-\-password\fR
Prompt for the Directory Manager password
.SH "EXIT STATUS"
0 if the command was successful

View File

@ -108,28 +108,27 @@ class LDAPUpdate:
self.sub_dict["DOMAIN"] = domain
if online:
# Try out the password
if not self.ldapi:
try:
conn = ipaldap.IPAdmin(fqdn, ldapi=True, realm=self.realm)
# Try out the connection/password
try:
conn = ipaldap.IPAdmin(fqdn, ldapi=self.ldapi, realm=self.realm)
if self.dm_password:
conn.do_simple_bind(binddn="cn=directory manager", bindpw=self.dm_password)
conn.unbind()
except ldap.CONNECT_ERROR:
raise RuntimeError("Unable to connect to LDAP server %s" % fqdn)
except ldap.SERVER_DOWN:
raise RuntimeError("Unable to connect to LDAP server %s" % fqdn)
except ldap.INVALID_CREDENTIALS:
raise RuntimeError("The password provided is incorrect for LDAP server %s" % fqdn)
else:
conn = ipaldap.IPAdmin(ldapi=True, realm=self.realm)
try:
if os.getegid() == 0:
elif os.getegid() == 0:
try:
# autobind
conn.do_external_bind(self.pw_name)
else:
except errors.NotFound:
# Fall back
conn.do_sasl_gssapi_bind()
except ldap.LOCAL_ERROR, e:
raise RuntimeError('%s' % e.args[0].get('info', '').strip())
else:
conn.do_sasl_gssapi_bind()
conn.unbind()
except (ldap.CONNECT_ERROR, ldap.SERVER_DOWN):
raise RuntimeError("Unable to connect to LDAP server %s" % fqdn)
except ldap.INVALID_CREDENTIALS:
raise RuntimeError("The password provided is incorrect for LDAP server %s" % fqdn)
except ldap.LOCAL_ERROR, e:
raise RuntimeError('%s' % e.args[0].get('info', '').strip())
else:
raise RuntimeError("Offline updates are not supported.")
@ -662,19 +661,24 @@ class LDAPUpdate:
if self.online:
if self.ldapi:
self.conn = ipaldap.IPAdmin(ldapi=True, realm=self.realm)
try:
if os.getegid() == 0:
# autobind
self.conn.do_external_bind(self.pw_name)
else:
self.conn.do_sasl_gssapi_bind()
except ldap.LOCAL_ERROR, e:
raise RuntimeError('%s' % e.args[0].get('info', '').strip())
else:
self.conn = ipaldap.IPAdmin(self.sub_dict['FQDN'],
ldapi=self.ldapi,
ldapi=False,
realm=self.realm)
self.conn.do_simple_bind(bindpw=self.dm_password)
try:
if self.dm_password:
self.conn.do_simple_bind(binddn="cn=directory manager", bindpw=self.dm_password)
elif os.getegid() == 0:
try:
# autobind
self.conn.do_external_bind(self.pw_name)
except errors.NotFound:
# Fall back
self.conn.do_sasl_gssapi_bind()
else:
self.conn.do_sasl_gssapi_bind()
except ldap.LOCAL_ERROR, e:
raise RuntimeError('%s' % e.args[0].get('info', '').strip())
else:
raise RuntimeError("Offline updates are not supported.")
all_updates = {}