From 5e871a0abb800ca190575dad3238706fea457d34 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 31 Aug 2009 15:47:14 -0600 Subject: Fleshed out krb plugin and added example of scripting against Python API --- doc/examples/python-api.py | 30 ++++++++++++++++ ipalib/plugins/kerberos.py | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100755 doc/examples/python-api.py diff --git a/doc/examples/python-api.py b/doc/examples/python-api.py new file mode 100755 index 000000000..17f00db3d --- /dev/null +++ b/doc/examples/python-api.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python + +from ipalib import api + +# 1. Initialize ipalib +# +# Run ./python-api.py --help to see the global options. Some useful options: +# +# -v Produce more verbose output +# -d Produce full debugging output +# -e in_server=True Force running in server mode +# -e xmlrpc_uri=https://foo.com/ipa/xml # Connect to a specific server + +api.bootstrap_with_global_options(context='example') +api.finalize() + +# You will need to create a connection. If you're in_server, call +# Backend.ldap.connect(), otherwise Backend.xmlclient.connect(). + +if api.env.in_server: + api.Backend.ldap2.connect( + ccache=api.Backend.krb.default_ccname() + ) +else: + api.Backend.xmlclient.connect() + + +# Now that you're connected, you can make calls to api.Command.whatever(): +print 'The admin user:' +print api.Command.user_show(u'admin') diff --git a/ipalib/plugins/kerberos.py b/ipalib/plugins/kerberos.py index cc8204976..5c048719d 100644 --- a/ipalib/plugins/kerberos.py +++ b/ipalib/plugins/kerberos.py @@ -23,12 +23,102 @@ Backend plugin for Kerberos. This wraps the python-kerberos and python-krbV bindings. """ +import sys from ipalib import api from ipalib.backend import Backend +import krbV + + +# FIXME: Is it safe to assume the Kerberos library is using UTF-8 for the +# principal and realm? If not, how do we query the Kerberos library to find +# the encoding it's using? +ENCODING = 'UTF-8' +FS_ENCODING = (sys.getfilesystemencoding() or sys.getdefaultencoding()) + class krb(Backend): """ Kerberos backend plugin. + + This wraps the `krbV` bindings (and will eventually wrap the `kerberos` + bindings also). Importantly, this plugin does correct Unicode + encoding/decoding of values going-to/coming-from the bindings. """ + def __default_ccache(self): + """ + Return the ``krbV.CCache`` for the default credential cache. + """ + return krbV.default_context().default_ccache() + + def __default_principal(self): + """ + Return the ``krb5.Principal`` for the default credential cache. + """ + return self.__default_ccache().principal() + + def __get_ccache(self, ccname): + """ + Return the ``krbV.CCache`` for the ``ccname`` credential ccache. + """ + return krbV.CCache(ccname.encode(FS_ENCODING)) + + def __get_principal(self, ccname): + """ + Return the ``krb5.Principal`` for the ``ccname`` credential ccache. + """ + return self.__get_ccache(ccname).principal() + + def default_ccname(self): + """ + Return the default ccache file name. + + This will return something like '/tmp/krb5cc_500'. + + This cannot return anything meaningful if used in the server as a + request is processed. + """ + return self.__default_ccache().name.decode(FS_ENCODING) + + def default_principal(self): + """ + Return the principal name in default credential cache. + + This will return something like 'admin@EXAMPLE.COM'. If no credential + cache exists for the invoking user, None is returned. + + This cannot return anything meaningful if used in the server as a + request is processed. + """ + return self.__default_principal().name.decode(ENCODING) + + def default_realm(self): + """ + Return the realm from the default credential cache. + + This will return something like 'EXAMPLE.COM'. If no credential cache + exists for the invoking user, None is returned. + + This cannot return anything meaningful if used in the server as a + request is processed. + """ + return krbV.default_context().default_realm.decode(ENCODING) + + def get_principal(self, ccname): + """ + Return the principal from credential cache file at ``ccname``. + + This will return something like 'admin@EXAMPLE.COM'. + """ + return self.__get_principal(ccname).name.decode(ENCODING) + + def get_realm(self, ccname): + """ + Return the realm from credential cache file at ``ccname``. + + This will return something like 'EXAMPLE.COM'. + """ + return self.__get_principal(ccname).realm.decode(ENCODING) + + api.register(krb) -- cgit