Attached is an updated to this patch that now correctly applies.

On Tue, 2009-07-07 at 07:07 +0000, Jason Gerard DeRose wrote:
> This patch adds the first example of scripting against the IPA Python
> API in doc/examples/python-api.py.
> 
> It also finally fleshes out the ipalib.plugins.kerberos.krb plugin.  It
> wraps the krbV bindings and does correct Unicode encoding/decoding.
> More work will be coming shortly with some exception handling cleanup
> and porting code to use Backend.krb instead of krbV, but this is a
> start.
> 
> I'm still trying to decide on a good solution for implementing the
> connection creation in a generic and plugable way (to replace the
> hard-coded Executioner.create_context() method).  The difficulty is 1)
> we need it to be plugable, we want to be able to add new backends that
> authenticate using their own mechanisms, while at the same time 2) we
> only want to expose connections (but not credentials of any kind) on
> request.context, and to make things worse, we 3) want to lazily create
> connections whenever possible.
> 
> I took a couple of stabs at the above, but didn't like any of them, so
> for now doc/examples/python-api.py just uses a similar hard-coded
> connection setup to what Executioner.create_context() uses, specifically
> it does this:
> 
>   if api.env.in_server:
>       api.Backend.ldap2.connect(
>           ccache=api.Backend.krb.default_ccname()
>        )
>   else:
>       api.Backend.xmlclient.connect()
> 
> This will be replaced eventually with some common method, but this works
> for now.
> 
> One last thing: to be consisted with the Kerberos library (right?) and
> SASL, I think we should consistently use `ccname` to mean the path of
> the file containing the credential cache.  We use `ccache` a lot
> instead, which can also be confused with the krbV.CCache object.  What
> does everyone think about this?
> 
> Cheers,
> Jason
> _______________________________________________
> Freeipa-devel mailing list
> Freeipa-devel@redhat.com
> https://www.redhat.com/mailman/listinfo/freeipa-devel
>From 5e871a0abb800ca190575dad3238706fea457d34 Mon Sep 17 00:00:00 2001
From: Jason Gerard DeRose <jder...@redhat.com>
Date: Mon, 31 Aug 2009 15:47:14 -0600
Subject: [PATCH] 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(+), 0 deletions(-)
 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 0000000..17f00db
--- /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 cc82049..5c04871 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 'ad...@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 'ad...@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)
-- 
1.6.0.4

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to