diff options
author | Kevin McCarthy <kmccarth@redhat.com> | 2007-08-22 10:30:51 -0700 |
---|---|---|
committer | Kevin McCarthy <kmccarth@redhat.com> | 2007-08-22 10:30:51 -0700 |
commit | 7691653c0a3ee95aab7c64d631c694a300547345 (patch) | |
tree | d1d3018438cc2b4abdc0b24c2751b85028e96e76 /ipa-server | |
parent | a8f302aa9f193984d68318a65a51b41298b1391d (diff) | |
download | freeipa-7691653c0a3ee95aab7c64d631c694a300547345.tar.gz freeipa-7691653c0a3ee95aab7c64d631c694a300547345.tar.xz freeipa-7691653c0a3ee95aab7c64d631c694a300547345.zip |
Create ipaerror module.
Move LDAPError trapping/conversion into the ipaldap module.
Fix xmlrpc layer to encode/decode ipaerrors properly.
Also, implement mid-air collision exception for updates.
Diffstat (limited to 'ipa-server')
-rw-r--r-- | ipa-server/ipa-gui/ipagui/controllers.py | 17 | ||||
-rw-r--r-- | ipa-server/ipaserver/ipaldap.py | 51 | ||||
-rw-r--r-- | ipa-server/xmlrpc-server/funcs.py | 134 | ||||
-rw-r--r-- | ipa-server/xmlrpc-server/ipaxmlrpc.py | 6 |
4 files changed, 81 insertions, 127 deletions
diff --git a/ipa-server/ipa-gui/ipagui/controllers.py b/ipa-server/ipa-gui/ipagui/controllers.py index bbe0f5d4..eb89e5a6 100644 --- a/ipa-server/ipa-gui/ipagui/controllers.py +++ b/ipa-server/ipa-gui/ipagui/controllers.py @@ -17,6 +17,7 @@ import ipa.ipaclient import ipa.user import xmlrpclib import forms.user +from ipa import ipaerror ipa.config.init_config() user_new_form = forms.user.UserNewForm() @@ -80,8 +81,8 @@ class Root(controllers.RootController): rv = client.add_user(new_user) turbogears.flash("%s added!" % kw['uid']) raise turbogears.redirect('/usershow', uid=kw['uid']) - except xmlrpclib.Fault, f: - turbogears.flash("User add failed: " + str(f.faultString)) + except ipaerror.IPAError, e: + turbogears.flash("User add failed: " + str(e)) return dict(form=user_new_form, tg_template='ipagui.templates.usernew') @@ -129,8 +130,8 @@ class Root(controllers.RootController): rv = client.update_user(new_user) turbogears.flash("%s updated!" % kw['uid']) raise turbogears.redirect('/usershow', uid=kw['uid']) - except xmlrpclib.Fault, f: - turbogears.flash("User update failed: " + str(f.faultString)) + except ipaerror.IPAError, e: + turbogears.flash("User update failed: " + str(e)) return dict(form=user_edit_form, user=kw, tg_template='ipagui.templates.useredit') @@ -143,8 +144,8 @@ class Root(controllers.RootController): if uid != None and len(uid) > 0: try: users = client.find_users(uid.encode('utf-8')) - except xmlrpclib.Fault, f: - turbogears.flash("User show failed: " + str(f.faultString)) + except ipaerror.IPAError, e: + turbogears.flash("User show failed: " + str(e)) raise turbogears.redirect("/userlist") return dict(users=users, fields=forms.user.UserFields()) @@ -156,8 +157,8 @@ class Root(controllers.RootController): try: user = client.get_user(uid) return dict(user=user.toDict(), fields=forms.user.UserFields()) - except xmlrpclib.Fault, f: - turbogears.flash("User show failed: " + str(f.faultString)) + except ipaerror.IPAError, e: + turbogears.flash("User show failed: " + str(e)) raise turbogears.redirect("/") @validate(form=user_new_form) diff --git a/ipa-server/ipaserver/ipaldap.py b/ipa-server/ipaserver/ipaldap.py index 633a9404..aaa4a35a 100644 --- a/ipa-server/ipaserver/ipaldap.py +++ b/ipa-server/ipaserver/ipaldap.py @@ -39,13 +39,7 @@ from ldap.modlist import modifyModlist from ldap.ldapobject import SimpleLDAPObject -class Error(Exception): pass -class InvalidArgumentError(Error): - def __init__(self,message): self.message = message - def __repr__(self): return message -class NoSuchEntryError(Error): - def __init__(self,message): self.message = message - def __repr__(self): return message +from ipa import ipaerror class Entry: """This class represents an LDAP Entry object. An LDAP entry consists of a DN @@ -192,12 +186,13 @@ class IPAdmin(SimpleLDAPObject): instdir = ent.getValue('nsslapd-instancedir') self.sroot, self.inst = re.match(r'(.*)[\/]slapd-(\w+)$', instdir).groups() self.errlog = ent.getValue('nsslapd-errorlog') - except (ldap.INSUFFICIENT_ACCESS, ldap.CONNECT_ERROR, NoSuchEntryError): + except (ldap.INSUFFICIENT_ACCESS, ldap.CONNECT_ERROR, + ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND)): pass # usually means # print "ignored exception" except ldap.LDAPError, e: print "caught exception ", e - raise + raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, None, e) def __localinit__(self): SimpleLDAPObject.__init__(self,'ldaps://%s:%d' % (self.host,self.port)) @@ -257,18 +252,23 @@ class IPAdmin(SimpleLDAPObject): def getEntry(self,*args): """This wraps the search function. It is common to just get one entry""" + sctrl = self.__get_server_controls__() if sctrl is not None: self.set_option(ldap.OPT_SERVER_CONTROLS, sctrl) - res = self.search(*args) + try: + res = self.search(*args) -# res = self.search_ext(args[0], args[1], filterstr=args[2], attrlist=args[3], serverctrls=sctrl) + # res = self.search_ext(args[0], args[1], filterstr=args[2], attrlist=args[3], serverctrls=sctrl) + except ldap.LDAPError, e: + raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, None, e) type, obj = self.result(res) if not obj: - raise NoSuchEntryError("no such entry for " + str(args)) + raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND, + "no such entry for " + str(args)) elif isinstance(obj,Entry): return obj else: # assume list/tuple @@ -278,14 +278,18 @@ class IPAdmin(SimpleLDAPObject): """This wraps the search function to find all users.""" sctrl = self.__get_server_controls__() - if sctrl is not None: self.set_option(ldap.OPT_SERVER_CONTROLS, sctrl) - res = self.search(*args) + try: + res = self.search(*args) + except ldap.LDAPError, e: + raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, None, e) + type, obj = self.result(res) if not obj: - raise NoSuchEntryError("no such entry for " + str(args)) + raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND, + "no such entry for " + str(args)) all_users = [] for s in obj: @@ -303,9 +307,9 @@ class IPAdmin(SimpleLDAPObject): self.set_option(ldap.OPT_SERVER_CONTROLS, sctrl) self.add_s(*args) except ldap.ALREADY_EXISTS: - raise ldap.ALREADY_EXISTS + raise ipaerror.gen_exception(ipaerror.LDAP_DUPLICATE) except ldap.LDAPError, e: - raise e + raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, None, e) return "Success" def updateEntry(self,dn,olduser,newuser): @@ -319,9 +323,13 @@ class IPAdmin(SimpleLDAPObject): try: self.set_option(ldap.OPT_SERVER_CONTROLS, sctrl) self.modify_s(dn, modlist) + # this is raised when a 'delete' attribute isn't found. + # it indicates the previous attribute was removed by another + # update, making the olduser stale. + except ldap.NO_SUCH_ATTRIBUTE: + raise ipaerror.gen_exception(ipaerror.LDAP_MIDAIR_COLLISION) except ldap.LDAPError, e: - raise e - # raise Exception, modlist + raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, None, e) return "Success" def generateModList(self, old_entry, new_entry): @@ -375,7 +383,7 @@ class IPAdmin(SimpleLDAPObject): self.set_option(ldap.OPT_SERVER_CONTROLS, sctrl) self.modify_s(dn, modlist) except ldap.LDAPError, e: - raise e + raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, None, e) return "Success" def __wrapmethods(self): @@ -429,7 +437,8 @@ class IPAdmin(SimpleLDAPObject): while not entry and int(time.time()) < timeout: try: entry = self.getEntry(dn, scope, filter, attrlist) - except NoSuchEntryError: pass # found entry, but no attr + except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): + pass # found entry, but no attr except ldap.NO_SUCH_OBJECT: pass # no entry yet except ldap.LDAPError, e: # badness print "\nError reading entry", dn, e diff --git a/ipa-server/xmlrpc-server/funcs.py b/ipa-server/xmlrpc-server/funcs.py index a261a86a..ebf28af3 100644 --- a/ipa-server/xmlrpc-server/funcs.py +++ b/ipa-server/xmlrpc-server/funcs.py @@ -24,10 +24,12 @@ import ldap import ipaserver.dsinstance import ipaserver.ipaldap import ipaserver.util -import string -from types import * import xmlrpclib import ipa.config +from ipa import ipaerror + +import string +from types import * import os import re @@ -83,15 +85,10 @@ class IPAServer: # FIXME: should we search for this in a specific area of the tree? filter = "(krbPrincipalName=" + princ + ")" - try: - # The only anonymous search we should have - m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,None) - ent = m1.getEntry(self.basedn, self.scope, filter, ['dn']) - _LDAPPool.releaseConn(m1) - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, e) - except ipaserver.ipaldap.NoSuchEntryError: - raise xmlrpclib.Fault(2, "No such user") + # The only anonymous search we should have + m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,None) + ent = m1.getEntry(self.basedn, self.scope, filter, ['dn']) + _LDAPPool.releaseConn(m1) return "dn:" + ent.dn @@ -153,22 +150,13 @@ class IPAServer: if (isinstance(username, tuple)): username = username[0] - try: - dn = self.get_dn_from_principal(self.princ) - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, e) - except ipaserver.ipaldap.NoSuchEntryError: - raise xmlrpclib.Fault(2, "No such user") + dn = self.get_dn_from_principal(self.princ) filter = "(uid=" + username + ")" - try: - m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn) - ent = m1.getEntry(self.basedn, self.scope, filter, sattrs) - _LDAPPool.releaseConn(m1) - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, e) - except ipaserver.ipaldap.NoSuchEntryError: - raise xmlrpclib.Fault(2, "No such user") + + m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn) + ent = m1.getEntry(self.basedn, self.scope, filter, sattrs) + _LDAPPool.releaseConn(m1) return self.convert_entry(ent) @@ -220,22 +208,12 @@ class IPAServer: if opts: self.set_principal(opts['remoteuser']) - try: - dn = self.get_dn_from_principal(self.princ) - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, e) - except ipaserver.ipaldap.NoSuchEntryError: - raise xmlrpclib.Fault(2, "No such user") + dn = self.get_dn_from_principal(self.princ) - try: - m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn) - res = m1.addEntry(entry) - _LDAPPool.releaseConn(m1) - return res - except ldap.ALREADY_EXISTS: - raise xmlrpclib.Fault(3, "User already exists") - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, str(e)) + m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn) + res = m1.addEntry(entry) + _LDAPPool.releaseConn(m1) + return res def get_add_schema (self): """Get the list of fields to be used when adding users in the GUI.""" @@ -290,23 +268,14 @@ class IPAServer: if opts: self.set_principal(opts['remoteuser']) - try: - dn = self.get_dn_from_principal(self.princ) - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, e) - except ipaserver.ipaldap.NoSuchEntryError: - raise xmlrpclib.Fault(2, "No such user") + dn = self.get_dn_from_principal(self.princ) # FIXME: Is this the filter we want or should it be more specific? filter = "(objectclass=posixAccount)" - try: - m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn) - all_users = m1.getList(self.basedn, self.scope, filter, None) - _LDAPPool.releaseConn(m1) - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, e) - except ipaserver.ipaldap.NoSuchEntryError: - raise xmlrpclib.Fault(2, "No such user") + + m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn) + all_users = m1.getList(self.basedn, self.scope, filter, None) + _LDAPPool.releaseConn(m1) users = [] for u in all_users: @@ -338,12 +307,7 @@ class IPAServer: if opts: self.set_principal(opts['remoteuser']) - try: - dn = self.get_dn_from_principal(self.princ) - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, e) - except ipaserver.ipaldap.NoSuchEntryError: - raise xmlrpclib.Fault(2, "No such user") + dn = self.get_dn_from_principal(self.princ) # TODO: this escaper assumes the python-ldap library will error out # on invalid codepoints. we need to check malformed utf-8 input @@ -359,12 +323,9 @@ class IPAServer: m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn) results = m1.getList(self.basedn, self.scope, filter, sattrs) _LDAPPool.releaseConn(m1) - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, e) - except ipaserver.ipaldap.NoSuchEntryError: + except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): results = [] - # raise xmlrpclib.Fault(2, "No such user") - + users = [] for u in results: users.append(self.convert_entry(u)) @@ -412,25 +373,17 @@ class IPAServer: try: moddn = olduser['dn'] except KeyError, e: - raise xmlrpclib.Fault(4, "Old user has no dn") + raise ipaerror.gen_exception(ipaerror.LDAP_MISSING_DN) if opts: self.set_principal(opts['remoteuser']) - try: - proxydn = self.get_dn_from_principal(self.princ) - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, e) - except ipaserver.ipaldap.NoSuchEntryError: - raise xmlrpclib.Fault(2, "No such user") + proxydn = self.get_dn_from_principal(self.princ) - try: - m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,proxydn) - res = m1.updateEntry(moddn, olduser, newuser) - _LDAPPool.releaseConn(m1) - return res - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, str(e)) + m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,proxydn) + res = m1.updateEntry(moddn, olduser, newuser) + _LDAPPool.releaseConn(m1) + return res def mark_user_deleted (self, args, opts=None): """Mark a user as inactive in LDAP. We aren't actually deleting @@ -442,17 +395,9 @@ class IPAServer: if opts: self.set_principal(opts['remoteuser']) - try: - proxydn = self.get_dn_from_principal(self.princ) - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, e) - except ipaserver.ipaldap.NoSuchEntryError: - raise xmlrpclib.Fault(2, "No such user") + proxydn = self.get_dn_from_principal(self.princ) - try: - user = self.get_user(uid, ['dn', 'nsAccountlock'], opts) - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, str(e)) + user = self.get_user(uid, ['dn', 'nsAccountlock'], opts) # Are we doing an add or replace operation? if user.has_key('nsaccountlock'): @@ -460,13 +405,10 @@ class IPAServer: else: has_key = False - try: - m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,proxydn) - res = m1.inactivateEntry(user['dn'], has_key) - _LDAPPool.releaseConn(m1) - return res - except ldap.LDAPError, e: - raise xmlrpclib.Fault(1, str(e)) + m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,proxydn) + res = m1.inactivateEntry(user['dn'], has_key) + _LDAPPool.releaseConn(m1) + return res def ldap_search_escape(match): diff --git a/ipa-server/xmlrpc-server/ipaxmlrpc.py b/ipa-server/xmlrpc-server/ipaxmlrpc.py index 03340ca5..be4762c3 100644 --- a/ipa-server/xmlrpc-server/ipaxmlrpc.py +++ b/ipa-server/xmlrpc-server/ipaxmlrpc.py @@ -35,6 +35,8 @@ from mod_python import apache import ipaserver import funcs +from ipa import ipaerror + import string import base64 @@ -144,9 +146,9 @@ class ModXMLRPCRequestHandler(object): # wrap response in a singleton tuple response = (response,) response = dumps(response, methodresponse=1, allow_none=1) - except Fault, fault: + except ipaerror.IPAError, e: self.traceback = True - response = dumps(fault) + response = dumps(Fault(e.code, str(e))) except: self.traceback = True # report exception back to server |