summaryrefslogtreecommitdiffstats
path: root/ipa-server/xmlrpc-server
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2009-01-29 16:29:11 -0500
committerRob Crittenden <rcritten@redhat.com>2009-02-03 15:28:31 -0500
commite0d428f97aad1f9e9c3faedeaddbcade22927d37 (patch)
tree3a21754e5f4c8283530e2619c32ace2ded324564 /ipa-server/xmlrpc-server
parente30cd6ba42c256d2016db45146d616f329455e86 (diff)
downloadfreeipa-e0d428f97aad1f9e9c3faedeaddbcade22927d37.tar.gz
freeipa-e0d428f97aad1f9e9c3faedeaddbcade22927d37.tar.xz
freeipa-e0d428f97aad1f9e9c3faedeaddbcade22927d37.zip
Mass file removal for IPAv2.
deleted: ipa-admintools/Makefile deleted: ipa-admintools/README deleted: ipa-admintools/ipa-adddelegation deleted: ipa-admintools/ipa-addgroup deleted: ipa-admintools/ipa-addservice deleted: ipa-admintools/ipa-adduser deleted: ipa-admintools/ipa-admintools.spec.in deleted: ipa-admintools/ipa-change-master-key deleted: ipa-admintools/ipa-defaultoptions deleted: ipa-admintools/ipa-deldelegation deleted: ipa-admintools/ipa-delgroup deleted: ipa-admintools/ipa-delservice deleted: ipa-admintools/ipa-deluser deleted: ipa-admintools/ipa-findgroup deleted: ipa-admintools/ipa-findservice deleted: ipa-admintools/ipa-finduser deleted: ipa-admintools/ipa-listdelegation deleted: ipa-admintools/ipa-lockuser deleted: ipa-admintools/ipa-moddelegation deleted: ipa-admintools/ipa-modgroup deleted: ipa-admintools/ipa-moduser deleted: ipa-admintools/ipa-passwd deleted: ipa-admintools/ipa-pwpolicy deleted: ipa-admintools/man/Makefile deleted: ipa-admintools/man/ipa-adddelegation.1 deleted: ipa-admintools/man/ipa-addgroup.1 deleted: ipa-admintools/man/ipa-addservice.1 deleted: ipa-admintools/man/ipa-adduser.1 deleted: ipa-admintools/man/ipa-defaultoptions.1 deleted: ipa-admintools/man/ipa-deldelegation.1 deleted: ipa-admintools/man/ipa-delgroup.1 deleted: ipa-admintools/man/ipa-delservice.1 deleted: ipa-admintools/man/ipa-deluser.1 deleted: ipa-admintools/man/ipa-findgroup.1 deleted: ipa-admintools/man/ipa-findservice.1 deleted: ipa-admintools/man/ipa-finduser.1 deleted: ipa-admintools/man/ipa-listdelegation.1 deleted: ipa-admintools/man/ipa-lockuser.1 deleted: ipa-admintools/man/ipa-moddelegation.1 deleted: ipa-admintools/man/ipa-modgroup.1 deleted: ipa-admintools/man/ipa-moduser.1 deleted: ipa-admintools/man/ipa-passwd.1 deleted: ipa-admintools/man/ipa-pwpolicy.1 deleted: ipa-server/AUTHORS deleted: ipa-server/Makefile.am deleted: ipa-server/NEWS deleted: ipa-server/README deleted: ipa-server/configure.ac deleted: ipa-server/ipa-gui/Makefile.am deleted: ipa-server/ipa-gui/README.i18n deleted: ipa-server/ipa-gui/README.multivalue deleted: ipa-server/ipa-gui/README.txt deleted: ipa-server/ipa-gui/dev.cfg deleted: ipa-server/ipa-gui/i18n.patch deleted: ipa-server/ipa-gui/ipa_gui.egg-info/Makefile.am deleted: ipa-server/ipa-gui/ipa_gui.egg-info/PKG-INFO deleted: ipa-server/ipa-gui/ipa_gui.egg-info/SOURCES.txt deleted: ipa-server/ipa-gui/ipa_gui.egg-info/dependency_links.txt deleted: ipa-server/ipa-gui/ipa_gui.egg-info/entry_points.txt deleted: ipa-server/ipa-gui/ipa_gui.egg-info/not-zip-safe deleted: ipa-server/ipa-gui/ipa_gui.egg-info/paster_plugins.txt deleted: ipa-server/ipa-gui/ipa_gui.egg-info/requires.txt deleted: ipa-server/ipa-gui/ipa_gui.egg-info/sqlobject.txt deleted: ipa-server/ipa-gui/ipa_gui.egg-info/top_level.txt deleted: ipa-server/ipa-gui/ipa_webgui deleted: ipa-server/ipa-gui/ipa_webgui.cfg deleted: ipa-server/ipa-gui/ipa_webgui.init deleted: ipa-server/ipa-gui/ipagui/Makefile.am deleted: ipa-server/ipa-gui/ipagui/__init__.py deleted: ipa-server/ipa-gui/ipagui/config/Makefile.am deleted: ipa-server/ipa-gui/ipagui/config/__init__.py deleted: ipa-server/ipa-gui/ipagui/config/app.cfg deleted: ipa-server/ipa-gui/ipagui/config/log.cfg deleted: ipa-server/ipa-gui/ipagui/controllers.py deleted: ipa-server/ipa-gui/ipagui/forms/Makefile.am deleted: ipa-server/ipa-gui/ipagui/forms/__init__.py deleted: ipa-server/ipa-gui/ipagui/forms/delegate.py deleted: ipa-server/ipa-gui/ipagui/forms/group.py deleted: ipa-server/ipa-gui/ipagui/forms/ipapolicy.py deleted: ipa-server/ipa-gui/ipagui/forms/principal.py deleted: ipa-server/ipa-gui/ipagui/forms/user.py deleted: ipa-server/ipa-gui/ipagui/helpers/Makefile.am deleted: ipa-server/ipa-gui/ipagui/helpers/__init__.py deleted: ipa-server/ipa-gui/ipagui/helpers/ipahelper.py deleted: ipa-server/ipa-gui/ipagui/helpers/userhelper.py deleted: ipa-server/ipa-gui/ipagui/helpers/validators.py deleted: ipa-server/ipa-gui/ipagui/json.py deleted: ipa-server/ipa-gui/ipagui/model.py deleted: ipa-server/ipa-gui/ipagui/proxyprovider.py deleted: ipa-server/ipa-gui/ipagui/proxyvisit.py deleted: ipa-server/ipa-gui/ipagui/release.py deleted: ipa-server/ipa-gui/ipagui/static/Makefile.am deleted: ipa-server/ipa-gui/ipagui/static/css/Makefile.am deleted: ipa-server/ipa-gui/ipagui/static/css/style_freeipa.css deleted: ipa-server/ipa-gui/ipagui/static/css/style_platform-objects.css deleted: ipa-server/ipa-gui/ipagui/static/css/style_platform.css deleted: ipa-server/ipa-gui/ipagui/static/images/Makefile.am deleted: ipa-server/ipa-gui/ipagui/static/images/branding/Makefile.am deleted: ipa-server/ipa-gui/ipagui/static/images/branding/logo.png deleted: ipa-server/ipa-gui/ipagui/static/images/down.gif deleted: ipa-server/ipa-gui/ipagui/static/images/favicon.ico deleted: ipa-server/ipa-gui/ipagui/static/images/header_inner.png deleted: ipa-server/ipa-gui/ipagui/static/images/info.png deleted: ipa-server/ipa-gui/ipagui/static/images/logo.png deleted: ipa-server/ipa-gui/ipagui/static/images/objects/Makefile.am deleted: ipa-server/ipa-gui/ipagui/static/images/objects/object-accesscontrol.png deleted: ipa-server/ipa-gui/ipagui/static/images/objects/object-channel.png deleted: ipa-server/ipa-gui/ipagui/static/images/objects/object-channels.png deleted: ipa-server/ipa-gui/ipagui/static/images/objects/object-content.png deleted: ipa-server/ipa-gui/ipagui/static/images/objects/object-media.png deleted: ipa-server/ipa-gui/ipagui/static/images/objects/object-overview.png deleted: ipa-server/ipa-gui/ipagui/static/images/objects/object-policy.png deleted: ipa-server/ipa-gui/ipagui/static/images/objects/object-system.png deleted: ipa-server/ipa-gui/ipagui/static/images/objects/object-user.png deleted: ipa-server/ipa-gui/ipagui/static/images/objects/object-usergroup.png deleted: ipa-server/ipa-gui/ipagui/static/images/objects/object-virtualsystem.png deleted: ipa-server/ipa-gui/ipagui/static/images/ok.png deleted: ipa-server/ipa-gui/ipagui/static/images/template/Makefile.am deleted: ipa-server/ipa-gui/ipagui/static/images/template/background-content.png deleted: ipa-server/ipa-gui/ipagui/static/images/template/background-navbar-active.png deleted: ipa-server/ipa-gui/ipagui/static/images/template/background-navbar-active_fullsize.png deleted: ipa-server/ipa-gui/ipagui/static/images/template/background-navbar.png deleted: ipa-server/ipa-gui/ipagui/static/images/template/background-navbar_fullsize.png deleted: ipa-server/ipa-gui/ipagui/static/images/template/background-sidebar.png deleted: ipa-server/ipa-gui/ipagui/static/images/template/background.png deleted: ipa-server/ipa-gui/ipagui/static/images/tg_under_the_hood.png deleted: ipa-server/ipa-gui/ipagui/static/images/under_the_hood_blue.png deleted: ipa-server/ipa-gui/ipagui/static/images/up.gif deleted: ipa-server/ipa-gui/ipagui/static/javascript/Makefile.am deleted: ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js deleted: ipa-server/ipa-gui/ipagui/static/javascript/dynamicselect.js deleted: ipa-server/ipa-gui/ipagui/static/javascript/effects.js deleted: ipa-server/ipa-gui/ipagui/static/javascript/ipautil.js deleted: ipa-server/ipa-gui/ipagui/static/javascript/prototype.js deleted: ipa-server/ipa-gui/ipagui/static/javascript/scriptaculous.js deleted: ipa-server/ipa-gui/ipagui/static/javascript/tablekit.js deleted: ipa-server/ipa-gui/ipagui/subcontrollers/Makefile.am deleted: ipa-server/ipa-gui/ipagui/subcontrollers/__init__.py deleted: ipa-server/ipa-gui/ipagui/subcontrollers/delegation.py deleted: ipa-server/ipa-gui/ipagui/subcontrollers/group.py deleted: ipa-server/ipa-gui/ipagui/subcontrollers/ipacontroller.py deleted: ipa-server/ipa-gui/ipagui/subcontrollers/ipapolicy.py deleted: ipa-server/ipa-gui/ipagui/subcontrollers/policy.py deleted: ipa-server/ipa-gui/ipagui/subcontrollers/principal.py deleted: ipa-server/ipa-gui/ipagui/subcontrollers/user.py deleted: ipa-server/ipa-gui/ipagui/templates/Makefile.am deleted: ipa-server/ipa-gui/ipagui/templates/__init__.py deleted: ipa-server/ipa-gui/ipagui/templates/delegateedit.kid deleted: ipa-server/ipa-gui/ipagui/templates/delegateform.kid deleted: ipa-server/ipa-gui/ipagui/templates/delegategroupsearch.kid deleted: ipa-server/ipa-gui/ipagui/templates/delegatelayout.kid deleted: ipa-server/ipa-gui/ipagui/templates/delegatelist.kid deleted: ipa-server/ipa-gui/ipagui/templates/delegatenew.kid deleted: ipa-server/ipa-gui/ipagui/templates/dynamiceditsearch.kid deleted: ipa-server/ipa-gui/ipagui/templates/groupedit.kid deleted: ipa-server/ipa-gui/ipagui/templates/groupeditform.kid deleted: ipa-server/ipa-gui/ipagui/templates/grouplayout.kid deleted: ipa-server/ipa-gui/ipagui/templates/grouplist.kid deleted: ipa-server/ipa-gui/ipagui/templates/groupnew.kid deleted: ipa-server/ipa-gui/ipagui/templates/groupnewform.kid deleted: ipa-server/ipa-gui/ipagui/templates/groupshow.kid deleted: ipa-server/ipa-gui/ipagui/templates/ipapolicyedit.kid deleted: ipa-server/ipa-gui/ipagui/templates/ipapolicyeditform.kid deleted: ipa-server/ipa-gui/ipagui/templates/ipapolicyshow.kid deleted: ipa-server/ipa-gui/ipagui/templates/loginfailed.kid deleted: ipa-server/ipa-gui/ipagui/templates/master.kid deleted: ipa-server/ipa-gui/ipagui/templates/not_found.kid deleted: ipa-server/ipa-gui/ipagui/templates/policyindex.kid deleted: ipa-server/ipa-gui/ipagui/templates/policylayout.kid deleted: ipa-server/ipa-gui/ipagui/templates/principallayout.kid deleted: ipa-server/ipa-gui/ipagui/templates/principallist.kid deleted: ipa-server/ipa-gui/ipagui/templates/principalnew.kid deleted: ipa-server/ipa-gui/ipagui/templates/principalnewform.kid deleted: ipa-server/ipa-gui/ipagui/templates/principalshow.kid deleted: ipa-server/ipa-gui/ipagui/templates/unhandled_exception.kid deleted: ipa-server/ipa-gui/ipagui/templates/useredit.kid deleted: ipa-server/ipa-gui/ipagui/templates/usereditform.kid deleted: ipa-server/ipa-gui/ipagui/templates/userlayout.kid deleted: ipa-server/ipa-gui/ipagui/templates/userlist.kid deleted: ipa-server/ipa-gui/ipagui/templates/usernew.kid deleted: ipa-server/ipa-gui/ipagui/templates/usernewform.kid deleted: ipa-server/ipa-gui/ipagui/templates/userselectsearch.kid deleted: ipa-server/ipa-gui/ipagui/templates/usershow.kid deleted: ipa-server/ipa-gui/ipagui/templates/welcome.kid deleted: ipa-server/ipa-gui/ipagui/tests/Makefile.am deleted: ipa-server/ipa-gui/ipagui/tests/__init__.py deleted: ipa-server/ipa-gui/ipagui/tests/test_controllers.py deleted: ipa-server/ipa-gui/ipagui/tests/test_model.py deleted: ipa-server/ipa-gui/locales/ja/LC_MESSAGES/messages.po deleted: ipa-server/ipa-gui/locales/messages.pot deleted: ipa-server/ipa-gui/sample-prod.cfg deleted: ipa-server/ipa-gui/setup.py deleted: ipa-server/ipa-gui/start-ipagui.py deleted: ipa-server/ipa-gui/test.cfg deleted: ipa-server/ipa-server.spec.in deleted: ipa-server/xmlrpc-server/Makefile.am deleted: ipa-server/xmlrpc-server/README deleted: ipa-server/xmlrpc-server/attrs.py deleted: ipa-server/xmlrpc-server/funcs.py deleted: ipa-server/xmlrpc-server/ipaxmlrpc.py deleted: ipa-server/xmlrpc-server/test/Makefile.am deleted: ipa-server/xmlrpc-server/test/README deleted: ipa-server/xmlrpc-server/test/test.py deleted: ipa-server/xmlrpc-server/test/test_methods.py deleted: ipa-server/xmlrpc-server/test/test_mod_python.py
Diffstat (limited to 'ipa-server/xmlrpc-server')
-rw-r--r--ipa-server/xmlrpc-server/Makefile.am38
-rw-r--r--ipa-server/xmlrpc-server/README0
-rw-r--r--ipa-server/xmlrpc-server/attrs.py53
-rw-r--r--ipa-server/xmlrpc-server/funcs.py2291
-rw-r--r--ipa-server/xmlrpc-server/ipaxmlrpc.py394
-rw-r--r--ipa-server/xmlrpc-server/test/Makefile.am12
-rw-r--r--ipa-server/xmlrpc-server/test/README60
-rw-r--r--ipa-server/xmlrpc-server/test/test.py41
-rw-r--r--ipa-server/xmlrpc-server/test/test_methods.py57
-rw-r--r--ipa-server/xmlrpc-server/test/test_mod_python.py52
10 files changed, 0 insertions, 2998 deletions
diff --git a/ipa-server/xmlrpc-server/Makefile.am b/ipa-server/xmlrpc-server/Makefile.am
deleted file mode 100644
index 49457ba4c..000000000
--- a/ipa-server/xmlrpc-server/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
-NULL =
-
-SUBDIRS = \
- test \
- $(NULL)
-
-htmldir = $(IPA_DATA_DIR)/html
-html_DATA = \
- ssbrowser.html \
- unauthorized.html \
- $(NULL)
-
-coredir = $(pythondir)/ipaserver
-core_PYTHON = \
- attrs.py \
- funcs.py \
- $(NULL)
-
-serverdir = $(IPA_DATA_DIR)/ipaserver
-server_PYTHON = \
- ipaxmlrpc.py \
- $(NULL)
-
-appdir = $(IPA_DATA_DIR)
-app_DATA = \
- ipa.conf \
- ipa-rewrite.conf \
- $(NULL)
-
-EXTRA_DIST = \
- README \
- $(app_DATA) \
- $(html_DATA) \
- $(NULL)
-
-MAINTAINERCLEANFILES = \
- *~ \
- Makefile.in
diff --git a/ipa-server/xmlrpc-server/README b/ipa-server/xmlrpc-server/README
deleted file mode 100644
index e69de29bb..000000000
--- a/ipa-server/xmlrpc-server/README
+++ /dev/null
diff --git a/ipa-server/xmlrpc-server/attrs.py b/ipa-server/xmlrpc-server/attrs.py
deleted file mode 100644
index 415744a23..000000000
--- a/ipa-server/xmlrpc-server/attrs.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Authors: Rob Crittenden <rcritten@redhat.com>
-#
-# Copyright (C) 2007 Red Hat
-# see file 'COPYING' for use and warranty information
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; version 2 only
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-attr_label_list = {
- "givenname":"First Name",
- "sn":"Last Name",
- "cn":"Full Name",
- "title":"Job Title",
- "displayname":"Display Name",
- "initials":"Initials",
- "uid":"Login",
- "krbprincipalkey":"Password",
- "uidnumber":"UID",
- "gidnumber":"GID",
- "homedirectory":"Home Directory",
- "loginshell":"Login Shell",
- "gecos":"GECOS",
- "mail":"E-mail Address",
- "telephonenumber":"Work Number",
- "facsimiletelephonenumber":"Fax Number",
- "mobile":"Cell Number",
- "homephone":"Home Number",
- "street":"Street Address",
- "l":"City",
- "st":"State",
- "postalcode":"ZIP",
- "ou":"Org Unit",
- "businesscategory":"Tags",
- "description":"Description",
- "employeetype":"Employee Type",
- "manager":"Manager",
- "roomnumber":"Room Number",
- "secretary":"Secretary",
- "carlicense":"Car License",
- "labelduri":"Home Page",
- "nsaccountlock":"Account Status"
-}
diff --git a/ipa-server/xmlrpc-server/funcs.py b/ipa-server/xmlrpc-server/funcs.py
deleted file mode 100644
index cf9e7de58..000000000
--- a/ipa-server/xmlrpc-server/funcs.py
+++ /dev/null
@@ -1,2291 +0,0 @@
-# Authors: Rob Crittenden <rcritten@redhat.com>
-#
-# Copyright (C) 2007 Red Hat
-# see file 'COPYING' for use and warranty information
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; version 2 only
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-import sys
-
-import krbV
-import ldap
-import ldap.dn
-import ipaserver.dsinstance
-import ipaserver.ipaldap
-import copy
-from ipaserver import attrs
-from ipa import version
-from ipa import ipaerror
-from ipa import ipautil
-from urllib import quote,unquote
-from ipa import radius_util
-from ipa import dnsclient
-
-import string
-from types import *
-import re
-import logging
-import subprocess
-
-try:
- from threading import Lock
-except ImportError:
- from dummy_threading import Lock
-
-# Need a global to store this between requests
-_LDAPPool = None
-
-ACIContainer = "cn=accounts"
-DefaultUserContainer = "cn=users,cn=accounts"
-DefaultGroupContainer = "cn=groups,cn=accounts"
-DefaultServiceContainer = "cn=services,cn=accounts"
-
-#
-# Apache runs in multi-process mode so each process will have its own
-# connection. This could theoretically drive the total number of connections
-# very high but since this represents just the administrative interface
-# this is not anticipated.
-#
-# The pool consists of two things, a dictionary keyed on the principal name
-# that contains the connection and a list that is used to keep track of the
-# order. If the list fills up just pop the top entry off and you've got
-# the least recently used.
-
-# maxsize = 0 means no limit
-class IPAConnPool:
- def __init__(self, maxsize = 0):
- self._dict = {}
- self._lru = []
- self._lock = Lock()
- self._maxsize = maxsize
- self._ctx = krbV.default_context()
-
- def getConn(self, host, port, krbccache=None, debug=None):
- conn = None
-
- ccache = krbV.CCache(name=krbccache, context=self._ctx)
- cprinc = ccache.principal()
-
- conn = ipaserver.ipaldap.IPAdmin(host,port,None,None,None,debug)
-
- # This will bind the connection
- try:
- conn.set_krbccache(krbccache, cprinc.name)
- except ldap.UNWILLING_TO_PERFORM:
- raise ipaerror.gen_exception(ipaerror.CONNECTION_UNWILLING)
- except Exception, e:
- raise ipaerror.gen_exception(ipaerror.CONNECTION_NO_CONN, nested_exception=e)
-
- return conn
-
- def releaseConn(self, conn):
- if conn is None:
- return
-
- conn.unbind_s()
-
-class IPAServer:
-
- def __init__(self):
- global _LDAPPool
- # FIXME, this needs to be auto-discovered
- self.host = 'localhost'
- self.port = 389
- self.sslport = 636
- self.bindcert = "/usr/share/ipa/cert.pem"
- self.bindkey = "/usr/share/ipa/key.pem"
- self.bindca = "/usr/share/ipa/cacert.asc"
- self.krbctx = krbV.default_context()
- self.realm = self.krbctx.default_realm
-
- if _LDAPPool is None:
- _LDAPPool = IPAConnPool(128)
- self.basedn = ipautil.realm_to_suffix(self.realm)
- self.accountsdn = "cn=accounts," + self.basedn
- self.scope = ldap.SCOPE_SUBTREE
- self.princ = None
- self.krbccache = None
-
- def set_principal(self, princ):
- self.princ = princ
-
- def set_krbccache(self, krbccache):
- self.krbccache = krbccache
-
- def get_dn_from_principal(self, princ, debug):
- """Given a kerberos principal get the LDAP uid"""
- global _LDAPPool
-
- princ = self.__safe_filter(princ)
- searchfilter = "(krbPrincipalName=" + princ + ")"
- # The only anonymous search we should have
- conn = _LDAPPool.getConn(self.host,self.sslport,self.bindca,self.bindcert,self.bindkey,None,None,debug)
- try:
- ent = conn.getEntry(self.accountsdn, self.scope, searchfilter, ['dn'])
- finally:
- _LDAPPool.releaseConn(conn)
-
- return "dn:" + ent.dn
-
- def __setup_connection(self, opts):
- """Set up common things done in the connection.
- If there is a Kerberos credentials cache then return None as the
- proxy dn and the ccache otherwise return the proxy dn and None as
- the ccache.
-
- We only want one or the other used at one time and we prefer
- the Kerberos credentials cache. So if there is a ccache, return
- that and None for proxy dn to make calling getConn() easier.
- """
-
- debug = "Off"
-
- if opts is not None:
- debug = opts.get('ipadebug')
- if opts.get('krbccache'):
- self.set_krbccache(opts['krbccache'])
- self.set_principal(None)
- else:
- self.set_krbccache(None)
- self.set_principal(opts['remoteuser'])
- else:
- # The caller should have already set the principal or the
- # krbccache. If not they'll get an authentication error later.
- pass
-
- if self.princ is not None:
- return self.get_dn_from_principal(self.princ, debug), None, debug
- else:
- return None, self.krbccache, debug
-
- def getConnection(self, opts):
- """Wrapper around IPAConnPool.getConn() so we don't have to pass
- around self.* every time a connection is needed.
-
- For SASL connections (where we have a krbccache) we can't set
- the SSL variables for certificates. It confuses the ldap
- module.
- """
- global _LDAPPool
-
- (proxy_dn, krbccache, debug) = self.__setup_connection(opts)
-
- if krbccache is not None:
- bindca = None
- bindcert = None
- bindkey = None
- port = self.port
- else:
- raise ipaerror.gen_exception(ipaerror.CONNECTION_NO_CCACHE)
-
- try:
- conn = _LDAPPool.getConn(self.host,port,krbccache,debug)
- except ldap.INVALID_CREDENTIALS, e:
- raise ipaerror.gen_exception(ipaerror.CONNECTION_GSSAPI_CREDENTIALS, nested_exception=e)
-
- if conn is None:
- raise ipaerror.gen_exception(ipaerror.CONNECTION_NO_CONN)
-
- return conn
-
- def releaseConnection(self, conn):
- global _LDAPPool
-
- _LDAPPool.releaseConn(conn)
-
- def convert_entry(self, ent):
- entry = dict(ent.data)
- entry['dn'] = ent.dn
- # For now convert single entry lists to a string for the ui.
- # TODO: we need to deal with multi-values better
- for key,value in entry.iteritems():
- if isinstance(value,list) or isinstance(value,tuple):
- if len(value) == 0:
- entry[key] = ''
- elif len(value) == 1:
- entry[key] = value[0]
- return entry
-
- # TODO: rethink the get_entry vs get_list API calls.
- # they currently restrict the data coming back without
- # restricting scope. For now adding a __get_base/sub_entry()
- # calls, but the API isn't great.
- def __get_entry (self, base, scope, searchfilter, sattrs=None, opts=None):
- """Get a specific entry (with a parametized scope).
- Return as a dict of values.
- Multi-valued fields are represented as lists.
- """
- ent=""
-
- conn = self.getConnection(opts)
- try:
- ent = conn.getEntry(base, scope, searchfilter, sattrs)
-
- finally:
- self.releaseConnection(conn)
-
- return self.convert_entry(ent)
-
- def __get_base_entry (self, base, searchfilter, sattrs=None, opts=None):
- """Get a specific entry (with a scope of BASE).
- Return as a dict of values.
- Multi-valued fields are represented as lists.
- """
- return self.__get_entry(base, ldap.SCOPE_BASE, searchfilter, sattrs, opts)
-
- def __get_sub_entry (self, base, searchfilter, sattrs=None, opts=None):
- """Get a specific entry (with a scope of SUB).
- Return as a dict of values.
- Multi-valued fields are represented as lists.
- """
- return self.__get_entry(base, ldap.SCOPE_SUBTREE, searchfilter, sattrs, opts)
-
- def __get_list (self, base, searchfilter, sattrs=None, opts=None):
- """Gets a list of entries. Each is converted to a dict of values.
- Multi-valued fields are represented as lists.
- """
- entries = []
-
- conn = self.getConnection(opts)
- try:
- entries = conn.getList(base, self.scope, searchfilter, sattrs)
- finally:
- self.releaseConnection(conn)
-
- return map(self.convert_entry, entries)
-
- def __update_entry (self, oldentry, newentry, opts=None):
- """Update an LDAP entry
-
- oldentry is a dict
- newentry is a dict
- """
- oldentry = self.convert_scalar_values(oldentry)
- newentry = self.convert_scalar_values(newentry)
-
- # Should be able to get this from either the old or new entry
- # but just in case someone has decided to try changing it, use the
- # original
- try:
- moddn = oldentry['dn']
- except KeyError:
- raise ipaerror.gen_exception(ipaerror.LDAP_MISSING_DN)
-
- conn = self.getConnection(opts)
- try:
- res = conn.updateEntry(moddn, oldentry, newentry)
- finally:
- self.releaseConnection(conn)
- return res
-
- def __safe_filter(self, criteria):
- """Make sure any arguments used when creating a filter are safe."""
-
- # TODO: this escaper assumes the python-ldap library will error out
- # on invalid codepoints. we need to check malformed utf-8 input
- # where the second byte in a multi-byte character
- # is (illegally) ')' and make sure python-ldap
- # bombs out.
- criteria = re.sub(r'[\(\)\\\*]', ldap_search_escape, criteria)
-
- return criteria
-
- def __generate_match_filters(self, search_fields, criteria_words):
- """Generates a search filter based on a list of words and a list
- of fields to search against.
-
- Returns a tuple of two filters: (exact_match, partial_match)"""
-
- # construct search pattern for a single word
- # (|(f1=word)(f2=word)...)
- search_pattern = "(|"
- for field in search_fields:
- search_pattern += "(" + field + "=%(match)s)"
- search_pattern += ")"
- gen_search_pattern = lambda word: search_pattern % {'match':word}
-
- # construct the giant match for all words
- exact_match_filter = "(&"
- partial_match_filter = "(|"
- for word in criteria_words:
- exact_match_filter += gen_search_pattern(word)
- partial_match_filter += gen_search_pattern("*%s*" % word)
- exact_match_filter += ")"
- partial_match_filter += ")"
-
- return (exact_match_filter, partial_match_filter)
-
- def __get_schema(self, opts=None):
- """Retrieves the current LDAP schema from the LDAP server."""
-
- schema_entry = self.__get_base_entry("", "objectclass=*", ['dn','subschemasubentry'], opts)
- schema_cn = schema_entry.get('subschemasubentry')
- schema = self.__get_base_entry(schema_cn, "objectclass=*", ['*'], opts)
-
- return schema
-
- def __get_objectclasses(self, opts=None):
- """Returns a list of available objectclasses that the LDAP
- server supports. This parses out the syntax, attributes, etc
- and JUST returns a lower-case list of the names."""
-
- schema = self.__get_schema(opts)
-
- objectclasses = schema.get('objectclasses')
-
- # Convert this list into something more readable
- result = []
- for i in range(len(objectclasses)):
- oc = objectclasses[i].lower().split(" ")
- result.append(oc[3].replace("'",""))
-
- return result
-
- def __has_nsaccountlock(self, dn, opts):
- """Check to see if an entry has the nsaccountlock attribute.
- This attribute is provided by the Class of Service plugin so
- doing a search isn't enough. It is provided by the two
- entries cn=inactivated and cn=activated. So if the entry has
- the attribute and isn't in either cn=activated or cn=inactivated
- then the attribute must be in the entry itself.
-
- Returns True or False
- """
- # First get the entry. If it doesn't have nsaccountlock at all we
- # can exit early.
- entry = self.get_entry_by_dn(dn, ['dn', 'nsaccountlock', 'memberof'], opts)
- if not entry.get('nsaccountlock'):
- return False
-
- # Now look to see if they are in activated or inactivated
- # entry is a member
- memberof = entry.get('memberof')
- if isinstance(memberof, basestring):
- memberof = [memberof]
- for m in memberof:
- inactivated = m.find("cn=inactivated")
- activated = m.find("cn=activated")
- # if they are in either group that means that the nsaccountlock
- # value comes from there, otherwise it must be in this entry.
- if inactivated >= 0 or activated >= 0:
- return False
-
- return True
-
-# Higher-level API
- def version(self, opts=None):
- """The version of IPA"""
- logging.debug("IPA: version %d" % version.NUM_VERSION)
- return version.NUM_VERSION
-
- def get_aci_entry(self, sattrs, opts=None):
- """Returns the entry containing access control ACIs."""
-
- if sattrs is not None and not isinstance(sattrs,list):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- logging.info("IPA: get_aci_entry")
-
- dn="%s,%s" % (ACIContainer, self.basedn)
- return self.get_entry_by_dn(dn, sattrs, opts)
-
-# General searches
-
- def get_entry_by_dn (self, dn, sattrs, opts=None):
- """Get a specific entry. Return as a dict of values.
- Multi-valued fields are represented as lists.
- """
- if not isinstance(dn,basestring) or len(dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if sattrs is not None and not isinstance(sattrs,list):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- searchfilter = "(objectClass=*)"
- logging.info("IPA: get_entry_by_dn '%s'" % dn)
- return self.__get_base_entry(dn, searchfilter, sattrs, opts)
-
- def get_entry_by_cn (self, cn, sattrs, opts=None):
- """Get a specific entry by cn. Return as a dict of values.
- Multi-valued fields are represented as lists.
- """
-
- if not isinstance(cn,basestring) or len(cn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if sattrs is not None and not isinstance(sattrs,list):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- logging.info("IPA: get_entry_by_cn '%s'" % cn)
- cn = self.__safe_filter(cn)
- searchfilter = "(cn=" + cn + ")"
- return self.__get_sub_entry(self.accountsdn, searchfilter, sattrs, opts)
-
- def update_entry (self, oldentry, newentry, opts=None):
- """Update an entry in LDAP
-
- oldentry and newentry are XML-RPC structs.
-
- If oldentry is not empty then it is used when determine what
- has changed.
-
- If oldentry is empty then the value of newentry is compared
- to the current value of oldentry.
- """
- if not newentry:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- if not oldentry:
- oldentry = self.get_entry_by_dn(newentry.get('dn'), None, opts)
- if oldentry is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
- logging.info("IPA: update_entry '%s'" % newentry.get('dn'))
- return self.__update_entry(oldentry, newentry, opts)
-
-# User support
-
- def __is_user_unique(self, uid, opts):
- """Return True if the uid is unique in the tree, False otherwise."""
- uid = self.__safe_filter(uid)
- searchfilter = "(&(uid=%s)(objectclass=posixAccount))" % uid
-
- try:
- entry = self.__get_sub_entry(self.accountsdn, searchfilter, ['dn','uid'], opts)
- return False
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- return True
-
- def __uid_too_long(self, uid, opts):
- """Verify that the new uid is within the limits we set. This is a
- very narrow test.
-
- Returns True if it is longer than allowed
- False otherwise
- """
- if not isinstance(uid,basestring) or len(uid) == 0:
- # It is bad, but not too long
- return False
- logging.debug("IPA: __uid_too_long(%s)" % uid)
- try:
- config = self.get_ipa_config(opts)
- maxlen = int(config.get('ipamaxusernamelength', 0))
- if maxlen > 0 and len(uid) > maxlen:
- return True
- except Exception, e:
- logging.debug("There was a problem " + str(e))
-
- return False
-
- def get_user_by_uid (self, uid, sattrs, opts=None):
- """Get a specific user's entry. Return as a dict of values.
- Multi-valued fields are represented as lists.
- """
-
- if not isinstance(uid,basestring) or len(uid) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if sattrs is not None and not isinstance(sattrs,list):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- logging.info("IPA: get_user_by_uid '%s'" % uid)
- uid = self.__safe_filter(uid)
- searchfilter = "(uid=" + uid + ")"
- return self.__get_sub_entry(self.accountsdn, searchfilter, sattrs, opts)
-
- def get_user_by_principal(self, principal, sattrs, opts=None):
- """Get a user entry searching by Kerberos Principal Name.
- Return as a dict of values. Multi-valued fields are
- represented as lists.
- """
-
- if not isinstance(principal,basestring) or len(principal) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if sattrs is not None and not isinstance(sattrs,list):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- searchfilter = "(krbPrincipalName="+self.__safe_filter(principal)+")"
- logging.info("IPA: get_user_by_principal '%s'" % principal)
- return self.__get_sub_entry(self.accountsdn, searchfilter, sattrs, opts)
-
- def get_user_by_email (self, email, sattrs, opts=None):
- """Get a specific user's entry. Return as a dict of values.
- Multi-valued fields are represented as lists.
- """
-
- if not isinstance(email,basestring) or len(email) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if sattrs is not None and not isinstance(sattrs,list):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- logging.info("IPA: get_user_by_email '%s'" % email)
- email = self.__safe_filter(email)
- searchfilter = "(mail=" + email + ")"
- return self.__get_sub_entry(self.basedn, searchfilter, sattrs, opts)
-
- def get_users_by_manager (self, manager_dn, sattrs, opts=None):
- """Gets the users that report to a particular manager.
- """
-
- if not isinstance(manager_dn,basestring) or len(manager_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if sattrs is not None and not isinstance(sattrs,list):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- logging.info("IPA: get_user_by_manager '%s'" % manager_dn)
- manager_dn = self.__safe_filter(manager_dn)
- searchfilter = "(&(objectClass=person)(manager=%s))" % manager_dn
-
- try:
- return self.__get_list(self.accountsdn, searchfilter, sattrs, opts)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- return []
-
- def add_user (self, user, user_container, opts=None):
- """Add a user in LDAP. Takes as input a dict where the key is the
- attribute name and the value is either a string or in the case
- of a multi-valued field a list of values. user_container sets
- where in the tree the user is placed.
- """
- logging.info("IPA: add_user")
- if not user_container:
- user_container = DefaultUserContainer
-
- if not isinstance(user,dict):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(user_container,basestring) or len(user_container) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- if not self.__is_user_unique(user['uid'], opts):
- raise ipaerror.gen_exception(ipaerror.LDAP_DUPLICATE)
- if self.__uid_too_long(user['uid'], opts):
- raise ipaerror.gen_exception(ipaerror.INPUT_UID_TOO_LONG)
-
- # dn is set here, not by the user
- try:
- del user['dn']
- except KeyError:
- pass
-
- # No need to set empty fields, and they can cause issues when they
- # get to LDAP, like:
- # TypeError: ('expected a string in the list', None)
- for k in user.keys():
- if not user[k] or len(user[k]) == 0 or (isinstance(user[k],list) and len(user[k]) == 1 and '' in user[k]):
- del user[k]
-
- dn="uid=%s,%s,%s" % (ldap.dn.escape_dn_chars(user['uid']),
- user_container,self.basedn)
- entry = ipaserver.ipaldap.Entry(dn)
-
- # FIXME: This should be dynamic and can include just about anything
-
- # Get our configuration
- config = self.get_ipa_config(opts)
-
- # Let us add in some missing attributes
- if user.get('homedirectory') is None:
- user['homedirectory'] = '%s/%s' % (config.get('ipahomesrootdir'), user.get('uid'))
- user['homedirectory'] = user['homedirectory'].replace('//', '/')
- user['homedirectory'] = user['homedirectory'].rstrip('/')
- if user.get('loginshell') is None:
- user['loginshell'] = config.get('ipadefaultloginshell')
- if user.get('gecos') is None:
- user['gecos'] = user['uid']
-
- # If uidnumber is blank the the FDS dna_plugin will automatically
- # assign the next value. So we don't have to do anything with it.
-
- group_dn="cn=%s,%s,%s" % (config.get('ipadefaultprimarygroup'), DefaultGroupContainer, self.basedn)
- try:
- default_group = self.get_entry_by_dn(group_dn, ['dn','gidNumber'], opts)
- if default_group:
- user['gidnumber'] = default_group.get('gidnumber')
- except ipaerror.exception_for(ipaerror.LDAP_DATABASE_ERROR), e:
- raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, message=None, nested_exception=e.detail)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- # Fake an LDAP error so we can return something useful to the user
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND, "The default group for new users, '%s', cannot be found." % config.get('ipadefaultprimarygroup'))
-
- if user.get('krbprincipalname') is None:
- user['krbprincipalname'] = "%s@%s" % (user.get('uid'), self.realm)
-
- # FIXME. This is a hack so we can request separate First and Last
- # name in the GUI.
- if user.get('cn') is None:
- user['cn'] = "%s %s" % (user.get('givenname'),
- user.get('sn'))
-
- if user.get('gn'):
- del user['gn']
-
- # some required objectclasses
- entry.setValues('objectClass', (config.get('ipauserobjectclasses')))
-
- # fill in our new entry with everything sent by the user
- for u in user:
- entry.setValues(u, user[u])
-
- conn = self.getConnection(opts)
- try:
- try:
- res = conn.addEntry(entry)
- except TypeError, e:
- raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, "There is a problem with one of the data types.")
- except ipaerror.exception_for(ipaerror.LDAP_DATABASE_ERROR), e:
- raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, message=None, nested_exception=e.detail)
- except Exception, e:
- raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, nested_exception=e)
- try:
- self.add_user_to_group(user.get('uid'), group_dn, opts)
- except ipaerror.exception_for(ipaerror.LDAP_DATABASE_ERROR), e:
- raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, message=None, nested_exception=e.detail)
- except Exception, e:
- raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, "The user was created but adding to group %s failed" % group_dn)
- finally:
- self.releaseConnection(conn)
- return res
-
- def get_custom_fields (self, opts=None):
- """Get the list of custom user fields.
-
- A schema is a list of dict's of the form:
- label: The label dispayed to the user
- field: the attribute name
- required: true/false
-
- It is displayed to the user in the order of the list.
- """
-
- config = self.get_ipa_config(opts)
-
- fields = config.get('ipacustomfields')
-
- if fields is None or fields == '':
- return []
-
- fl = fields.split('$')
- schema = []
- for x in range(len(fl)):
- vals = fl[x].split(',')
- if len(vals) != 3:
- # Raise?
- logging.debug("IPA: Invalid field, skipping: %s", vals)
- d = dict(label=unquote(vals[0]), field=unquote(vals[1]), required=unquote(vals[2]))
- schema.append(d)
-
- return schema
-# radius support
-
- # clients
- def get_radius_client_by_ip_addr(self, ip_addr, container=None, sattrs=None, opts=None):
- filter = radius_util.radius_client_filter(ip_addr)
- basedn = radius_util.radius_clients_basedn(container, self.basedn)
- return self.__get_sub_entry(basedn, filter, sattrs, opts)
-
- def __radius_client_exists(self, ip_addr, container, opts):
- filter = radius_util.radius_client_filter(ip_addr)
- basedn = radius_util.radius_clients_basedn(container, self.basedn)
-
- try:
- entry = self.__get_sub_entry(basedn, filter, ['dn','uid'], opts)
- return True
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- return False
-
- def add_radius_client (self, client, container=None, opts=None):
- if container is None:
- container = radius_util.clients_container
-
- ip_addr = client['radiusClientIPAddress']
-
- if self.__radius_client_exists(ip_addr, container, opts):
- raise ipaerror.gen_exception(ipaerror.LDAP_DUPLICATE)
-
- dn = radius_util.radius_client_dn(ip_addr, container, self.basedn)
- entry = ipaserver.ipaldap.Entry(dn)
-
- # some required objectclasses
- entry.setValues('objectClass', 'top', 'radiusClientProfile')
-
- # fill in our new entry with everything sent by the client
- for attr in client:
- entry.setValues(attr, client[attr])
-
- conn = self.getConnection(opts)
- try:
- res = conn.addEntry(entry)
- finally:
- self.releaseConnection(conn)
- return res
-
- def update_radius_client(self, oldentry, newentry, opts=None):
- return self.update_entry(oldentry, newentry, opts)
-
- def delete_radius_client(self, ip_addr, container=None, opts=None):
- client = self.get_radius_client_by_ip_addr(ip_addr, container, ['dn', 'cn'], opts)
- if client is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
- conn = self.getConnection(opts)
- try:
- res = conn.deleteEntry(client['dn'])
- finally:
- self.releaseConnection(conn)
- return res
-
- def find_radius_clients(self, ip_attrs, container=None, sattrs=None, sizelimit=-1, timelimit=-1, opts=None):
- def gen_filter(objectclass, attr, values):
- '''Given ('myclass', 'myattr', [v1, v2]) returns
- (&(objectclass=myclass)(|(myattr=v1)(myattr=v2)))
- '''
- # Don't use __safe_filter, prevents wildcarding
- #attrs = ''.join(['(%s=%s)' % (attr, self.__safe_filter(val)) for val in values])
- attrs = ''.join(['(%s=%s)' % (attr, val) for val in values])
- filter = "(&(objectclass=%s)(|%s))" % (objectclass, attrs)
- return filter
-
- basedn = radius_util.radius_clients_basedn(container, self.basedn)
- filter = gen_filter('radiusClientProfile', 'radiusClientIPAddress', ip_attrs)
- conn = self.getConnection(opts)
- try:
- try:
- results = conn.getListAsync(basedn, self.scope, filter, sattrs, 0, None, None, timelimit, sizelimit)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- results = [0]
- finally:
- self.releaseConnection(conn)
-
- counter = results[0]
- results = results[1:]
- radius_clients = [counter]
- for radius_client in results:
- radius_clients.append(self.convert_entry(radius_client))
-
- return radius_clients
-
- # profiles
- def get_radius_profile_by_uid(self, uid, user_profile=True, sattrs=None, opts=None):
- if user_profile:
- container = DefaultUserContainer
- else:
- container = radius_util.profiles_container
-
- uid = self.__safe_filter(uid)
- filter = radius_util.radius_profile_filter(uid)
- basedn = radius_util.radius_profiles_basedn(container, self.basedn)
- return self.__get_sub_entry(basedn, filter, sattrs, opts)
-
- def __radius_profile_exists(self, uid, user_profile, opts):
- if user_profile:
- container = DefaultUserContainer
- else:
- container = radius_util.profiles_container
-
- uid = self.__safe_filter(uid)
- filter = radius_util.radius_profile_filter(uid)
- basedn = radius_util.radius_profiles_basedn(container, self.basedn)
-
- try:
- entry = self.__get_sub_entry(basedn, filter, ['dn','uid'], opts)
- return True
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- return False
-
- def add_radius_profile (self, profile, user_profile=True, opts=None):
- uid = profile['uid']
-
- if self.__radius_profile_exists(uid, user_profile, opts):
- raise ipaerror.gen_exception(ipaerror.LDAP_DUPLICATE)
-
- if user_profile:
- container = DefaultUserContainer
- else:
- container = radius_util.profiles_container
-
- dn = radius_util.radius_profile_dn(uid, container, self.basedn)
- entry = ipaserver.ipaldap.Entry(dn)
-
- # some required objectclasses
- entry.setValues('objectClass', 'top', 'radiusprofile')
-
- # fill in our new entry with everything sent by the profile
- for attr in profile:
- entry.setValues(attr, profile[attr])
-
- conn = self.getConnection(opts)
- try:
- res = conn.addEntry(entry)
- finally:
- self.releaseConnection(conn)
- return res
-
- def update_radius_profile(self, oldentry, newentry, opts=None):
- return self.update_entry(oldentry, newentry, opts)
-
- def delete_radius_profile(self, uid, user_profile, opts=None):
- profile = self.get_radius_profile_by_uid(uid, user_profile, ['dn', 'cn'], opts)
- if profile is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
- conn = self.getConnection(opts)
- try:
- res = conn.deleteEntry(profile['dn'])
- finally:
- self.releaseConnection(conn)
- return res
-
- def find_radius_profiles(self, uids, user_profile=True, sattrs=None, sizelimit=-1, timelimit=-1, opts=None):
- def gen_filter(objectclass, attr, values):
- '''Given ('myclass', 'myattr', [v1, v2]) returns
- (&(objectclass=myclass)(|(myattr=v1)(myattr=v2)))
- '''
- # Don't use __safe_filter, prevents wildcarding
- #attrs = ''.join(['(%s=%s)' % (attr, self.__safe_filter(val)) for val in values])
- attrs = ''.join(['(%s=%s)' % (attr, val) for val in values])
- filter = "(&(objectclass=%s)(|%s))" % (objectclass, attrs)
- return filter
-
- if user_profile:
- container = DefaultUserContainer
- else:
- container = radius_util.profiles_container
-
- filter = gen_filter('radiusprofile', 'uid', uids)
- basedn="%s,%s" % (container, self.basedn)
- conn = self.getConnection(opts)
- try:
- try:
- results = conn.getListAsync(basedn, self.scope, filter, sattrs, 0, None, None, timelimit, sizelimit)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- results = [0]
- finally:
- self.releaseConnection(conn)
-
- counter = results[0]
- results = results[1:]
- radius_profiles = [counter]
- for radius_profile in results:
- radius_profiles.append(self.convert_entry(radius_profile))
-
- return radius_profiles
-
- def set_custom_fields (self, schema, opts=None):
- """Set the list of custom user fields.
-
- A schema is a list of dict's of the form:
- label: The label dispayed to the user
- field: the attribute name
- required: true/false
-
- It is displayed to the user in the order of the list.
- """
- if not isinstance(schema,basestring) or len(schema) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- config = self.get_ipa_config(opts)
-
- # The schema is stored as:
- # label,field,required$label,field,required$...
- # quote() from urilib is used to ensure that it is easy to unparse
-
- stored_schema = ""
- for i in range(len(schema)):
- entry = schema[i]
- entry = quote(entry.get('label')) + "," + quote(entry.get('field')) + "," + quote(entry.get('required'))
-
- if stored_schema != "":
- stored_schema = stored_schema + "$" + entry
- else:
- stored_schema = entry
-
- new_config = copy.deepcopy(config)
- new_config['ipacustomfields'] = stored_schema
-
- return self.update_entry(config, new_config, opts)
-
- def get_all_users (self, opts=None):
- """Return a list containing a User object for each
- existing user.
- """
- logging.info("IPA: get_all_users")
- searchfilter = "(objectclass=posixAccount)"
-
- conn = self.getConnection(opts)
- try:
- all_users = conn.getList(self.accountsdn, self.scope, searchfilter, None)
- finally:
- self.releaseConnection(conn)
-
- users = []
- for u in all_users:
- users.append(self.convert_entry(u))
-
- return users
-
- def find_users (self, criteria, sattrs, sizelimit=-1, timelimit=-1,
- opts=None):
- """Returns a list: counter followed by the results.
- If the results are truncated, counter will be set to -1."""
-
- if not isinstance(criteria,basestring) or len(criteria) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if sattrs is not None and not isinstance(sattrs, list):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(sizelimit,int):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(timelimit,int):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- logging.info("IPA: find_users '%s'" % criteria)
- config = self.get_ipa_config(opts)
- if timelimit < 0:
- timelimit = float(config.get('ipasearchtimelimit'))
- if sizelimit < 0:
- sizelimit = int(config.get('ipasearchrecordslimit'))
-
- # Assume the list of fields to search will come from a central
- # configuration repository. A good format for that would be
- # a comma-separated list of fields
- search_fields_conf_str = config.get('ipausersearchfields')
- search_fields = string.split(search_fields_conf_str, ",")
-
- criteria = self.__safe_filter(criteria)
- criteria_words = re.split(r'\s+', criteria)
- criteria_words = filter(lambda value:value!="", criteria_words)
- if len(criteria_words) == 0:
- return [0]
-
- (exact_match_filter, partial_match_filter) = self.__generate_match_filters(
- search_fields, criteria_words)
-
- #
- # further constrain search to just the objectClass
- # TODO - need to parameterize this into generate_match_filters,
- # and work it into the field-specification search feature
- #
- exact_match_filter = "(&(objectClass=person)%s)" % exact_match_filter
- partial_match_filter = "(&(objectClass=person)%s)" % partial_match_filter
-
- conn = self.getConnection(opts)
- try:
- try:
- exact_results = conn.getListAsync(self.accountsdn, self.scope,
- exact_match_filter, sattrs, 0, None, None, timelimit,
- sizelimit)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- exact_results = [0]
-
- try:
- partial_results = conn.getListAsync(self.accountsdn, self.scope,
- partial_match_filter, sattrs, 0, None, None, timelimit,
- sizelimit)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- partial_results = [0]
- finally:
- self.releaseConnection(conn)
-
- exact_counter = exact_results[0]
- partial_counter = partial_results[0]
-
- exact_results = exact_results[1:]
- partial_results = partial_results[1:]
-
- # Remove exact matches from the partial_match list
- exact_dns = set(map(lambda e: e.dn, exact_results))
- partial_results = filter(lambda e: e.dn not in exact_dns,
- partial_results)
-
- if (exact_counter == -1) or (partial_counter == -1):
- counter = -1
- else:
- counter = len(exact_results) + len(partial_results)
-
- users = [counter]
- for u in exact_results + partial_results:
- users.append(self.convert_entry(u))
-
- return users
-
- def convert_scalar_values(self, orig_dict):
- """LDAP update dicts expect all values to be a list (except for dn).
- This method converts single entries to a list."""
- if not orig_dict or not isinstance(orig_dict, dict):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- new_dict={}
- for (k,v) in orig_dict.iteritems():
- if not isinstance(v, list) and k != 'dn':
- v = [v]
- new_dict[k] = v
-
- return new_dict
-
- def update_user (self, oldentry, newentry, opts=None):
- """Wrapper around update_entry with user-specific handling.
-
- oldentry and newentry are XML-RPC structs.
-
- If oldentry is not empty then it is used when determine what
- has changed.
-
- If oldentry is empty then the value of newentry is compared
- to the current value of oldentry.
-
- If you want to change the RDN of a user you must use
- this function. update_entry will fail.
- """
- logging.info("IPA: update_user")
- if not isinstance(newentry,dict):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if oldentry and not isinstance(oldentry,dict):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not oldentry:
- oldentry = self.get_entry_by_dn(newentry.get('dn'), None, opts)
- if oldentry is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
- newrdn = 0
-
- if oldentry.get('uid') != newentry.get('uid'):
- if self.__uid_too_long(newentry.get('uid'), opts):
- raise ipaerror.gen_exception(ipaerror.INPUT_UID_TOO_LONG)
- # RDN change
- conn = self.getConnection(opts)
- try:
- res = conn.updateRDN(oldentry.get('dn'), "uid=" + newentry.get('uid'))
- newdn = oldentry.get('dn')
- newdn = newdn.replace("uid=%s" % oldentry.get('uid'), "uid=%s" % newentry.get('uid'))
-
- # Now fix up the dns and uids so they aren't seen as having
- # changed.
- oldentry['dn'] = newdn
- newentry['dn'] = newdn
- oldentry['uid'] = newentry['uid']
- newrdn = 1
- finally:
- self.releaseConnection(conn)
-
- # Get our configuration
- config = self.get_ipa_config(opts)
-
- # Make sure we have the latest object classes
- # newentry['objectclass'] = uniq_list(newentry.get('objectclass') + config.get('ipauserobjectclasses'))
-
- try:
- rv = self.update_entry(oldentry, newentry, opts)
- return rv
- except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
- # This means that there was just an rdn change, nothing else.
- if newrdn == 1:
- return "Success"
- else:
- raise
-
- def mark_entry_active (self, dn, opts=None):
- """Mark an entry as active in LDAP."""
-
- # This can be tricky. The entry itself can be marked inactive
- # by being in the inactivated group. It can also be inactivated by
- # being the member of an inactive group.
- #
- # First we try to remove the entry from the inactivated group. Then
- # if it is still inactive we have to add it to the activated group
- # which will override the group membership.
-
- if not dn:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- res = ""
- # First, check the entry status
- entry = self.get_entry_by_dn(dn, ['dn', 'nsAccountlock'], opts)
-
- if entry.get('nsaccountlock', 'false').lower() == "false":
- logging.debug("IPA: already active")
- raise ipaerror.gen_exception(ipaerror.STATUS_ALREADY_ACTIVE)
-
- if self.__has_nsaccountlock(dn, opts):
- logging.debug("IPA: appears to have the nsaccountlock attribute")
- raise ipaerror.gen_exception(ipaerror.STATUS_HAS_NSACCOUNTLOCK)
-
- group = self.get_entry_by_cn("inactivated", None, opts)
- try:
- self.remove_member_from_group(entry.get('dn'), group.get('dn'), opts)
- except ipaerror.exception_for(ipaerror.STATUS_NOT_GROUP_MEMBER):
- # Perhaps the user is there as a result of group membership
- pass
-
- # Now they aren't a member of inactivated directly, what is the status
- # now?
- entry = self.get_entry_by_dn(dn, ['dn', 'nsAccountlock'], opts)
-
- if entry.get('nsaccountlock', 'false').lower() == "false":
- # great, we're done
- logging.debug("IPA: removing from inactivated did it.")
- return res
-
- # So still inactive, add them to activated
- group = self.get_entry_by_cn("activated", None, opts)
- res = self.add_member_to_group(dn, group.get('dn'), opts)
- logging.debug("IPA: added to activated.")
-
- return res
-
- def mark_entry_inactive (self, dn, opts=None):
- """Mark an entry as inactive in LDAP."""
-
- if not dn:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- entry = self.get_entry_by_dn(dn, ['dn', 'nsAccountlock', 'memberOf'], opts)
-
- if entry.get('nsaccountlock', 'false').lower() == "true":
- logging.debug("IPA: already marked as inactive")
- raise ipaerror.gen_exception(ipaerror.STATUS_ALREADY_INACTIVE)
-
- if self.__has_nsaccountlock(dn, opts):
- logging.debug("IPA: appears to have the nsaccountlock attribute")
- raise ipaerror.gen_exception(ipaerror.STATUS_HAS_NSACCOUNTLOCK)
-
- # First see if they are in the activated group as this will override
- # the our inactivation.
- group = self.get_entry_by_cn("activated", None, opts)
- try:
- self.remove_member_from_group(dn, group.get('dn'), opts)
- except ipaerror.exception_for(ipaerror.STATUS_NOT_GROUP_MEMBER):
- # this is fine, they may not be explicitly in this group
- pass
-
- # Now add them to inactivated
- group = self.get_entry_by_cn("inactivated", None, opts)
- res = self.add_member_to_group(dn, group.get('dn'), opts)
-
- return res
-
- def mark_user_active(self, uid, opts=None):
- """Mark a user as active"""
-
- if not isinstance(uid,basestring) or len(uid) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- user = self.get_user_by_uid(uid, ['dn', 'uid'], opts)
- logging.info("IPA: mark_user_active '%s'" % user.get('dn'))
- return self.mark_entry_active(user.get('dn'))
-
- def mark_user_inactive(self, uid, opts=None):
- """Mark a user as inactive"""
-
- if not isinstance(uid,basestring) or len(uid) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if uid == "admin":
- raise ipaerror.gen_exception(ipaerror.INPUT_CANT_INACTIVATE)
- user = self.get_user_by_uid(uid, ['dn', 'uid'], opts)
- logging.info("IPA: mark_user_inactive '%s'" % user.get('dn'))
- return self.mark_entry_inactive(user.get('dn'))
-
- def delete_user (self, uid, opts=None):
- """Delete a user. Not to be confused with inactivate_user. This
- makes the entry go away completely.
-
- uid is the uid of the user to delete
-
- The memberOf plugin handles removing the user from any other
- groups.
- """
- if not isinstance(uid,basestring) or len(uid) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if uid == "admin":
- raise ipaerror.gen_exception(ipaerror.INPUT_ADMIN_REQUIRED)
- logging.info("IPA: delete_user '%s'" % uid)
- user = self.get_user_by_uid(uid, ['dn', 'uid', 'objectclass'], opts)
- if user is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
- conn = self.getConnection(opts)
- try:
- res = conn.deleteEntry(user['dn'])
- finally:
- self.releaseConnection(conn)
- return res
-
- def modifyPassword (self, principal, oldpass, newpass, opts=None):
- """Set/Reset a user's password
-
- uid tells us who's password to change
- oldpass is the old password (if available)
- newpass is the new password
- """
- if not isinstance(principal,basestring) or len(principal) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if oldpass and not isinstance(oldpass,basestring):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(newpass,basestring) or len(newpass) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- logging.info("IPA: modifyPassword '%s'" % principal)
-
- user = self.get_user_by_principal(principal, ['krbprincipalname'], opts)
- if user is None or user['krbprincipalname'] != principal:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
- conn = self.getConnection(opts)
- try:
- res = conn.modifyPassword(user['dn'], oldpass, newpass)
- finally:
- self.releaseConnection(conn)
- return res
-
-# Group support
-
- def __is_group_unique(self, cn, opts):
- """Return True if the cn is unique in the tree, False otherwise."""
- cn = self.__safe_filter(cn)
- searchfilter = "(&(cn=%s)(objectclass=posixGroup))" % cn
-
- try:
- entry = self.__get_sub_entry(self.accountsdn, searchfilter, ['dn','cn'], opts)
- return False
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- return True
-
- def get_groups_by_member (self, member_dn, sattrs, opts=None):
- """Get all of the groups an object is explicitly a member of.
-
- This does not include groups an entry may be a member of as a
- result of recursion (being a group that is a member of another
- group). In other words, this searches on 'member' and not
- 'memberof'.
-
- Return as a dict of values.
- Multi-valued fields are represented as lists.
- """
- if not isinstance(member_dn,basestring) or len(member_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if sattrs is not None and not isinstance(sattrs,list):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- logging.info("IPA: get_groups_by_member '%s'" % member_dn)
-
- member_dn = self.__safe_filter(member_dn)
- searchfilter = "(&(objectClass=posixGroup)(member=%s))" % member_dn
-
- try:
- return self.__get_list(self.accountsdn, searchfilter, sattrs, opts)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- return []
-
- def add_group (self, group, group_container, opts=None):
- """Add a group in LDAP. Takes as input a dict where the key is the
- attribute name and the value is either a string or in the case
- of a multi-valued field a list of values. group_container sets
- where in the tree the group is placed."""
- if not group_container:
- group_container = DefaultGroupContainer
-
- if not isinstance(group,dict):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(group_container,basestring) or len(group_container) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- if not self.__is_group_unique(group['cn'], opts):
- raise ipaerror.gen_exception(ipaerror.LDAP_DUPLICATE)
-
- # Get our configuration
- config = self.get_ipa_config(opts)
-
- dn="cn=%s,%s,%s" % (ldap.dn.escape_dn_chars(group['cn']),
- group_container,self.basedn)
- logging.info("IPA: add_group '%s'" % dn)
- entry = ipaserver.ipaldap.Entry(dn)
-
- # some required objectclasses
- entry.setValues('objectClass', (config.get('ipagroupobjectclasses')))
-
- # No need to explicitly set gidNumber. The dna_plugin will do this
- # for us if the value isn't provided by the user.
-
- # fill in our new entry with everything sent by the user
- for g in group:
- entry.setValues(g, group[g])
-
- conn = self.getConnection(opts)
- try:
- res = conn.addEntry(entry)
- finally:
- self.releaseConnection(conn)
-
- def find_groups (self, criteria, sattrs, sizelimit=-1, timelimit=-1,
- opts=None):
- """Return a list containing a User object for each
- existing group that matches the criteria.
- """
- if not isinstance(criteria,basestring) or len(criteria) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if sattrs is not None and not isinstance(sattrs, list):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(sizelimit,int):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(timelimit,int):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- logging.info("IPA: find groups '%s'" % criteria)
-
- config = self.get_ipa_config(opts)
- if timelimit < 0:
- timelimit = float(config.get('ipasearchtimelimit'))
- if sizelimit < 0:
- sizelimit = int(config.get('ipasearchrecordslimit'))
-
- # Assume the list of fields to search will come from a central
- # configuration repository. A good format for that would be
- # a comma-separated list of fields
- search_fields_conf_str = config.get('ipagroupsearchfields')
- search_fields = string.split(search_fields_conf_str, ",")
-
- criteria = self.__safe_filter(criteria)
- criteria_words = re.split(r'\s+', criteria)
- criteria_words = filter(lambda value:value!="", criteria_words)
- if len(criteria_words) == 0:
- return [0]
-
- (exact_match_filter, partial_match_filter) = self.__generate_match_filters(
- search_fields, criteria_words)
-
- #
- # further constrain search to just the objectClass
- # TODO - need to parameterize this into generate_match_filters,
- # and work it into the field-specification search feature
- #
- exact_match_filter = "(&(objectClass=posixGroup)%s)" % exact_match_filter
- partial_match_filter = "(&(objectClass=posixGroup)%s)" % partial_match_filter
-
- #
- # TODO - copy/paste from find_users. needs to be refactored
- #
- conn = self.getConnection(opts)
- try:
- try:
- exact_results = conn.getListAsync(self.accountsdn, self.scope,
- exact_match_filter, sattrs, 0, None, None, timelimit,
- sizelimit)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- exact_results = [0]
-
- try:
- partial_results = conn.getListAsync(self.accountsdn, self.scope,
- partial_match_filter, sattrs, 0, None, None, timelimit,
- sizelimit)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- partial_results = [0]
- finally:
- self.releaseConnection(conn)
-
- exact_counter = exact_results[0]
- partial_counter = partial_results[0]
-
- exact_results = exact_results[1:]
- partial_results = partial_results[1:]
-
- # Remove exact matches from the partial_match list
- exact_dns = set(map(lambda e: e.dn, exact_results))
- partial_results = filter(lambda e: e.dn not in exact_dns,
- partial_results)
-
- if (exact_counter == -1) or (partial_counter == -1):
- counter = -1
- else:
- counter = len(exact_results) + len(partial_results)
-
- groups = [counter]
- for u in exact_results + partial_results:
- groups.append(self.convert_entry(u))
-
- return groups
-
- def add_member_to_group(self, member_dn, group_dn, opts=None):
- """Add a member to an existing group.
- """
- if not isinstance(member_dn,basestring) or len(member_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(group_dn,basestring) or len(group_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- logging.info("IPA: add_member_to_group '%s' to '%s'" % (member_dn, group_dn))
- if member_dn.lower() == group_dn.lower():
- raise ipaerror.gen_exception(ipaerror.INPUT_SAME_GROUP)
-
- old_group = self.get_entry_by_dn(group_dn, None, opts)
- if old_group is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
- new_group = copy.deepcopy(old_group)
-
- # check to make sure member_dn exists
- member_entry = self.__get_base_entry(member_dn, "(objectClass=*)", ['dn','uid'], opts)
- if not member_entry:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
- if new_group.get('member') is not None:
- if isinstance(new_group.get('member'),basestring):
- new_group['member'] = [new_group['member']]
- new_group['member'].append(member_dn)
- else:
- new_group['member'] = member_dn
-
- try:
- ret = self.__update_entry(old_group, new_group, opts)
- except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
- raise
- return ret
-
- def add_members_to_group(self, member_dns, group_dn, opts=None):
- """Given a list of dn's, add them to the group cn denoted by group
- Returns a list of the member_dns that were not added to the group.
- """
- if not (isinstance(member_dns,list) or isinstance(member_dns,basestring)):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(group_dn,basestring) or len(group_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- if not member_dns or not group_dn:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- logging.info("IPA: add_members_to_group '%s'" % group_dn)
-
- failed = []
-
- if (isinstance(member_dns,basestring)):
- member_dns = [member_dns]
-
- for member_dn in member_dns:
- try:
- self.add_member_to_group(member_dn, group_dn, opts)
- except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
- # User is already in the group
- failed.append(member_dn)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- # User or the group does not exist
- failed.append(member_dn)
-
- return failed
-
- def remove_member_from_group(self, member_dn, group_dn, opts=None):
- """Remove a member_dn from an existing group.
- """
- if not isinstance(member_dn,basestring) or len(member_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(group_dn,basestring) or len(group_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- old_group = self.get_entry_by_dn(group_dn, None, opts)
- if old_group is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
- if old_group.get('cn') == "admins":
- member = self.get_entry_by_dn(member_dn, ['dn','uid'], opts)
- if member.get('uid') == "admin":
- raise ipaerror.gen_exception(ipaerror.INPUT_ADMIN_REQUIRED_IN_ADMINS)
- logging.info("IPA: remove_member_from_group '%s' from '%s'" % (member_dn, group_dn))
- new_group = copy.deepcopy(old_group)
-
- if new_group.get('member') is not None:
- if isinstance(new_group.get('member'),basestring):
- new_group['member'] = [new_group['member']]
- for i in range(len(new_group['member'])):
- new_group['member'][i] = ipaserver.ipaldap.IPAdmin.normalizeDN(new_group['member'][i])
- try:
- new_group['member'].remove(member_dn)
- except ValueError:
- # member is not in the group
- # FIXME: raise more specific error?
- raise ipaerror.gen_exception(ipaerror.STATUS_NOT_GROUP_MEMBER)
- else:
- # Nothing to do if the group has no members
- raise ipaerror.gen_exception(ipaerror.STATUS_NOT_GROUP_MEMBER)
-
- try:
- ret = self.__update_entry(old_group, new_group, opts)
- except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
- raise
- return ret
-
- def remove_members_from_group(self, member_dns, group_dn, opts=None):
- """Given a list of member dn's remove them from the group.
- Returns a list of the members not removed from the group.
- """
- if not (isinstance(member_dns,list) or isinstance(member_dns,basestring)):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(group_dn,basestring) or len(group_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- logging.info("IPA: remove_members_from_group '%s'" % group_dn)
- failed = []
-
- if (isinstance(member_dns,basestring)):
- member_dns = [member_dns]
-
- for member_dn in member_dns:
- try:
- self.remove_member_from_group(member_dn, group_dn, opts)
- except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
- # member is not in the group
- failed.append(member_dn)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- # member_dn or the group does not exist
- failed.append(member_dn)
- except ipaerror.exception_for(ipaerror.STATUS_NOT_GROUP_MEMBER):
- # not a member of the group
- failed.append(member_dn)
- except ipaerror.exception_for(ipaerror.INPUT_ADMIN_REQUIRED_IN_ADMINS):
- # Can't remove admin from admins group
- failed.append(member_dn)
-
- return failed
-
- def add_user_to_group(self, user_uid, group_dn, opts=None):
- """Add a user to an existing group.
- """
- if not isinstance(user_uid,basestring) or len(user_uid) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(group_dn,basestring) or len(group_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- logging.info("IPA: add_user_to_group '%s' to '%s'" % (user_uid, group_dn))
-
- user = self.get_user_by_uid(user_uid, ['dn', 'uid', 'objectclass'], opts)
- if user is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
- return self.add_member_to_group(user['dn'], group_dn, opts)
-
- def add_users_to_group(self, user_uids, group_dn, opts=None):
- """Given a list of user uid's add them to the group cn denoted by group
- Returns a list of the users were not added to the group.
- """
- if not (isinstance(user_uids,list) or isinstance(user_uids,basestring)):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(group_dn,basestring) or len(group_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- logging.info("IPA: add_users_to_group '%s'" % group_dn)
- failed = []
-
- if (isinstance(user_uids,basestring)):
- user_uids = [user_uids]
-
- for user_uid in user_uids:
- try:
- self.add_user_to_group(user_uid, group_dn, opts)
- except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
- # User is already in the group
- failed.append(user_uid)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- # User or the group does not exist
- failed.append(user_uid)
-
- return failed
-
- def remove_user_from_group(self, user_uid, group_dn, opts=None):
- """Remove a user from an existing group.
- """
- if not isinstance(user_uid,basestring) or len(user_uid) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(group_dn,basestring) or len(group_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- logging.info("IPA: remove_user_from_group '%s' from '%s'" % (user_uid, group_dn))
- user = self.get_user_by_uid(user_uid, ['dn', 'uid', 'objectclass'], opts)
- if user is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
- return self.remove_member_from_group(user['dn'], group_dn, opts)
-
- def remove_users_from_group(self, user_uids, group_dn, opts=None):
- """Given a list of user uid's remove them from the group
- Returns a list of the user uids not removed from the group.
- """
- if not (isinstance(user_uids,list) or isinstance(user_uids,basestring)):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(group_dn,basestring) or len(group_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- logging.info("IPA: remove_users_from_group '%s'" % group_dn)
- failed = []
-
- if (isinstance(user_uids,basestring)):
- user_uids = [user_uids]
-
- for user_uid in user_uids:
- try:
- self.remove_user_from_group(user_uid, group_dn, opts)
- except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
- # User is not in the group
- failed.append(user_uid)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- # User or the group does not exist
- failed.append(user_uid)
-
- return failed
-
- def add_groups_to_user(self, group_dns, user_dn, opts=None):
- """Given a list of group dn's add them to the user.
-
- Returns a list of the group dns that were not added.
- """
- if not (isinstance(group_dns,list) or isinstance(group_dns,basestring)):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(user_dn,basestring) or len(user_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- logging.info("IPA: add_groups_to_user '%s'" % user_dn)
- failed = []
-
- if (isinstance(group_dns, basestring)):
- group_dns = [group_dns]
-
- for group_dn in group_dns:
- try:
- self.add_member_to_group(user_dn, group_dn, opts)
- except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
- # User is already in the group
- failed.append(group_dn)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- # User or the group does not exist
- failed.append(group_dn)
-
- return failed
-
- def remove_groups_from_user(self, group_dns, user_dn, opts=None):
- """Given a list of group dn's remove them from the user.
-
- Returns a list of the group dns that were not removed.
- """
- if not (isinstance(group_dns,list) or isinstance(group_dns,basestring)):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(user_dn,basestring) or len(user_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- logging.info("IPA: remove_groups_from_user '%s'" % user_dn)
- failed = []
-
- if (isinstance(group_dns,basestring)):
- group_dns = [group_dns]
-
- for group_dn in group_dns:
- try:
- self.remove_member_from_group(user_dn, group_dn, opts)
- except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
- # User is not in the group
- failed.append(group_dn)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- # User or the group does not exist
- failed.append(group_dn)
- except ipaerror.exception_for(ipaerror.STATUS_NOT_GROUP_MEMBER):
- # User is not in the group
- failed.append(group_dn)
- except ipaerror.exception_for(ipaerror.INPUT_ADMIN_REQUIRED_IN_ADMINS):
- # Can't remove admin from admins group
- failed.append(member_dn)
-
- return failed
-
- def update_group (self, oldentry, newentry, opts=None):
- """Wrapper around update_entry with group-specific handling.
-
- oldentry and newentry are XML-RPC structs.
-
- If oldentry is not empty then it is used when determine what
- has changed.
-
- If oldentry is empty then the value of newentry is compared
- to the current value of oldentry.
-
- If you want to change the RDN of a group you must use
- this function. update_entry will fail.
- """
- if not isinstance(newentry,dict):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if oldentry and not isinstance(oldentry,dict):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not oldentry:
- oldentry = self.get_entry_by_dn(newentry.get('dn'), None, opts)
- if oldentry is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
- logging.info("IPA: update_group '%s'" % oldentry.get('cn'))
- newrdn = 0
-
- oldcn=oldentry.get('cn')
- newcn=newentry.get('cn')
- if isinstance(oldcn,basestring):
- oldcn = [oldcn]
- if isinstance(newcn,basestring):
- newcn = [newcn]
-
- if "admins" in oldcn:
- raise ipaerror.gen_exception(ipaerror.INPUT_ADMINS_IMMUTABLE)
-
- oldcn.sort()
- newcn.sort()
- if oldcn != newcn:
- # RDN change
- conn = self.getConnection(opts)
- try:
- res = conn.updateRDN(oldentry.get('dn'), "cn=" + newcn[0])
- newdn = oldentry.get('dn')
- newcn = newentry.get('cn')
- if isinstance(newcn,basestring):
- newcn = [newcn]
-
- # Ick. Need to find the exact cn used in the old DN so we'll
- # walk the list of cns and skip the obviously bad ones:
- for c in oldentry.get('dn').split("cn="):
- if c and c != "groups" and not c.startswith("accounts"):
- newdn = newdn.replace("cn=%s" % c, "cn=%s," % newcn[0])
- break
-
- # Now fix up the dns and cns so they aren't seen as having
- # changed.
- oldentry['dn'] = newdn
- newentry['dn'] = newdn
- oldentry['cn'] = newentry.get('cn')
- newrdn = 1
- finally:
- self.releaseConnection(conn)
-
- # Get our configuration
- config = self.get_ipa_config(opts)
-
- # Make sure we have the latest object classes
- # newentry['objectclass'] = uniq_list(newentry.get('objectclass') + config.get('ipagroupobjectclasses'))
-
- try:
- rv = self.update_entry(oldentry, newentry, opts)
- return rv
- except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
- if newrdn == 1:
- # This means that there was just the rdn change, no other
- # attributes
- return "Success"
- else:
- raise
-
- def delete_group (self, group_dn, opts=None):
- """Delete a group
- group_dn is the DN of the group to delete
-
- The memberOf plugin handles removing the group from any other
- groups.
- """
- if not isinstance(group_dn,basestring) or len(group_dn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- group = self.get_entry_by_dn(group_dn, ['dn', 'cn'], opts)
- if group is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
- logging.info("IPA: delete_group '%s'" % group_dn)
-
- # We have 2 special groups, don't allow them to be removed
- if "admins" in group.get('cn') or "editors" in group.get('cn'):
- raise ipaerror.gen_exception(ipaerror.CONFIG_REQUIRED_GROUPS)
-
- # Don't allow the default user group to be removed
- config=self.get_ipa_config(opts)
- default_group = self.get_entry_by_cn(config.get('ipadefaultprimarygroup'), None, opts)
- if group_dn == default_group.get('dn'):
- raise ipaerror.gen_exception(ipaerror.CONFIG_DEFAULT_GROUP)
-
- conn = self.getConnection(opts)
- try:
- res = conn.deleteEntry(group_dn)
- finally:
- self.releaseConnection(conn)
- return res
-
- def add_group_to_group(self, group, tgroup, opts=None):
- """Add a group to an existing group.
- group is a DN of the group to add
- tgroup is the DN of the target group to be added to
- """
- if not isinstance(group,basestring) or len(group) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(tgroup,basestring) or len(tgroup) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if group.lower() == tgroup.lower():
- raise ipaerror.gen_exception(ipaerror.INPUT_SAME_GROUP)
- old_group = self.get_entry_by_dn(tgroup, None, opts)
- if old_group is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
- logging.info("IPA: add_group_to_group '%s' to '%s'" % (group, tgroup))
- new_group = copy.deepcopy(old_group)
-
- group_dn = self.get_entry_by_dn(group, ['dn', 'cn', 'objectclass'], opts)
- if group_dn is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
- if new_group.get('member') is not None:
- if isinstance(new_group.get('member'),basestring):
- new_group['member'] = [new_group['member']]
- new_group['member'].append(group_dn['dn'])
- else:
- new_group['member'] = group_dn['dn']
-
- try:
- ret = self.__update_entry(old_group, new_group, opts)
- except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST):
- raise
- return ret
-
- def attrs_to_labels(self, attr_list, opts=None):
- """Take a list of LDAP attributes and convert them to more friendly
- labels."""
- if not (isinstance(attr_list,list)):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- logging.info("IPA: attrs_to_labels")
-
- label_list = {}
-
- for a in attr_list:
- label_list[a] = attrs.attr_label_list.get(a,a)
-
- return label_list
-
- def get_all_attrs(self, opts=None):
- """We have a list of hardcoded attributes -> readable labels. Return
- that complete list if someone wants it.
- """
- logging.info("IPA: get_all_attrs")
-
- return attrs.attr_label_list
-
- def group_members(self, groupdn, attr_list, membertype, opts=None):
- """Do a memberOf search of groupdn and return the attributes in
- attr_list (an empty list returns all attributes).
-
- membertype = 0 all members returned
- membertype = 1 only direct members are returned
- membertype = 2 only inherited members are returned
-
- Members may be included in a group as a result of being a member
- of a group that is a member of the group being queried.
- """
-
- if not isinstance(groupdn,basestring) or len(groupdn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if attr_list is not None and not isinstance(attr_list,list):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if membertype is not None and not isinstance(membertype,int):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if membertype is None:
- membertype = 0
- if membertype < 0 or membertype > 3:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- logging.info("IPA: group_members '%s' %d" % (groupdn, membertype))
- config = self.get_ipa_config(opts)
- timelimit = float(config.get('ipasearchtimelimit'))
-
- sizelimit = int(config.get('ipasearchrecordslimit'))
-
- groupdn = self.__safe_filter(groupdn)
- searchfilter = "(memberOf=%s)" % groupdn
-
- if attr_list is None:
- attr_list = []
- attr_list.append("member")
-
- conn = self.getConnection(opts)
- try:
- try:
- results = conn.getListAsync(self.accountsdn, self.scope,
- searchfilter, attr_list, 0, None, None, timelimit,
- sizelimit)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- results = [0]
- finally:
- self.releaseConnection(conn)
-
- counter = results[0]
- results = results[1:]
-
- if membertype == 0:
- entries = [counter]
- for e in results:
- entries.append(self.convert_entry(e))
-
- return entries
-
- group = self.get_entry_by_dn(groupdn, ['dn', 'member'], opts)
- real_members = group.get('member')
- if isinstance(real_members, basestring):
- real_members = [real_members]
- if real_members is None:
- real_members = []
-
- # Normalize all the dns
- for i in range(len(real_members)):
- real_members[i] = ipaserver.ipaldap.IPAdmin.normalizeDN(real_members[i])
-
- entries = [0]
- for e in results:
- if ipaserver.ipaldap.IPAdmin.normalizeDN(e.dn) not in real_members:
- if membertype == 2:
- entries.append(self.convert_entry(e))
- else:
- if membertype == 1:
- entries.append(self.convert_entry(e))
-
- if len(entries) > 1:
- entries[0] = len(entries) - 1
-
- return entries
-
- def mark_group_active(self, cn, opts=None):
- """Mark a group as active"""
-
- if not isinstance(cn,basestring) or len(cn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- logging.info("IPA: mark_group_active '%s'" % cn)
- group = self.get_entry_by_cn(cn, ['dn', 'cn'], opts)
- return self.mark_entry_active(group.get('dn'))
-
- def mark_group_inactive(self, cn, opts=None):
- """Mark a group as inactive"""
-
- if not isinstance(cn,basestring) or len(cn) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if cn == "admins" or cn == "editors":
- raise ipaerror.gen_exception(ipaerror.INPUT_CANT_INACTIVATE)
- logging.info("IPA: mark_group_inactive '%s'" % cn)
- group = self.get_entry_by_cn(cn, ['dn', 'uid'], opts)
- return self.mark_entry_inactive(group.get('dn'))
-
- def __is_service_unique(self, name, opts):
- """Return True if the uid is unique in the tree, False otherwise."""
- name = self.__safe_filter(name)
- searchfilter = "(&(krbprincipalname=%s)(objectclass=krbPrincipal))" % name
-
- try:
- entry = self.__get_sub_entry(self.accountsdn, searchfilter, ['dn','krbprincipalname'], opts)
- return False
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- return True
-
- def add_service_principal(self, name, force, opts=None):
- """Given a name of the form: service/FQDN create a service
- principal for it in the default realm.
-
- Ensure that the principal points at a DNS A record so it will
- work with Kerberos unless force is set to 1"""
- if not name:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- try:
- f = int(force)
- except ValueError:
- f = 1
- logging.info("IPA: add_service_principal '%s' (%d)" % (name, f))
-
- # Break down the principal into its component parts, which may or
- # may not include the realm.
- sp = name.split('/')
- if len(sp) != 2:
- raise ipaerror.gen_exception(ipaerror.INPUT_MALFORMED_SERVICE_PRINCIPAL)
- service = sp[0]
-
- sr = sp[1].split('@')
- if len(sr) == 1:
- hostname = sr[0].lower()
- realm = self.realm
- elif len(sr) == 2:
- hostname = sr[0].lower()
- realm = sr[1]
- else:
- raise ipaerror.gen_exception(ipaerror.INPUT_MALFORMED_SERVICE_PRINCIPAL)
-
- if not f:
- fqdn = hostname + "."
- rs = dnsclient.query(fqdn, dnsclient.DNS_C_IN, dnsclient.DNS_T_A)
- if len(rs) == 0:
- logging.debug("IPA: DNS A record lookup failed for '%s'" % hostname)
- raise ipaerror.gen_exception(ipaerror.INPUT_NOT_DNS_A_RECORD)
- else:
- logging.debug("IPA: found %d records for '%s'" % (len(rs), hostname))
-
- service_container = DefaultServiceContainer
-
- # At some point we'll support multiple realms
- if (realm != self.realm):
- raise ipaerror.gen_exception(ipaerror.INPUT_REALM_MISMATCH)
-
- # Put the principal back together again
- princ_name = service + "/" + hostname + "@" + realm
-
- conn = self.getConnection(opts)
- if not self.__is_service_unique(princ_name, opts):
- raise ipaerror.gen_exception(ipaerror.LDAP_DUPLICATE)
-
- dn = "krbprincipalname=%s,%s,%s" % (ldap.dn.escape_dn_chars(princ_name),
- service_container,self.basedn)
- entry = ipaserver.ipaldap.Entry(dn)
-
- entry.setValues('objectclass', 'krbPrincipal', 'krbPrincipalAux', 'krbTicketPolicyAux')
- entry.setValues('krbprincipalname', princ_name)
-
- try:
- res = conn.addEntry(entry)
- finally:
- self.releaseConnection(conn)
- return res
-
- def delete_service_principal (self, principal, opts=None):
- """Delete a service principal.
-
- principal is the full DN of the entry to delete.
-
- This should be called with much care.
- """
- if not isinstance(principal,basestring) or len(principal) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- entry = self.get_entry_by_dn(principal, ['dn', 'objectclass'], opts)
- if entry is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
- dn_list = ldap.explode_dn(entry['dn'].lower())
- if "cn=kerberos" in dn_list:
- raise ipaerror.gen_exception(ipaerror.INPUT_SERVICE_PRINCIPAL_REQUIRED)
- logging.info("IPA: delete_service_principal '%s'" % principal)
-
- conn = self.getConnection(opts)
- try:
- res = conn.deleteEntry(entry['dn'])
- finally:
- self.releaseConnection(conn)
- return res
-
- def find_service_principal(self, criteria, sattrs, sizelimit=-1,
- timelimit=-1, opts=None):
- """Returns a list: counter followed by the results.
- If the results are truncated, counter will be set to -1."""
- if not isinstance(criteria,basestring) or len(criteria) == 0:
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if sattrs is not None and not isinstance(sattrs, list):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(sizelimit,int):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not isinstance(timelimit,int):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
-
- config = self.get_ipa_config(opts)
- if timelimit < 0:
- timelimit = float(config.get('ipasearchtimelimit'))
- if sizelimit < 0:
- sizelimit = int(config.get('ipasearchrecordslimit'))
-
- search_fields = ["krbprincipalname"]
- logging.info("IPA: find_service_principal '%s'" % criteria)
-
- criteria = self.__safe_filter(criteria)
- criteria_words = re.split(r'\s+', criteria)
- criteria_words = filter(lambda value:value!="", criteria_words)
- if len(criteria_words) == 0:
- return [0]
-
- (exact_match_filter, partial_match_filter) = self.__generate_match_filters(
- search_fields, criteria_words)
-
- #
- # further constrain search to just the objectClass
- # TODO - need to parameterize this into generate_match_filters,
- # and work it into the field-specification search feature
- #
- exact_match_filter = "(&(objectclass=krbPrincipalAux)(!(objectClass=person))(!(|(krbprincipalname=kadmin/*)(krbprincipalname=K/M@*)(krbprincipalname=krbtgt/*)))%s)" % exact_match_filter
- partial_match_filter = "(&(objectclass=krbPrincipalAux)(!(objectClass=person))(!(|(krbprincipalname=kadmin/*)(krbprincipalname=K/M@*)(krbprincipalname=krbtgt/*)))%s)" % partial_match_filter
-
-
- conn = self.getConnection(opts)
- try:
- try:
- exact_results = conn.getListAsync(self.basedn, self.scope,
- exact_match_filter, sattrs, 0, None, None, timelimit,
- sizelimit)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- exact_results = [0]
-
- try:
- partial_results = conn.getListAsync(self.basedn, self.scope,
- partial_match_filter, sattrs, 0, None, None, timelimit,
- sizelimit)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- partial_results = [0]
- finally:
- self.releaseConnection(conn)
-
- exact_counter = exact_results[0]
- partial_counter = partial_results[0]
-
- exact_results = exact_results[1:]
- partial_results = partial_results[1:]
-
- # Remove exact matches from the partial_match list
- exact_dns = set(map(lambda e: e.dn, exact_results))
- partial_results = filter(lambda e: e.dn not in exact_dns,
- partial_results)
-
- if (exact_counter == -1) or (partial_counter == -1):
- counter = -1
- else:
- counter = len(exact_results) + len(partial_results)
-
- entries = [counter]
- for e in exact_results + partial_results:
- entries.append(self.convert_entry(e))
-
- return entries
-
-
-# Configuration support
- def get_ipa_config(self, opts=None):
- """Retrieve the IPA configuration"""
- searchfilter = "cn=ipaconfig"
- try:
- config = self.__get_sub_entry("cn=etc," + self.basedn, searchfilter, None, opts)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- raise ipaerror.gen_exception(ipaerror.LDAP_NO_CONFIG)
-
- return config
-
- def update_ipa_config(self, oldconfig, newconfig, opts=None):
- """Update the IPA configuration.
-
- oldconfig and newconfig are XML-RPC structs.
-
- If oldconfig is not empty then it is used when determine what
- has changed.
-
- If oldconfig is empty then the value of newconfig is compared
- to the current value of oldconfig.
-
- """
- if not isinstance(newconfig,dict):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if oldconfig and not isinstance(oldconfig,dict):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not oldconfig:
- oldconfig = self.get_entry_by_dn(newconfig.get('dn'), None, opts)
- if oldconfig is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
- # The LDAP routines want strings, not ints, so convert a few
- # things. Otherwise it sees a string -> int conversion as a change.
- try:
- newconfig['ipapwdexpadvnotify'] = str(newconfig.get('ipapwdexpadvnotify'))
- newconfig['ipasearchtimelimit'] = str(newconfig.get('ipasearchtimelimit'))
- newconfig['ipasearchrecordslimit'] = str(newconfig.get('ipasearchrecordslimit'))
- newconfig['ipamaxusernamelength'] = str(newconfig.get('ipamaxusernamelength'))
- except KeyError:
- # These should all be there but if not, let things proceed
- pass
-
- # Ensure that the default group for users exists
- try:
- group = self.get_entry_by_cn(newconfig.get('ipadefaultprimarygroup'), None, opts)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- raise
- except:
- raise
-
- # Run through the list of User and Group object classes to make
- # sure they are all valid. This doesn't handle dependencies but it
- # will at least catch typos.
- classes = self.__get_objectclasses(opts)
- oc = newconfig['ipauserobjectclasses']
- for i in range(len(oc)):
- if not oc[i].lower() in classes:
- raise ipaerror.gen_exception(ipaerror.CONFIG_INVALID_OC)
- oc = newconfig['ipagroupobjectclasses']
- for i in range(len(oc)):
- if not oc[i].lower() in classes:
- raise ipaerror.gen_exception(ipaerror.CONFIG_INVALID_OC)
-
- return self.update_entry(oldconfig, newconfig, opts)
-
- def get_password_policy(self, opts=None):
- """Retrieve the IPA password policy"""
- try:
- policy = self.get_entry_by_cn("accounts", None, opts)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- raise ipaerror.gen_exception(ipaerror.LDAP_NO_CONFIG)
-
- # convert some values for display purposes
- policy['krbmaxpwdlife'] = str(int(policy.get('krbmaxpwdlife')) / 86400)
- policy['krbminpwdlife'] = str(int(policy.get('krbminpwdlife')) / 3600)
-
- return policy
-
- def update_password_policy(self, oldpolicy, newpolicy, opts=None):
- """Update the IPA configuration
-
- oldpolicy and newpolicy are XML-RPC structs.
-
- If oldpolicy is not empty then it is used when determine what
- has changed.
-
- If oldpolicy is empty then the value of newpolicy is compared
- to the current value of oldpolicy.
-
- """
- if not isinstance(newpolicy,dict):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if oldpolicy and not isinstance(oldpolicy,dict):
- raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
- if not oldpolicy:
- oldpolicy = self.get_entry_by_dn(newpolicy.get('dn'), None, opts)
- if oldpolicy is None:
- raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
-
-
- # The LDAP routines want strings, not ints, so convert a few
- # things. Otherwise it sees a string -> int conversion as a change.
- try:
- for k in oldpolicy.iterkeys():
- if k.startswith("krb", 0, 3):
- oldpolicy[k] = str(oldpolicy[k])
- for k in newpolicy.iterkeys():
- if k.startswith("krb", 0, 3):
- newpolicy[k] = str(newpolicy[k])
-
- # Convert hours and days to seconds
- oldpolicy['krbmaxpwdlife'] = str(int(oldpolicy.get('krbmaxpwdlife')) * 86400)
- oldpolicy['krbminpwdlife'] = str(int(oldpolicy.get('krbminpwdlife')) * 3600)
- newpolicy['krbmaxpwdlife'] = str(int(newpolicy.get('krbmaxpwdlife')) * 86400)
- newpolicy['krbminpwdlife'] = str(int(newpolicy.get('krbminpwdlife')) * 3600)
- except KeyError:
- # These should all be there but if not, let things proceed
- pass
- except:
- # Anything else raise an error
- raise
-
- return self.update_entry(oldpolicy, newpolicy, opts)
-
-def ldap_search_escape(match):
- """Escapes out nasty characters from the ldap search.
- See RFC 2254."""
- value = match.group()
- if (len(value) != 1):
- return ""
-
- if value == "(":
- return "\\28"
- elif value == ")":
- return "\\29"
- elif value == "\\":
- return "\\5c"
- elif value == "*":
- # drop '*' from input. search performs its own wildcarding
- return ""
- elif value =='\x00':
- return r'\00'
- else:
- return value
-
-def uniq_list(x):
- """Return a unique list, preserving order and ignoring case"""
- set = {}
- return [set.setdefault(e.lower(),e) for e in x if e.lower() not in set]
diff --git a/ipa-server/xmlrpc-server/ipaxmlrpc.py b/ipa-server/xmlrpc-server/ipaxmlrpc.py
deleted file mode 100644
index 5e13611aa..000000000
--- a/ipa-server/xmlrpc-server/ipaxmlrpc.py
+++ /dev/null
@@ -1,394 +0,0 @@
-# mod_python script
-
-# ipaxmlrpc - an XMLRPC interface for ipa.
-# Copyright (c) 2007 Red Hat
-#
-# IPA is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation;
-# version 2.1 of the License.
-#
-# This software is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this software; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Based on kojixmlrpc - an XMLRPC interface for koji by
-# Mike McLean <mikem@redhat.com>
-#
-# Authors:
-# Rob Crittenden <rcritten@redhat.com>
-
-import sys
-
-
-import time
-import traceback
-import pprint
-from xmlrpclib import Marshaller,loads,dumps,Fault
-from mod_python import apache
-import logging
-
-from ipaserver import funcs
-from ipa import ipaerror, ipautil
-import ldap
-
-import string
-import base64
-
-#
-# An override so we can base64 encode all outgoing values.
-# This is set by calling: Marshaller._Marshaller__dump = xmlrpclib_dump
-#
-# Not currently used.
-#
-def xmlrpclib_escape(s, replace = string.replace):
- """
- xmlrpclib only handles certain characters. Lets encode the whole
- blob
- """
-
- return base64.encodestring(s)
-
-def xmlrpclib_dump(self, value, write):
- """
- xmlrpclib cannot marshal instances of subclasses of built-in
- types. This function overrides xmlrpclib.Marshaller.__dump so that
- any value that is an instance of one of its acceptable types is
- marshalled as that type.
-
- xmlrpclib also cannot handle invalid 7-bit control characters. See
- above.
- """
-
- # Use our escape function
- args = [self, value, write]
- if isinstance(value, (str, unicode)):
- args.append(xmlrpclib_escape)
-
- try:
- # Try for an exact match first
- f = self.dispatch[type(value)]
- except KeyError:
- # Try for an isinstance() match
- for Type, f in self.dispatch.iteritems():
- if isinstance(value, Type):
- f(*args)
- return
- raise TypeError, "cannot marshal %s objects" % type(value)
- else:
- f(*args)
-
-
-class ModXMLRPCRequestHandler(object):
- """Simple XML-RPC handler for mod_python environment"""
-
- def __init__(self):
- self.funcs = {}
- self.traceback = False
- #introspection functions
- self.register_function(self.ping, name="ping")
- self.register_function(self.list_api, name="_listapi")
- self.register_function(self.system_listMethods, name="system.listMethods")
- self.register_function(self.system_methodSignature, name="system.methodSignature")
- self.register_function(self.system_methodHelp, name="system.methodHelp")
- self.register_function(self.multiCall)
-
- def register_function(self, function, name = None):
- if name is None:
- name = function.__name__
- self.funcs[name] = function
-
- def register_module(self, instance, prefix=None):
- """Register all the public functions in an instance with prefix prepended
-
- For example
- h.register_module(exports,"pub.sys")
- will register the methods of exports with names like
- pub.sys.method1
- pub.sys.method2
- ...etc
- """
- for name in dir(instance):
- if name.startswith('_'):
- continue
- function = getattr(instance, name)
- if not callable(function):
- continue
- if prefix is not None:
- name = "%s.%s" %(prefix,name)
- self.register_function(function, name=name)
-
- def register_instance(self,instance):
- self.register_module(instance)
-
- def _marshaled_dispatch(self, data, req):
- """Dispatches an XML-RPC method from marshalled (XML) data."""
-
- params, method = loads(data)
- pythonopts = req.get_options()
-
- # Populate the Apache environment variables
- req.add_common_vars()
-
- opts={}
- opts['remoteuser'] = req.user
-
- if req.subprocess_env.get("KRB5CCNAME") is not None:
- opts['krbccache'] = req.subprocess_env.get("KRB5CCNAME")
- else:
- response = dumps(Fault(5, "Did not receive Kerberos credentials."))
- return response
-
- debuglevel = logging.INFO
- if pythonopts.get("IPADebug"):
- opts['ipadebug'] = pythonopts.get("IPADebug").lower()
-
- if opts['ipadebug'] == "on":
- debuglevel = logging.DEBUG
-
- if not opts.get('ipadebug'):
- opts['ipadebug'] = "off"
-
- logging.basicConfig(level=debuglevel,
- format='[%(asctime)s] [%(levelname)s] %(message)s',
- datefmt='%a %b %d %H:%M:%S %Y',
- stream=sys.stderr)
-
-# if opts['ipadebug'] == "on":
-# for o in opts:
-# logging.debug("IPA: setting option %s: %s" % (o, opts[o]))
-# for e in req.subprocess_env:
-# logging.debug("IPA: environment %s: %s" % (e, req.subprocess_env[e]))
-
- # Tack onto the end of the passed-in arguments any options we also
- # need
- params = params + (opts,)
-
- # special case
-# if method == "get_user":
-# Marshaller._Marshaller__dump = xmlrpclib_dump
-
- start = time.time()
- # generate response
- try:
- response = self._dispatch(method, params)
- # wrap response in a singleton tuple
- response = (response,)
- response = dumps(response, methodresponse=1, allow_none=1)
- except ipaerror.IPAError, e:
- self.traceback = True
-
- if (isinstance(e.detail, ldap.LDAPError) and len(e.detail[0].get('desc')) > 1):
- err = ": %s: %s" % (e.detail[0].get('desc'), e.detail[0].get('info',''))
- response = dumps(Fault(e.code, str(e) + err))
- else:
- response = dumps(Fault(e.code, str(e)))
- except:
- self.traceback = True
- # report exception back to server
- e_class, e = sys.exc_info()[:2]
- faultCode = getattr(e_class,'faultCode',1)
- tb_str = ''.join(traceback.format_exception(*sys.exc_info()))
- faultString = tb_str
- response = dumps(Fault(faultCode, faultString))
-
- return response
-
- def _dispatch(self,method,params):
- func = self.funcs.get(method,None)
- if func is None:
- raise Fault(1, "Invalid method: %s" % method)
-
- args = list(ipautil.unwrap_binary_data(params))
- for i in range(len(args)):
- if args[i] == '__NONE__':
- args[i] = None
-
- ret = func(*args)
-
- return ipautil.wrap_binary_data(ret)
-
- def multiCall(self, calls):
- """Execute a multicall. Execute each method call in the calls list, collecting
- results and errors, and return those as a list."""
- results = []
- for call in calls:
- try:
- result = self._dispatch(call['methodName'], call['params'])
- except Fault, fault:
- results.append({'faultCode': fault.faultCode, 'faultString': fault.faultString})
- except:
- # transform unknown exceptions into XML-RPC Faults
- # don't create a reference to full traceback since this creates
- # a circular reference.
- exc_type, exc_value = sys.exc_info()[:2]
- faultCode = getattr(exc_type, 'faultCode', 1)
- faultString = ', '.join(exc_value.args)
- trace = traceback.format_exception(*sys.exc_info())
- # traceback is not part of the multicall spec, but we include it for debugging purposes
- results.append({'faultCode': faultCode, 'faultString': faultString, 'traceback': trace})
- else:
- results.append([result])
-
- return results
-
- def list_api(self,opts):
- funcs = []
- for name,func in self.funcs.items():
- #the keys in self.funcs determine the name of the method as seen over xmlrpc
- #func.__name__ might differ (e.g. for dotted method names)
- args = self._getFuncArgs(func)
- funcs.append({'name': name,
- 'doc': func.__doc__,
- 'args': args})
- return funcs
-
- def ping(self,opts):
- """Simple test to see if the XML-RPC is up and active."""
- return "pong"
-
- def _getFuncArgs(self, func):
- args = []
- for x in range(0, func.func_code.co_argcount):
- if x == 0 and func.func_code.co_varnames[x] == "self":
- continue
- # opts is a name we tack on internally. Don't publish it.
- if func.func_code.co_varnames[x] == "opts":
- continue
- if func.func_defaults and func.func_code.co_argcount - x <= len(func.func_defaults):
- args.append((func.func_code.co_varnames[x], func.func_defaults[x - func.func_code.co_argcount + len(func.func_defaults)]))
- else:
- args.append(func.func_code.co_varnames[x])
- return args
-
- def system_listMethods(self, opts):
- return self.funcs.keys()
-
- def system_methodSignature(self, method, opts):
- #it is not possible to autogenerate this data
- return 'signatures not supported'
-
- def system_methodHelp(self, method, opts):
- func = self.funcs.get(method)
- if func is None:
- return ""
- arglist = []
- for arg in self._getFuncArgs(func):
- if isinstance(arg,str):
- arglist.append(arg)
- else:
- arglist.append('%s=%s' % (arg[0], arg[1]))
- ret = '%s(%s)' % (method, ", ".join(arglist))
- if func.__doc__:
- ret += "\ndescription: %s" % func.__doc__
- return ret
-
- def handle_request(self,req):
- """Handle a single XML-RPC request"""
-
- # XMLRPC uses POST only. Reject anything else
- if req.method != 'POST':
- req.allow_methods(['POST'],1)
- raise apache.SERVER_RETURN, apache.HTTP_METHOD_NOT_ALLOWED
-
- # The LDAP connection pool is not thread-safe. Avoid problems and
- # force the forked model for now.
- if apache.mpm_query(apache.AP_MPMQ_IS_THREADED):
- response = dumps(Fault(3, "Apache must use the forked model"))
- else:
- response = self._marshaled_dispatch(req.read(), req)
-
- req.content_type = "text/xml"
- req.set_content_length(len(response))
- req.write(response)
-
-
-#
-# mod_python handler
-#
-
-def handler(req, profiling=False):
- if profiling:
- import profile, pstats, StringIO, tempfile
- global _profiling_req
- _profiling_req = req
- temp = tempfile.NamedTemporaryFile()
- profile.run("import ipxmlrpc; ipaxmlrpc.handler(ipaxmlrpc._profiling_req, False)", temp.name)
- stats = pstats.Stats(temp.name)
- strstream = StringIO.StringIO()
- sys.stdout = strstream
- stats.sort_stats("time")
- stats.print_stats()
- req.write("<pre>" + strstream.getvalue() + "</pre>")
- _profiling_req = None
- else:
- opts = req.get_options()
- try:
- f = funcs.IPAServer()
- h = ModXMLRPCRequestHandler()
- h.register_function(f.version)
- h.register_function(f.get_aci_entry)
- h.register_function(f.get_entry_by_dn)
- h.register_function(f.get_entry_by_cn)
- h.register_function(f.update_entry)
- h.register_function(f.get_user_by_uid)
- h.register_function(f.get_user_by_principal)
- h.register_function(f.get_user_by_email)
- h.register_function(f.get_users_by_manager)
- h.register_function(f.add_user)
- h.register_function(f.get_custom_fields)
- h.register_function(f.set_custom_fields)
- h.register_function(f.get_all_users)
- h.register_function(f.find_users)
- h.register_function(f.update_user)
- h.register_function(f.delete_user)
- h.register_function(f.mark_user_active)
- h.register_function(f.mark_user_inactive)
- h.register_function(f.mark_group_active)
- h.register_function(f.mark_group_inactive)
- h.register_function(f.modifyPassword)
- h.register_function(f.get_groups_by_member)
- h.register_function(f.add_group)
- h.register_function(f.find_groups)
- h.register_function(f.add_member_to_group)
- h.register_function(f.add_members_to_group)
- h.register_function(f.remove_member_from_group)
- h.register_function(f.remove_members_from_group)
- h.register_function(f.add_user_to_group)
- h.register_function(f.add_users_to_group)
- h.register_function(f.add_group_to_group)
- h.register_function(f.remove_user_from_group)
- h.register_function(f.remove_users_from_group)
- h.register_function(f.add_groups_to_user)
- h.register_function(f.remove_groups_from_user)
- h.register_function(f.update_group)
- h.register_function(f.delete_group)
- h.register_function(f.attrs_to_labels)
- h.register_function(f.get_all_attrs)
- h.register_function(f.group_members)
- h.register_function(f.get_ipa_config)
- h.register_function(f.update_ipa_config)
- h.register_function(f.get_password_policy)
- h.register_function(f.update_password_policy)
- h.register_function(f.add_service_principal)
- h.register_function(f.delete_service_principal)
- h.register_function(f.find_service_principal)
- h.register_function(f.get_radius_client_by_ip_addr)
- h.register_function(f.add_radius_client)
- h.register_function(f.update_radius_client)
- h.register_function(f.delete_radius_client)
- h.register_function(f.find_radius_clients)
- h.register_function(f.get_radius_profile_by_uid)
- h.register_function(f.add_radius_profile)
- h.register_function(f.update_radius_profile)
- h.register_function(f.delete_radius_profile)
- h.register_function(f.find_radius_profiles)
- h.handle_request(req)
- finally:
- pass
- return apache.OK
diff --git a/ipa-server/xmlrpc-server/test/Makefile.am b/ipa-server/xmlrpc-server/test/Makefile.am
deleted file mode 100644
index 310d9d472..000000000
--- a/ipa-server/xmlrpc-server/test/Makefile.am
+++ /dev/null
@@ -1,12 +0,0 @@
-NULL =
-
-EXTRA_DIST = \
- README \
- test_methods.py \
- test_mod_python.py \
- test.py \
- $(NULL)
-
-MAINTAINERCLEANFILES = \
- *~ \
- Makefile.in
diff --git a/ipa-server/xmlrpc-server/test/README b/ipa-server/xmlrpc-server/test/README
deleted file mode 100644
index 544efa526..000000000
--- a/ipa-server/xmlrpc-server/test/README
+++ /dev/null
@@ -1,60 +0,0 @@
-Diagnosing Kerberos credentials cache problems is difficult.
-
-The first thing to try is to set LogLevel to debug in
-/etc/httpd/conf/httpd.conf and restart Apache.
-
-Look in /var/log/httpd/error_log for any problems.
-
-Also check out /var/log/krb5kdc.log
-
-To simplify things and test just Kerberos ticket forwarding:
-
-The first test is with a CGI:
-
-- copy test.py /var/www/cgi-bin
-- chmod +x /var/www/cgi-bin/test.py
-- kinit admin (or some other existing user)
-- curl -u : --negotiate http://yourhost.fqdn/cgi-bin/test.py
-
-For yourhost.fqdn use the fully-qualified hostname of your webserver.
-
-The output should look something like:
-
-KRB5CCNAME is FILE:/tmp/krb5cc_apache_TiMAbq
-Sucessfully bound to LDAP using SASL mechanism GSSAPI
-
-This CGI uses the forwarded credentials to make an authenticated LDAP
-connection. If this fails it means that Apache is not properly storing
-the kerberos credentials.
-
-If that works, the second test more closely models the way that IPA works.
-
-- mkdir /usr/share/ipa/ipatest
-- cp test_mod_python.py /usr/share/ipa/ipatest
-- uncomment the entries for ipatest in /etc/httpd/conf.d/ipa.conf. There are
- entries for ProxyPass and ProxyReversePass, an Alias and a Directory
-- restart Apache
-- curl -u : --negotiate http://yourhost.fqdn/ipatest/
-
-For yourhost.fqdn use the fully-qualified hostname of your webserver.
-
-The output should look something like:
-
-KRB5CCNAME: FILE:/tmp/krb5cc_apache_c0MU9o<br>
-GATEWAY_INTERFACE: CGI/1.1<br>
-...
-SCRIPT_FILENAME: /usr/share/ipa/ipaserver/<br>
-REMOTE_PORT: 45691<br>
-REMOTE_USER: rcrit@GREYOAK.COM<br>
-AUTH_TYPE: Negotiate<br>
-KRB5CCNAME is FILE:/tmp/krb5cc_apache_c0MU9o<br>
-Sucessfully bound to LDAP using SASL mechanism GSSAPI<br>
-
-It should print all of the environment variables available to mod_python
-and do a GSSAPI LDAP connection.
-
-A final test, which lists the capabilities of the XML-RPC server is
-test_methods.py. This is more a sanity check that new functions added
-to the server work as expected.
-
-Note that opts is added by the server itself and is not passed in by the user.
diff --git a/ipa-server/xmlrpc-server/test/test.py b/ipa-server/xmlrpc-server/test/test.py
deleted file mode 100644
index 7c05f8d29..000000000
--- a/ipa-server/xmlrpc-server/test/test.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/python
-
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; version 2 only
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# A test CGI that tests that the Kerberos credentials cache was created
-# properly in Apache.
-
-import ldap
-import ldap.sasl
-import os
-
-sasl_auth = ldap.sasl.sasl({}, "GSSAPI")
-conn = ldap.initialize("ldap://localhost:389/")
-conn.protocol_version = 3
-
-print "Content-type: text/plain"
-print ""
-
-try:
- print "KRB5CCNAME is", os.environ["KRB5CCNAME"]
-
- try:
- conn.sasl_interactive_bind_s("", sasl_auth)
- except ldap.LDAPError,e:
- print "Error using SASL mechanism", sasl_auth.mech, str(e)
- else:
- print "Sucessfully bound to LDAP using SASL mechanism", sasl_auth.mech
- conn.unbind()
-except KeyError,e:
- print "not set."
diff --git a/ipa-server/xmlrpc-server/test/test_methods.py b/ipa-server/xmlrpc-server/test/test_methods.py
deleted file mode 100644
index 88fcd9339..000000000
--- a/ipa-server/xmlrpc-server/test/test_methods.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/python
-
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; version 2 only
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# Simple program to interrogate the XML-RPC server for information on what
-# it can do.
-
-import sys
-import xmlrpclib
-from ipa.krbtransport import KerbTransport
-import ipa
-from ipa import config
-
-ipa.config.init_config()
-
-serverlist = config.config.get_server()
-url = "http://" + serverlist[0] + "/ipa"
-s = xmlrpclib.Server(url, KerbTransport())
-
-print "A list of all methods available on the server."
-print "system.listMethods: ", s.system.listMethods()
-print ""
-
-print "Signatures are not supported."
-print "system.methodSignature: ", s.system.methodSignature("get_user_by_uid")
-print ""
-
-print "Help on a specific method"
-print "system.methodHelp: ", s.system.methodHelp("get_user_by_uid")
-
-print "The entire API:"
-result = s._listapi()
-for item in result:
- print item['name'],
- print "(",
- i = len(item['args'])
- p = 0
- for a in item['args']:
- if isinstance(a, list):
- print "%s=%s" % (a[0], a[1]),
- else:
- print a,
- if p < i - 1:
- print ",",
- p = p + 1
- print ")"
diff --git a/ipa-server/xmlrpc-server/test/test_mod_python.py b/ipa-server/xmlrpc-server/test/test_mod_python.py
deleted file mode 100644
index 6136b5416..000000000
--- a/ipa-server/xmlrpc-server/test/test_mod_python.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/python
-
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; version 2 only
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# A test CGI that tests that the Kerberos credentials cache was created
-# properly in Apache.
-
-import ldap
-import ldap.sasl
-import os
-from mod_python import apache
-
-def handler(req):
- req.content_type = "text/plain"
- req.send_http_header()
- do_request(req)
- return apache.OK
-
-def do_request(req):
- sasl_auth = ldap.sasl.sasl({}, "GSSAPI")
- conn = ldap.initialize("ldap://localhost:389/")
- conn.protocol_version = 3
-
- req.add_common_vars()
-
- for e in req.subprocess_env:
- req.write("%s: %s<br>\n" % (e, req.subprocess_env[e]))
-
- try:
- req.write("KRB5CCNAME is %s<br>\n" % req.subprocess_env["KRB5CCNAME"])
- os.environ["KRB5CCNAME"] = req.subprocess_env["KRB5CCNAME"]
-
- try:
- conn.sasl_interactive_bind_s("", sasl_auth)
- except ldap.LDAPError,e:
- req.write("Error using SASL mechanism %s %s<br>\n" % (sasl_auth.mech, str(e)))
- else:
- req.write("Sucessfully bound to LDAP using SASL mechanism %s<br>\n" % sasl_auth.mech)
- conn.unbind()
- except KeyError,e:
- req.write("KRB5CCNAME is not set.")