Retrieve the LDAP schema using kerberos credentials.

This is required so we can disable anonymous access in 389-ds.
This commit is contained in:
Rob Crittenden 2010-03-17 10:01:24 -04:00 committed by Jason Gerard DeRose
parent c1b828563b
commit f0d51b65f1
3 changed files with 41 additions and 8 deletions

View File

@ -452,6 +452,7 @@ def main():
# Configuration for ipalib, we will bootstrap and finalize later, after # Configuration for ipalib, we will bootstrap and finalize later, after
# we are sure we have the configuration file ready. # we are sure we have the configuration file ready.
cfg = dict( cfg = dict(
context='installer',
in_server=True, in_server=True,
debug=options.debug debug=options.debug
) )

View File

@ -30,6 +30,7 @@ import re
from ipalib import api, errors, output, uuid from ipalib import api, errors, output, uuid
from ipalib import Command, List, Password, Str from ipalib import Command, List, Password, Str
from ipalib.cli import to_cli from ipalib.cli import to_cli
if api.env.in_server and api.env.context in ['lite', 'server']:
from ipaserver.plugins.ldap2 import ldap2 from ipaserver.plugins.ldap2 import ldap2
from ipalib import _ from ipalib import _
from ipalib.text import Gettext # FIXME: remove once the other Gettext FIXME is removed from ipalib.text import Gettext # FIXME: remove once the other Gettext FIXME is removed

View File

@ -30,6 +30,8 @@ import copy
import os import os
import socket import socket
import string import string
import shutil
import tempfile
import krbV import krbV
import ldap as _ldap import ldap as _ldap
@ -47,6 +49,9 @@ from ipalib.encoder import Encoder, encode_args, decode_retval
from ipalib.request import context from ipalib.request import context
# SASL authentication mechanism
SASL_AUTH = _ldap_sasl.sasl({}, 'GSSAPI')
# universal LDAPError handler # universal LDAPError handler
def _handle_errors(e, **kw): def _handle_errors(e, **kw):
""" """
@ -98,12 +103,38 @@ def _handle_errors(e, **kw):
raise errors.DatabaseError(desc=desc, info=info) raise errors.DatabaseError(desc=desc, info=info)
# retrieves LDAP schema from server
def load_schema(url): def load_schema(url):
"""
Retrieve the LDAP schema from the provided url.
Bind using kerberos credentials. If in the context of the
in-tree "lite" server then use the current ccache. If in the context of
Apache then create a new ccache and bind using the Apache HTTP service
principal.
"""
tmpdir = None
if not api.env.in_server or api.env.context not in ['lite', 'server']:
# The schema is only needed on the server side
return
try: try:
if api.env.context == 'server':
# Create a new credentials cache for this Apache process
tmpdir = tempfile.mkdtemp(prefix = "tmp-")
ccache_file = 'FILE:%s/ccache' % tmpdir
krbcontext = krbV.default_context()
principal = str('HTTP/%s@%s' % (api.env.host, api.env.realm))
keytab = krbV.Keytab(name='/etc/httpd/conf/ipa.keytab', context=krbcontext)
principal = krbV.Principal(name=principal, context=krbcontext)
os.environ['KRB5CCNAME'] = ccache_file
ccache = krbV.CCache(name=ccache_file, context=krbcontext, primary_principal=principal)
ccache.init(principal)
ccache.init_creds_keytab(keytab=keytab, principal=principal)
conn = _ldap.initialize(url) conn = _ldap.initialize(url)
# assume anonymous access is enabled conn.sasl_interactive_bind_s('', SASL_AUTH)
conn.simple_bind_s('', '')
schema_entry = conn.search_s( schema_entry = conn.search_s(
'cn=schema', _ldap.SCOPE_BASE, 'cn=schema', _ldap.SCOPE_BASE,
attrlist=['attributetypes', 'objectclasses'] attrlist=['attributetypes', 'objectclasses']
@ -119,6 +150,9 @@ def load_schema(url):
# TODO: DS uses 'cn=schema', support for other server? # TODO: DS uses 'cn=schema', support for other server?
# raise a more appropriate exception # raise a more appropriate exception
raise raise
finally:
if tmpdir:
shutil.rmtree(tmpdir)
return _ldap.schema.SubSchema(schema_entry[1]) return _ldap.schema.SubSchema(schema_entry[1])
@ -165,9 +199,6 @@ class ldap2(CrudBackend, Encoder):
# only MOD_REPLACE operations are generated for them # only MOD_REPLACE operations are generated for them
_FORCE_REPLACE_ON_UPDATE_ATTRS = [] _FORCE_REPLACE_ON_UPDATE_ATTRS = []
# SASL authentication mechanism
_SASL_AUTH = _ldap_sasl.sasl({}, 'GSSAPI')
# rules for generating filters from entries # rules for generating filters from entries
MATCH_ANY = '|' # (|(filter1)(filter2)) MATCH_ANY = '|' # (|(filter1)(filter2))
MATCH_ALL = '&' # (&(filter1)(filter2)) MATCH_ALL = '&' # (&(filter1)(filter2))
@ -239,7 +270,7 @@ class ldap2(CrudBackend, Encoder):
if ccache is not None: if ccache is not None:
try: try:
os.environ['KRB5CCNAME'] = ccache os.environ['KRB5CCNAME'] = ccache
conn.sasl_interactive_bind_s('', self._SASL_AUTH) conn.sasl_interactive_bind_s('', SASL_AUTH)
principal = krbV.CCache(name=ccache, principal = krbV.CCache(name=ccache,
context=krbV.default_context()).principal().name context=krbV.default_context()).principal().name
setattr(context, 'principal', principal) setattr(context, 'principal', principal)