mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Use DN objects instead of strings
* Convert every string specifying a DN into a DN object * Every place a dn was manipulated in some fashion it was replaced by the use of DN operators * Add new DNParam parameter type for parameters which are DN's * DN objects are used 100% of the time throughout the entire data pipeline whenever something is logically a dn. * Many classes now enforce DN usage for their attributes which are dn's. This is implmented via ipautil.dn_attribute_property(). The only permitted types for a class attribute specified to be a DN are either None or a DN object. * Require that every place a dn is used it must be a DN object. This translates into lot of:: assert isinstance(dn, DN) sprinkled through out the code. Maintaining these asserts is valuable to preserve DN type enforcement. The asserts can be disabled in production. The goal of 100% DN usage 100% of the time has been realized, these asserts are meant to preserve that. The asserts also proved valuable in detecting functions which did not obey their function signatures, such as the baseldap pre and post callbacks. * Moved ipalib.dn to ipapython.dn because DN class is shared with all components, not just the server which uses ipalib. * All API's now accept DN's natively, no need to convert to str (or unicode). * Removed ipalib.encoder and encode/decode decorators. Type conversion is now explicitly performed in each IPASimpleLDAPObject method which emulates a ldap.SimpleLDAPObject method. * Entity & Entry classes now utilize DN's * Removed __getattr__ in Entity & Entity clases. There were two problems with it. It presented synthetic Python object attributes based on the current LDAP data it contained. There is no way to validate synthetic attributes using code checkers, you can't search the code to find LDAP attribute accesses (because synthetic attriutes look like Python attributes instead of LDAP data) and error handling is circumscribed. Secondly __getattr__ was hiding Python internal methods which broke class semantics. * Replace use of methods inherited from ldap.SimpleLDAPObject via IPAdmin class with IPAdmin methods. Directly using inherited methods was causing us to bypass IPA logic. Mostly this meant replacing the use of search_s() with getEntry() or getList(). Similarly direct access of the LDAP data in classes using IPAdmin were replaced with calls to getValue() or getValues(). * Objects returned by ldap2.find_entries() are now compatible with either the python-ldap access methodology or the Entity/Entry access methodology. * All ldap operations now funnel through the common IPASimpleLDAPObject giving us a single location where we interface to python-ldap and perform conversions. * The above 4 modifications means we've greatly reduced the proliferation of multiple inconsistent ways to perform LDAP operations. We are well on the way to having a single API in IPA for doing LDAP (a long range goal). * All certificate subject bases are now DN's * DN objects were enhanced thusly: - find, rfind, index, rindex, replace and insert methods were added - AVA, RDN and DN classes were refactored in immutable and mutable variants, the mutable variants are EditableAVA, EditableRDN and EditableDN. By default we use the immutable variants preserving important semantics. To edit a DN cast it to an EditableDN and cast it back to DN when done editing. These issues are fully described in other documentation. - first_key_match was removed - DN equalty comparison permits comparison to a basestring * Fixed ldapupdate to work with DN's. This work included: - Enhance test_updates.py to do more checking after applying update. Add test for update_from_dict(). Convert code to use unittest classes. - Consolidated duplicate code. - Moved code which should have been in the class into the class. - Fix the handling of the 'deleteentry' update action. It's no longer necessary to supply fake attributes to make it work. Detect case where subsequent update applies a change to entry previously marked for deletetion. General clean-up and simplification of the 'deleteentry' logic. - Rewrote a couple of functions to be clearer and more Pythonic. - Added documentation on the data structure being used. - Simplfy the use of update_from_dict() * Removed all usage of get_schema() which was being called prior to accessing the .schema attribute of an object. If a class is using internal lazy loading as an optimization it's not right to require users of the interface to be aware of internal optimization's. schema is now a property and when the schema property is accessed it calls a private internal method to perform the lazy loading. * Added SchemaCache class to cache the schema's from individual servers. This was done because of the observation we talk to different LDAP servers, each of which may have it's own schema. Previously we globally cached the schema from the first server we connected to and returned that schema in all contexts. The cache includes controls to invalidate it thus forcing a schema refresh. * Schema caching is now senstive to the run time context. During install and upgrade the schema can change leading to errors due to out-of-date cached schema. The schema cache is refreshed in these contexts. * We are aware of the LDAP syntax of all LDAP attributes. Every attribute returned from an LDAP operation is passed through a central table look-up based on it's LDAP syntax. The table key is the LDAP syntax it's value is a Python callable that returns a Python object matching the LDAP syntax. There are a handful of LDAP attributes whose syntax is historically incorrect (e.g. DistguishedNames that are defined as DirectoryStrings). The table driven conversion mechanism is augmented with a table of hard coded exceptions. Currently only the following conversions occur via the table: - dn's are converted to DN objects - binary objects are converted to Python str objects (IPA convention). - everything else is converted to unicode using UTF-8 decoding (IPA convention). However, now that the table driven conversion mechanism is in place it would be trivial to do things such as converting attributes which have LDAP integer syntax into a Python integer, etc. * Expected values in the unit tests which are a DN no longer need to use lambda expressions to promote the returned value to a DN for equality comparison. The return value is automatically promoted to a DN. The lambda expressions have been removed making the code much simpler and easier to read. * Add class level logging to a number of classes which did not support logging, less need for use of root_logger. * Remove ipaserver/conn.py, it was unused. * Consolidated duplicate code wherever it was found. * Fixed many places that used string concatenation to form a new string rather than string formatting operators. This is necessary because string formatting converts it's arguments to a string prior to building the result string. You can't concatenate a string and a non-string. * Simplify logic in rename_managed plugin. Use DN operators to edit dn's. * The live version of ipa-ldap-updater did not generate a log file. The offline version did, now both do. https://fedorahosted.org/freeipa/ticket/1670 https://fedorahosted.org/freeipa/ticket/1671 https://fedorahosted.org/freeipa/ticket/1672 https://fedorahosted.org/freeipa/ticket/1673 https://fedorahosted.org/freeipa/ticket/1674 https://fedorahosted.org/freeipa/ticket/1392 https://fedorahosted.org/freeipa/ticket/2872
This commit is contained in:
parent
be9614654e
commit
94d457e83c
14
API.txt
14
API.txt
@ -491,7 +491,7 @@ output: Output('value', <type 'unicode'>, None)
|
||||
command: cosentry_add
|
||||
args: 1,7,3
|
||||
arg: Str('cn', attribute=True, cli_name='cn', multivalue=False, primary_key=True, required=True)
|
||||
option: Str('krbpwdpolicyreference', attribute=True, cli_name='krbpwdpolicyreference', multivalue=False, required=True)
|
||||
option: DNParam('krbpwdpolicyreference', attribute=True, cli_name='krbpwdpolicyreference', multivalue=False, required=True)
|
||||
option: Int('cospriority', attribute=True, cli_name='cospriority', minvalue=0, multivalue=False, required=True)
|
||||
option: Str('setattr*', cli_name='setattr', exclude='webui')
|
||||
option: Str('addattr*', cli_name='addattr', exclude='webui')
|
||||
@ -512,7 +512,7 @@ command: cosentry_find
|
||||
args: 1,9,4
|
||||
arg: Str('criteria?', noextrawhitespace=False)
|
||||
option: Str('cn', attribute=True, autofill=False, cli_name='cn', multivalue=False, primary_key=True, query=True, required=False)
|
||||
option: Str('krbpwdpolicyreference', attribute=True, autofill=False, cli_name='krbpwdpolicyreference', multivalue=False, query=True, required=False)
|
||||
option: DNParam('krbpwdpolicyreference', attribute=True, autofill=False, cli_name='krbpwdpolicyreference', multivalue=False, query=True, required=False)
|
||||
option: Int('cospriority', attribute=True, autofill=False, cli_name='cospriority', minvalue=0, multivalue=False, query=True, required=False)
|
||||
option: Int('timelimit?', autofill=False, minvalue=0)
|
||||
option: Int('sizelimit?', autofill=False, minvalue=0)
|
||||
@ -527,7 +527,7 @@ output: Output('truncated', <type 'bool'>, None)
|
||||
command: cosentry_mod
|
||||
args: 1,9,3
|
||||
arg: Str('cn', attribute=True, cli_name='cn', multivalue=False, primary_key=True, query=True, required=True)
|
||||
option: Str('krbpwdpolicyreference', attribute=True, autofill=False, cli_name='krbpwdpolicyreference', multivalue=False, required=False)
|
||||
option: DNParam('krbpwdpolicyreference', attribute=True, autofill=False, cli_name='krbpwdpolicyreference', multivalue=False, required=False)
|
||||
option: Int('cospriority', attribute=True, autofill=False, cli_name='cospriority', minvalue=0, multivalue=False, required=False)
|
||||
option: Str('setattr*', cli_name='setattr', exclude='webui')
|
||||
option: Str('addattr*', cli_name='addattr', exclude='webui')
|
||||
@ -1931,9 +1931,9 @@ command: migrate_ds
|
||||
args: 2,16,4
|
||||
arg: Str('ldapuri', cli_name='ldap_uri')
|
||||
arg: Password('bindpw', cli_name='password', confirm=False)
|
||||
option: Str('binddn?', autofill=True, cli_name='bind_dn', default=u'cn=directory manager')
|
||||
option: Str('usercontainer', autofill=True, cli_name='user_container', default=u'ou=people')
|
||||
option: Str('groupcontainer', autofill=True, cli_name='group_container', default=u'ou=groups')
|
||||
option: DNParam('binddn?', autofill=True, cli_name='bind_dn', default=ipapython.dn.DN('cn=directory manager'))
|
||||
option: DNParam('usercontainer', autofill=True, cli_name='user_container', default=ipapython.dn.DN('ou=people'))
|
||||
option: DNParam('groupcontainer', autofill=True, cli_name='group_container', default=ipapython.dn.DN('ou=groups'))
|
||||
option: Str('userobjectclass+', autofill=True, cli_name='user_objectclass', csv=True, default=(u'person',))
|
||||
option: Str('groupobjectclass+', autofill=True, cli_name='group_objectclass', csv=True, default=(u'groupOfUniqueNames', u'groupOfNames'))
|
||||
option: Str('userignoreobjectclass*', autofill=True, cli_name='user_ignore_objectclass', csv=True, default=())
|
||||
@ -1943,7 +1943,7 @@ option: Str('groupignoreattribute*', autofill=True, cli_name='group_ignore_attri
|
||||
option: Flag('groupoverwritegid', autofill=True, cli_name='group_overwrite_gid', default=False)
|
||||
option: StrEnum('schema?', autofill=True, cli_name='schema', default=u'RFC2307bis', values=(u'RFC2307bis', u'RFC2307'))
|
||||
option: Flag('continue?', autofill=True, default=False)
|
||||
option: Str('basedn?', cli_name='base_dn')
|
||||
option: DNParam('basedn?', cli_name='base_dn')
|
||||
option: Flag('compat?', autofill=True, cli_name='with_compat', default=False)
|
||||
option: Str('exclude_groups*', autofill=True, cli_name='exclude_groups', csv=True, default=())
|
||||
option: Str('exclude_users*', autofill=True, cli_name='exclude_users', csv=True, default=())
|
||||
|
@ -31,6 +31,7 @@ from optparse import OptionParser
|
||||
import ipachangeconf
|
||||
import ldap
|
||||
from ldap import LDAPError
|
||||
from ipapython.dn import DN
|
||||
|
||||
class ipaserver:
|
||||
|
||||
@ -90,7 +91,8 @@ class ipaserver:
|
||||
|
||||
#search and return known realms
|
||||
root_logger.debug("Search for (objectClass=krbRealmContainer) in "+self.basedn+"(sub)")
|
||||
lret = lh.search_s("cn=kerberos,"+self.basedn, ldap.SCOPE_SUBTREE, "(objectClass=krbRealmContainer)")
|
||||
lret = lh.search_s(str(DN(('cn', 'kerberos'), self.basedn)),
|
||||
ldap.SCOPE_SUBTREE, "(objectClass=krbRealmContainer)")
|
||||
if not lret:
|
||||
#something very wrong
|
||||
return False
|
||||
@ -272,8 +274,8 @@ def main():
|
||||
{'name':'ldap_version', 'type':'option', 'value':'3'},
|
||||
{'name':'base', 'type':'option', 'value':ipasrv.getBaseDN()},
|
||||
{'name':'empty', 'type':'empty'},
|
||||
{'name':'nss_base_passwd', 'type':'option', 'value':'cn=users,cn=accounts,'+ipasrv.getBaseDN()+'?sub'},
|
||||
{'name':'nss_base_group', 'type':'option', 'value':'cn=users,cn=accounts,'+ipasrv.getBaseDN()+'?sub'},
|
||||
{'name':'nss_base_passwd', 'type':'option', 'value':str(DN(('cn', 'users'), ('cn', 'accounts'), ipasrv.getBaseDN()))+'?sub'},
|
||||
{'name':'nss_base_group', 'type':'option', 'value':str(DN(('cn', 'users'), ('cn', 'accounts'), ipasrv.getBaseDN()))+'?sub'},
|
||||
{'name':'nss_schema', 'type':'option', 'value':'rfc2307bis'},
|
||||
{'name':'nss_map_attribute', 'type':'option', 'value':'uniqueMember member'},
|
||||
{'name':'nss_initgroups_ignoreusers', 'type':'option', 'value':'root,dirsrv'},
|
||||
|
@ -29,7 +29,7 @@ import tempfile
|
||||
import krbV
|
||||
import syslog
|
||||
from ipalib import api
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
from ipalib import errors
|
||||
from ipalib import x509
|
||||
from ipapython import services as ipaservices
|
||||
@ -52,7 +52,7 @@ api.finalize()
|
||||
# Update or add it
|
||||
tmpdir = tempfile.mkdtemp(prefix = "tmp-")
|
||||
try:
|
||||
dn = str(DN(('cn',nickname),('cn=ca_renewal,cn=ipa,cn=etc'),(api.env.basedn)))
|
||||
dn = DN(('cn', nickname), ('cn', 'ca_renewal'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
|
||||
principal = str('host/%s@%s' % (api.env.host, api.env.realm))
|
||||
ccache = ipautil.kinit_hostprincipal('/etc/krb5.keytab', tmpdir, principal)
|
||||
conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri)
|
||||
|
@ -27,6 +27,7 @@ import ldap
|
||||
import wsgiref
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.ipautil import get_ipa_basedn
|
||||
from ipapython.dn import DN
|
||||
|
||||
BASE_DN = ''
|
||||
LDAP_URI = 'ldaps://localhost:636'
|
||||
@ -80,10 +81,10 @@ def bind(username, password):
|
||||
if not base_dn:
|
||||
root_logger.error('migration unable to get base dn')
|
||||
raise IOError(errno.EIO, 'Cannot get Base DN')
|
||||
bind_dn = 'uid=%s,cn=users,cn=accounts,%s' % (username, base_dn)
|
||||
bind_dn = DN(('uid', username), ('cn', 'users'), ('cn', 'accounts'), base_dn)
|
||||
try:
|
||||
conn = ldap.initialize(LDAP_URI)
|
||||
conn.simple_bind_s(bind_dn, password)
|
||||
conn.simple_bind_s(str(bind_dn), password)
|
||||
except (ldap.INVALID_CREDENTIALS, ldap.UNWILLING_TO_PERFORM,
|
||||
ldap.NO_SUCH_OBJECT), e:
|
||||
root_logger.error('migration invalid credentials for %s: %s' % (bind_dn, convert_exception(e)))
|
||||
|
@ -26,7 +26,7 @@ import tempfile
|
||||
import krbV
|
||||
import syslog
|
||||
from ipalib import api
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
from ipalib import errors
|
||||
from ipapython import services as ipaservices
|
||||
from ipapython import ipautil
|
||||
@ -50,7 +50,7 @@ if not cert:
|
||||
# Update or add it
|
||||
tmpdir = tempfile.mkdtemp(prefix = "tmp-")
|
||||
try:
|
||||
dn = str(DN(('cn',nickname),('cn=ca_renewal,cn=ipa,cn=etc'),(api.env.basedn)))
|
||||
dn = DN(('cn',nickname), ('cn', 'ca_renewal'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
|
||||
principal = str('host/%s@%s' % (api.env.host, api.env.realm))
|
||||
ccache = ipautil.kinit_hostprincipal('/etc/krb5.keytab', tmpdir, principal)
|
||||
conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri)
|
||||
|
@ -29,7 +29,7 @@ from ipapython import ipautil
|
||||
from ipaserver.install import certs
|
||||
from ipaserver.install.cainstance import DEFAULT_DSPORT
|
||||
from ipalib import api
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
from ipalib import x509
|
||||
from ipalib import errors
|
||||
from ipaserver.plugins.ldap2 import ldap2
|
||||
@ -45,7 +45,7 @@ subject = x509.get_subject(cert, datatype=x509.DER)
|
||||
issuer = x509.get_issuer(cert, datatype=x509.DER)
|
||||
|
||||
# Load it into dogtag
|
||||
dn = str(DN(('uid','ipara'),('ou','People'),('o','ipaca')))
|
||||
dn = DN(('uid','ipara'),('ou','People'),('o','ipaca'))
|
||||
|
||||
try:
|
||||
dm_password = get_pin('internaldb')
|
||||
@ -55,7 +55,7 @@ except IOError, e:
|
||||
|
||||
try:
|
||||
conn = ldap2(shared_instance=False, ldap_uri='ldap://localhost:%d' % DEFAULT_DSPORT)
|
||||
conn.connect(bind_dn='cn=directory manager', bind_pw=dm_password)
|
||||
conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=dm_password)
|
||||
(entry_dn, entry_attrs) = conn.get_entry(dn, ['usercertificate'], normalize=False)
|
||||
entry_attrs['usercertificate'].append(cert)
|
||||
entry_attrs['description'] = '2;%d;%s;%s' % (serial_number, issuer, subject)
|
||||
@ -68,7 +68,7 @@ except Exception, e:
|
||||
# Store it in the IPA LDAP server
|
||||
tmpdir = tempfile.mkdtemp(prefix = "tmp-")
|
||||
try:
|
||||
dn = str(DN(('cn','ipaCert'),('cn=ca_renewal,cn=ipa,cn=etc'),(api.env.basedn)))
|
||||
dn = DN(('cn','ipaCert'), ('cn', 'ca_renewal'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
|
||||
principal = str('host/%s@%s' % (api.env.host, api.env.realm))
|
||||
ccache = ipautil.kinit_hostprincipal('/etc/krb5.keytab', tmpdir, principal)
|
||||
conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri)
|
||||
|
@ -32,6 +32,7 @@ from ipapython.config import IPAOptionParser
|
||||
import krbV
|
||||
import ldap
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
|
||||
log_file_name = "/var/log/ipaserver-install.log"
|
||||
|
||||
|
@ -28,6 +28,7 @@ try:
|
||||
from ipaserver.plugins.ldap2 import ldap2
|
||||
from ipalib import api, errors
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
except ImportError:
|
||||
print >> sys.stderr, """\
|
||||
There was a problem importing one of the required Python modules. The
|
||||
@ -37,8 +38,8 @@ error was:
|
||||
""" % sys.exc_value
|
||||
sys.exit(1)
|
||||
|
||||
compat_dn = "cn=Schema Compatibility,cn=plugins,cn=config"
|
||||
nis_config_dn = "cn=NIS Server,cn=plugins,cn=config"
|
||||
compat_dn = DN(('cn', 'Schema Compatibility'), ('cn', 'plugins'), ('cn', 'config'))
|
||||
nis_config_dn = DN(('cn', 'NIS Server'), ('cn', 'plugins'), ('cn', 'config'))
|
||||
|
||||
def parse_options():
|
||||
usage = "%prog [options] <enable|disable>\n"
|
||||
@ -107,7 +108,7 @@ def main():
|
||||
try:
|
||||
conn = ldap2(shared_instance=False, base_dn='')
|
||||
conn.connect(
|
||||
bind_dn='cn=directory manager', bind_pw=dirman_password
|
||||
bind_dn=DN(('cn', 'directory manager')), bind_pw=dirman_password
|
||||
)
|
||||
except errors.ExecutionError, lde:
|
||||
sys.exit("An error occurred while connecting to the server.\n%s\n" % str(lde))
|
||||
|
@ -36,6 +36,7 @@ try:
|
||||
from ipaserver.plugins.ldap2 import ldap2
|
||||
from ipalib import api, errors, backend
|
||||
from ipaserver.install import installutils
|
||||
from ipapython.dn import DN
|
||||
except ImportError, e:
|
||||
# If python-rhsm isn't installed exit gracefully and quietly.
|
||||
if e.args[0] == 'No module named rhsm.certificate':
|
||||
@ -116,7 +117,7 @@ def check_compliance(tmpdir, debug=False):
|
||||
# Get the hosts first
|
||||
try:
|
||||
(entries, truncated) = conn.find_entries('(krblastpwdchange=*)', ['dn'],
|
||||
'%s,%s' % (api.env.container_host, api.env.basedn),
|
||||
DN(api.env.container_host, api.env.basedn),
|
||||
conn.SCOPE_ONELEVEL,
|
||||
size_limit = -1)
|
||||
except errors.NotFound:
|
||||
@ -136,7 +137,7 @@ def check_compliance(tmpdir, debug=False):
|
||||
try:
|
||||
(entries, truncated) = conn.find_entries('(objectclass=ipaentitlement)',
|
||||
['dn', 'userCertificate'],
|
||||
'%s,%s' % (api.env.container_entitlements, api.env.basedn),
|
||||
DN(api.env.container_entitlements, api.env.basedn),
|
||||
conn.SCOPE_ONELEVEL,
|
||||
size_limit = -1)
|
||||
|
||||
|
@ -30,7 +30,7 @@ from ipaserver.install import replication, installutils
|
||||
from ipaserver import ipaldap
|
||||
from ipapython import version
|
||||
from ipalib import api, errors, util
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
|
||||
CACERT = "/etc/ipa/ca.crt"
|
||||
PORT = 7389
|
||||
@ -63,7 +63,7 @@ class CSReplicationManager(replication.ReplicationManager):
|
||||
|
||||
def __init__(self, realm, hostname, dirman_passwd, port=PORT, starttls=True):
|
||||
super(CSReplicationManager, self).__init__(realm, hostname, dirman_passwd, port, starttls)
|
||||
self.suffix = 'o=ipaca'
|
||||
self.suffix = DN(('o', 'ipaca'))
|
||||
self.hostnames = [] # set before calling or agreement_dn() will fail
|
||||
|
||||
def agreement_dn(self, hostname, master=None):
|
||||
@ -89,14 +89,14 @@ class CSReplicationManager(replication.ReplicationManager):
|
||||
else:
|
||||
name = "clone"
|
||||
cn="%sAgreement1-%s-%s" % (name, hostname, instance_name)
|
||||
dn = str(DN("cn=%s, %s" % (cn, self.replica_dn())))
|
||||
dn = DN(('cn', cn), self.replica_dn())
|
||||
return (cn, dn)
|
||||
|
||||
for host in self.hostnames:
|
||||
for master in ["master", "clone"]:
|
||||
try:
|
||||
cn="%sAgreement1-%s-%s" % (master, host, instance_name)
|
||||
dn = "cn=%s, %s" % (cn, self.replica_dn())
|
||||
dn = DN(('cn', cn), self.replica_dn())
|
||||
self.conn.getEntry(dn, ldap.SCOPE_BASE)
|
||||
return (cn, dn)
|
||||
except errors.NotFound:
|
||||
@ -106,12 +106,10 @@ class CSReplicationManager(replication.ReplicationManager):
|
||||
raise errors.NotFound(reason='No agreement found for %s' % hostname)
|
||||
|
||||
def delete_referral(self, hostname):
|
||||
esc1_suffix = self.suffix.replace('=', '\\3D').replace(',', '\\2C')
|
||||
esc2_suffix = self.suffix.replace('=', '%3D').replace(',', '%2C')
|
||||
dn = 'cn=%s,cn=mapping tree,cn=config' % esc1_suffix
|
||||
dn = DN(('cn', self.suffix), ('cn', 'mapping tree'), ('cn', 'config'))
|
||||
# TODO: should we detect proto/port somehow ?
|
||||
mod = [(ldap.MOD_DELETE, 'nsslapd-referral',
|
||||
'ldap://%s/%s' % (ipautil.format_netloc(hostname, PORT), esc2_suffix))]
|
||||
'ldap://%s/%s' % (ipautil.format_netloc(hostname, PORT), self.suffix))]
|
||||
|
||||
try:
|
||||
self.conn.modify_s(dn, mod)
|
||||
@ -165,16 +163,16 @@ def list_replicas(realm, host, replica, dirman_passwd, verbose):
|
||||
conn = ipaldap.IPAdmin(host, 636, cacert=CACERT)
|
||||
conn.do_simple_bind(bindpw=dirman_passwd)
|
||||
|
||||
dn = str(DN('cn=masters,cn=ipa,cn=etc,%s' % ipautil.realm_to_suffix(realm)))
|
||||
entries = conn.search_s(dn, ldap.SCOPE_ONELEVEL)
|
||||
dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), ipautil.realm_to_suffix(realm))
|
||||
entries = conn.getList(dn, ldap.SCOPE_ONELEVEL)
|
||||
|
||||
for ent in entries:
|
||||
try:
|
||||
cadn = DN(('cn', 'CA'), DN(ent.dn))
|
||||
entry = conn.getEntry(str(cadn), ldap.SCOPE_BASE)
|
||||
peers[ent.cn] = ['master', '']
|
||||
entry = conn.getEntry(cadn, ldap.SCOPE_BASE)
|
||||
peers[ent.getValue('cn')] = ['master', '']
|
||||
except errors.NotFound:
|
||||
peers[ent.cn] = ['CA not configured', '']
|
||||
peers[ent.getValue('cn')] = ['CA not configured', '']
|
||||
|
||||
except Exception, e:
|
||||
sys.exit("Failed to get data from '%s': %s" % (host, convert_error(e)))
|
||||
@ -190,13 +188,13 @@ def list_replicas(realm, host, replica, dirman_passwd, verbose):
|
||||
entries = repl.find_replication_agreements()
|
||||
|
||||
for entry in entries:
|
||||
print '%s' % entry.nsds5replicahost
|
||||
print '%s' % entry.getValue('nsds5replicahost')
|
||||
|
||||
if verbose:
|
||||
print " last init status: %s" % entry.nsds5replicalastinitstatus
|
||||
print " last init ended: %s" % str(ipautil.parse_generalized_time(entry.nsds5replicalastinitend))
|
||||
print " last update status: %s" % entry.nsds5replicalastupdatestatus
|
||||
print " last update ended: %s" % str(ipautil.parse_generalized_time(entry.nsds5replicalastupdateend))
|
||||
print " last init status: %s" % entry.getValue('nsds5replicalastinitstatus')
|
||||
print " last init ended: %s" % str(ipautil.parse_generalized_time(entry.getValue('nsds5replicalastinitend')))
|
||||
print " last update status: %s" % entry.getValue('nsds5replicalastupdatestatus')
|
||||
print " last update ended: %s" % str(ipautil.parse_generalized_time(entry.getValue('nsds5replicalastupdateend')))
|
||||
|
||||
def del_link(realm, replica1, replica2, dirman_passwd, force=False):
|
||||
|
||||
@ -316,7 +314,8 @@ def add_link(realm, replica1, replica2, dirman_passwd, options):
|
||||
conn = ipaldap.IPAdmin(replica2, 636, cacert=CACERT)
|
||||
conn.do_simple_bind(bindpw=dirman_passwd)
|
||||
|
||||
dn = str(DN('cn=CA,cn=%s,cn=masters,cn=ipa,cn=etc,%s' % (replica2, ipautil.realm_to_suffix(realm))))
|
||||
dn = DN(('cn', 'CA'), ('cn', replica2), ('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'),
|
||||
ipautil.realm_to_suffix(realm))
|
||||
conn.search_s(dn, ldap.SCOPE_ONELEVEL)
|
||||
conn.unbind_s()
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
@ -341,7 +340,7 @@ def add_link(realm, replica1, replica2, dirman_passwd, options):
|
||||
except Exception, e:
|
||||
sys.exit("Failed to get data from '%s': %s" % (replica1, convert_error(e)))
|
||||
|
||||
repl1.setup_replication(replica2, PORT, 0, "cn=Directory Manager", dirman_passwd, True, True)
|
||||
repl1.setup_replication(replica2, PORT, 0, DN(('cn', 'Directory Manager')), dirman_passwd, True, True)
|
||||
print "Connected '%s' to '%s'" % (replica1, replica2)
|
||||
|
||||
def re_initialize(realm, options):
|
||||
@ -355,7 +354,7 @@ def re_initialize(realm, options):
|
||||
thishost = installutils.get_fqdn()
|
||||
|
||||
filter = "(&(nsDS5ReplicaHost=%s)(|(objectclass=nsDSWindowsReplicationAgreement)(objectclass=nsds5ReplicationAgreement)))" % thishost
|
||||
entry = repl.conn.search_s("cn=config", ldap.SCOPE_SUBTREE, filter)
|
||||
entry = repl.conn.search_s(DN(('cn', 'config')), ldap.SCOPE_SUBTREE, filter)
|
||||
if len(entry) == 0:
|
||||
root_logger.error("Unable to find %s -> %s replication agreement" % (options.fromhost, thishost))
|
||||
sys.exit(1)
|
||||
|
@ -202,7 +202,7 @@ def main():
|
||||
root_logger.debug("will use dns_forwarders: %s\n", str(dns_forwarders))
|
||||
|
||||
if bind.dm_password:
|
||||
api.Backend.ldap2.connect(bind_dn="cn=Directory Manager", bind_pw=bind.dm_password)
|
||||
api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=bind.dm_password)
|
||||
else:
|
||||
# See if our LDAP server is up and we can talk to it over GSSAPI
|
||||
ccache = krbV.default_context().default_ccache().name
|
||||
|
@ -28,8 +28,8 @@ try:
|
||||
from ipaserver import ipaldap
|
||||
from ipaserver.plugins.ldap2 import ldap2
|
||||
from ipalib import api, errors
|
||||
from ipalib.dn import *
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
|
||||
except ImportError:
|
||||
print >> sys.stderr, """\
|
||||
@ -92,9 +92,8 @@ def main():
|
||||
('cn', 'Definitions'),
|
||||
('cn', 'Managed Entries'),
|
||||
('cn', 'etc'),
|
||||
DN(api.env.basedn)
|
||||
api.env.basedn
|
||||
)
|
||||
managed_entry_definitions_dn = str(managed_entry_definitions_dn)
|
||||
|
||||
conn = None
|
||||
try:
|
||||
@ -125,13 +124,13 @@ def main():
|
||||
# List available Managed Entry Plugins
|
||||
managed_entries = None
|
||||
try:
|
||||
entries = conn.search_s(
|
||||
entries = conn.getList(
|
||||
managed_entry_definitions_dn, ldap.SCOPE_SUBTREE, filter
|
||||
)
|
||||
except Exception, e:
|
||||
root_logger.debug("Search for managed entries failed: %s" % str(e))
|
||||
sys.exit("Unable to find managed entries at %s" % managed_entry_definitions_dn)
|
||||
managed_entries = [entry.cn for entry in entries]
|
||||
managed_entries = [entry.getValue('cn') for entry in entries]
|
||||
if managed_entries:
|
||||
print "Available Managed Entry Definitions:"
|
||||
for managed_entry in managed_entries:
|
||||
@ -142,22 +141,18 @@ def main():
|
||||
if not options.managed_entry:
|
||||
sys.exit("\nYou must specify a managed entry definition")
|
||||
else:
|
||||
rdn = DN(
|
||||
('cn', options.managed_entry),
|
||||
DN(managed_entry_definitions_dn)
|
||||
)
|
||||
def_dn = str(rdn)
|
||||
def_dn = DN(('cn', options.managed_entry), managed_entry_definitions_dn)
|
||||
|
||||
disabled = True
|
||||
try:
|
||||
entries = conn.search_s(def_dn,
|
||||
entry = conn.getEntry(def_dn,
|
||||
ldap.SCOPE_BASE,
|
||||
filter,
|
||||
['originfilter'],
|
||||
)
|
||||
disable_attr = '(objectclass=disable)'
|
||||
try:
|
||||
org_filter = entries[0].originfilter
|
||||
org_filter = entry.getValue('originfilter')
|
||||
disabled = re.search(r'%s' % disable_attr, org_filter)
|
||||
except KeyError:
|
||||
sys.exit("%s is not a valid Managed Entry" % def_dn)
|
||||
|
@ -30,6 +30,7 @@ try:
|
||||
from ipaserver.plugins.ldap2 import ldap2
|
||||
from ipalib import api, errors
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
except ImportError:
|
||||
print >> sys.stderr, """\
|
||||
There was a problem importing one of the required Python modules. The
|
||||
@ -39,8 +40,8 @@ error was:
|
||||
""" % sys.exc_value
|
||||
sys.exit(1)
|
||||
|
||||
nis_config_dn = "cn=NIS Server,cn=plugins,cn=config"
|
||||
compat_dn = "cn=Schema Compatibility,cn=plugins,cn=config"
|
||||
nis_config_dn = DN(('cn', 'NIS Server'), ('cn', 'plugins'), ('cn', 'config'))
|
||||
compat_dn = DN(('cn', 'Schema Compatibility'), ('cn', 'plugins'), ('cn', 'config'))
|
||||
|
||||
def parse_options():
|
||||
usage = "%prog [options] <enable|disable>\n"
|
||||
@ -120,7 +121,7 @@ def main():
|
||||
try:
|
||||
conn = ldap2(shared_instance=False, base_dn='')
|
||||
conn.connect(
|
||||
bind_dn='cn=directory manager', bind_pw=dirman_password
|
||||
bind_dn=DN(('cn', 'directory manager')), bind_pw=dirman_password
|
||||
)
|
||||
except errors.ExecutionError, lde:
|
||||
sys.exit("An error occurred while connecting to the server: %s" % str(lde))
|
||||
|
@ -36,12 +36,13 @@ from ipaserver.install.installutils import ReplicaConfig, expand_replica_info, r
|
||||
from ipaserver.install.installutils import get_host_name, BadHostError
|
||||
from ipaserver.plugins.ldap2 import ldap2
|
||||
from ipaserver.install import cainstance
|
||||
from ipapython import version
|
||||
from ipalib import api, errors, util
|
||||
from ipapython import version
|
||||
from ipapython.config import IPAOptionParser
|
||||
from ipapython import sysrestore
|
||||
from ipapython import services as ipaservices
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
|
||||
log_file_name = "/var/log/ipareplica-install.log"
|
||||
CACERT = "/etc/ipa/ca.crt"
|
||||
@ -204,7 +205,7 @@ def install_http(config, auto_redirect):
|
||||
return http
|
||||
|
||||
def install_bind(config, options):
|
||||
api.Backend.ldap2.connect(bind_dn="cn=Directory Manager",
|
||||
api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')),
|
||||
bind_pw=config.dirman_password)
|
||||
if options.forwarders:
|
||||
forwarders = options.forwarders
|
||||
@ -246,7 +247,7 @@ def install_dns_records(config, options):
|
||||
cur_uri = api.Backend.ldap2.ldap_uri
|
||||
object.__setattr__(api.Backend.ldap2, 'ldap_uri',
|
||||
'ldaps://%s' % ipautil.format_netloc(config.master_host_name))
|
||||
api.Backend.ldap2.connect(bind_dn="cn=Directory Manager",
|
||||
api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')),
|
||||
bind_pw=config.dirman_password,
|
||||
tls_cacertfile=CACERT)
|
||||
bind = bindinstance.BindInstance(dm_password=config.dirman_password)
|
||||
@ -360,10 +361,10 @@ def main():
|
||||
try:
|
||||
fd = open("/etc/ipa/default.conf", "w")
|
||||
fd.write("[global]\n")
|
||||
fd.write("host=" + config.host_name + "\n")
|
||||
fd.write("basedn=" + ipautil.realm_to_suffix(config.realm_name) + "\n")
|
||||
fd.write("realm=" + config.realm_name + "\n")
|
||||
fd.write("domain=" + config.domain_name + "\n")
|
||||
fd.write("host=%s\n" % config.host_name)
|
||||
fd.write("basedn=%s\n" % str(ipautil.realm_to_suffix(config.realm_name)))
|
||||
fd.write("realm=%s\n" % config.realm_name)
|
||||
fd.write("domain=%s\n" % config.domain_name)
|
||||
fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % ipautil.format_netloc(config.host_name))
|
||||
fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % dsinstance.realm_to_serverid(config.realm_name))
|
||||
if ipautil.file_exists(config.dir + "/cacert.p12"):
|
||||
@ -404,14 +405,14 @@ def main():
|
||||
ldapuri = 'ldaps://%s' % ipautil.format_netloc(config.master_host_name)
|
||||
try:
|
||||
conn = ldap2(shared_instance=False, ldap_uri=ldapuri, base_dn='')
|
||||
conn.connect(bind_dn='cn=directory manager',
|
||||
conn.connect(bind_dn=DN(('cn', 'directory manager')),
|
||||
bind_pw=config.dirman_password,
|
||||
tls_cacertfile=CACERT)
|
||||
replman = ReplicationManager(config.realm_name, config.master_host_name,
|
||||
config.dirman_password)
|
||||
found = False
|
||||
try:
|
||||
entry = conn.find_entries(u'fqdn=%s' % host, ['dn', 'fqdn'], u'%s,%s' % (api.env.container_host, api.env.basedn))
|
||||
entry = conn.find_entries(u'fqdn=%s' % host, ['dn', 'fqdn'], DN(api.env.container_host, api.env.basedn))
|
||||
print "The host %s already exists on the master server.\nYou should remove it before proceeding:" % host
|
||||
print " %% ipa host-del %s" % host
|
||||
found = True
|
||||
|
@ -29,8 +29,8 @@ from ipaserver.install import bindinstance
|
||||
from ipaserver import ipaldap
|
||||
from ipapython import version
|
||||
from ipalib import api, errors, util
|
||||
from ipalib.dn import DN
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
|
||||
CACERT = "/etc/ipa/ca.crt"
|
||||
|
||||
@ -125,23 +125,28 @@ def list_replicas(realm, host, replica, dirman_passwd, verbose):
|
||||
conn.do_simple_bind(bindpw=dirman_passwd)
|
||||
else:
|
||||
conn.do_sasl_gssapi_bind()
|
||||
|
||||
dn = 'cn=masters,cn=ipa,cn=etc,%s' % ipautil.realm_to_suffix(realm)
|
||||
entries = conn.search_s(dn, ldap.SCOPE_ONELEVEL)
|
||||
|
||||
for ent in entries:
|
||||
peers[ent.cn] = ['master', '']
|
||||
|
||||
dn = 'cn=replicas,cn=ipa,cn=etc,%s' % ipautil.realm_to_suffix(realm)
|
||||
entries = conn.search_s(dn, ldap.SCOPE_ONELEVEL)
|
||||
|
||||
for ent in entries:
|
||||
peers[ent.cn] = ent.ipaconfigstring.split(':')
|
||||
|
||||
except Exception, e:
|
||||
print "Failed to get data from '%s': %s" % (host, str(e))
|
||||
print "Failed to connect to host '%s': %s" % (host, str(e))
|
||||
return
|
||||
|
||||
dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), ipautil.realm_to_suffix(realm))
|
||||
try:
|
||||
entries = conn.getList(dn, ldap.SCOPE_ONELEVEL)
|
||||
except:
|
||||
print "Failed read master data from '%s': %s" % (host, str(e))
|
||||
return
|
||||
else:
|
||||
for ent in entries:
|
||||
peers[ent.getValue('cn')] = ['master', '']
|
||||
|
||||
dn = DN(('cn', 'replicas'), ('cn', 'ipa'), ('cn', 'etc'), ipautil.realm_to_suffix(realm))
|
||||
try:
|
||||
entries = conn.getList(dn, ldap.SCOPE_ONELEVEL)
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
for ent in entries:
|
||||
peers[ent.getValue('cn')] = ent.getValue('ipaConfigString').split(':')
|
||||
|
||||
if not replica:
|
||||
for k, p in peers.iteritems():
|
||||
@ -164,8 +169,8 @@ def list_replicas(realm, host, replica, dirman_passwd, verbose):
|
||||
repl = replication.ReplicationManager(realm, winsync_peer,
|
||||
dirman_passwd)
|
||||
cn, dn = repl.agreement_dn(replica)
|
||||
entries = repl.conn.search_s(dn, ldap.SCOPE_BASE,
|
||||
"(objectclass=nsDSWindowsReplicationAgreement)")
|
||||
entries = repl.conn.getList(dn, ldap.SCOPE_BASE,
|
||||
"(objectclass=nsDSWindowsReplicationAgreement)")
|
||||
ent_type = 'winsync'
|
||||
else:
|
||||
repl = replication.ReplicationManager(realm, replica,
|
||||
@ -177,13 +182,13 @@ def list_replicas(realm, host, replica, dirman_passwd, verbose):
|
||||
return
|
||||
|
||||
for entry in entries:
|
||||
print '%s: %s' % (entry.nsds5replicahost, ent_type)
|
||||
print '%s: %s' % (entry.getValue('nsds5replicahost'), ent_type)
|
||||
|
||||
if verbose:
|
||||
print " last init status: %s" % entry.nsds5replicalastinitstatus
|
||||
print " last init ended: %s" % str(ipautil.parse_generalized_time(entry.nsds5replicalastinitend))
|
||||
print " last update status: %s" % entry.nsds5replicalastupdatestatus
|
||||
print " last update ended: %s" % str(ipautil.parse_generalized_time(entry.nsds5replicalastupdateend))
|
||||
print " last init status: %s" % entry.getValue('nsds5replicalastinitstatus')
|
||||
print " last init ended: %s" % str(ipautil.parse_generalized_time(entry.getValue('nsds5replicalastinitend')))
|
||||
print " last update status: %s" % entry.getValue('nsds5replicalastupdatestatus')
|
||||
print " last update ended: %s" % str(ipautil.parse_generalized_time(entry.getValue('nsds5replicalastupdateend')))
|
||||
|
||||
def del_link(realm, replica1, replica2, dirman_passwd, force=False):
|
||||
|
||||
@ -254,9 +259,9 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
|
||||
|
||||
if type1 == replication.WINSYNC:
|
||||
try:
|
||||
dn = 'cn=%s,cn=replicas,cn=ipa,cn=etc,%s' % (replica2,
|
||||
ipautil.realm_to_suffix(realm))
|
||||
entries = repl1.conn.search_s(dn, ldap.SCOPE_SUBTREE)
|
||||
dn = DN(('cn', replica2), ('cn', 'replicas'), ('cn', 'ipa'), ('cn', 'etc'),
|
||||
ipautil.realm_to_suffix(realm))
|
||||
entries = repl1.conn.getList(dn, ldap.SCOPE_SUBTREE)
|
||||
if len(entries) != 0:
|
||||
dnset = repl1.conn.get_dns_sorted_by_length(entries,
|
||||
reverse=True)
|
||||
@ -300,11 +305,11 @@ def del_master(realm, hostname, options):
|
||||
force_del = True
|
||||
|
||||
if force_del:
|
||||
dn = 'cn=masters,cn=ipa,cn=etc,%s' % thisrepl.suffix
|
||||
res = thisrepl.conn.search_s(dn, ldap.SCOPE_ONELEVEL)
|
||||
dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), thisrepl.suffix)
|
||||
entries = thisrepl.conn.getList(dn, ldap.SCOPE_ONELEVEL)
|
||||
replica_names = []
|
||||
for entry in res:
|
||||
replica_names.append(entry.cn)
|
||||
for entry in entries:
|
||||
replica_names.append(entry.getValue('cn'))
|
||||
else:
|
||||
# Get list of agreements.
|
||||
replica_names = delrepl.find_ipa_replication_agreements()
|
||||
@ -340,7 +345,7 @@ def del_master(realm, hostname, options):
|
||||
if bindinstance.dns_container_exists(options.host, thisrepl.suffix,
|
||||
dm_password=options.dirman_passwd):
|
||||
if options.dirman_passwd:
|
||||
api.Backend.ldap2.connect(bind_dn='cn=Directory Manager',
|
||||
api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')),
|
||||
bind_pw=options.dirman_passwd)
|
||||
else:
|
||||
ccache = krbV.default_context().default_ccache().name
|
||||
@ -366,7 +371,7 @@ def add_link(realm, replica1, replica2, dirman_passwd, options):
|
||||
repl = replication.ReplicationManager(realm, replica1, dirman_passwd)
|
||||
if repl.get_agreement_type(replica2) == replication.WINSYNC:
|
||||
agreement = repl.get_replication_agreement(replica2)
|
||||
sys.exit("winsync agreement already exists on subtree %s" %
|
||||
sys.exit("winsync agreement already exists on subtree %s" %
|
||||
agreement.getValue('nsds7WindowsReplicaSubtree'))
|
||||
else:
|
||||
sys.exit("A replication agreement to %s already exists" % replica2)
|
||||
@ -407,8 +412,8 @@ def add_link(realm, replica1, replica2, dirman_passwd, options):
|
||||
# from scratch
|
||||
try:
|
||||
masters_dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), (api.env.basedn))
|
||||
master1_dn = str(DN(('cn', replica1), masters_dn))
|
||||
master2_dn = str(DN(('cn', replica2), masters_dn))
|
||||
master1_dn = DN(('cn', replica1), masters_dn)
|
||||
master2_dn = DN(('cn', replica2), masters_dn)
|
||||
|
||||
repl1.conn.getEntry(master1_dn, ldap.SCOPE_BASE)
|
||||
repl1.conn.getEntry(master2_dn, ldap.SCOPE_BASE)
|
||||
|
@ -35,6 +35,7 @@ from ipaserver.plugins.ldap2 import ldap2
|
||||
from ipapython import version
|
||||
from ipapython.config import IPAOptionParser
|
||||
from ipalib import api, errors, util
|
||||
from ipapython.dn import DN
|
||||
|
||||
def parse_options():
|
||||
usage = "%prog [options] FQDN (e.g. replica.example.com)"
|
||||
@ -99,13 +100,16 @@ def parse_options():
|
||||
def get_subject_base(host_name, dm_password, suffix):
|
||||
try:
|
||||
conn = ldap2(shared_instance=False, base_dn=suffix)
|
||||
conn.connect(bind_dn='cn=directory manager', bind_pw=dm_password)
|
||||
conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=dm_password)
|
||||
except errors.ExecutionError, e:
|
||||
root_logger.critical("Could not connect to the Directory Server on %s" % host_name)
|
||||
raise e
|
||||
(dn, entry_attrs) = conn.get_ipa_config()
|
||||
conn.disconnect()
|
||||
return entry_attrs.get('ipacertificatesubjectbase', [None])[0]
|
||||
subject_base = entry_attrs.get('ipacertificatesubjectbase', [None])[0]
|
||||
if subject_base is not None:
|
||||
subject_base = DN(subject_base)
|
||||
return subject_base
|
||||
|
||||
def check_ipa_configuration(realm_name):
|
||||
config_dir = dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name))
|
||||
@ -200,7 +204,7 @@ def save_config(dir, realm_name, host_name,
|
||||
config.set("realm", "master_host_name", host_name)
|
||||
config.set("realm", "domain_name", domain_name)
|
||||
config.set("realm", "destination_host", dest_host)
|
||||
config.set("realm", "subject_base", subject_base)
|
||||
config.set("realm", "subject_base", str(subject_base))
|
||||
fd = open(dir + "/realm_info", "w")
|
||||
config.write(fd)
|
||||
|
||||
@ -260,7 +264,7 @@ def main():
|
||||
# Try out the password
|
||||
try:
|
||||
conn = ldap2(shared_instance=False)
|
||||
conn.connect(bind_dn='cn=directory manager', bind_pw=dirman_password)
|
||||
conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=dirman_password)
|
||||
conn.disconnect()
|
||||
except errors.ACIError:
|
||||
sys.exit("\nThe password provided is incorrect for LDAP server %s" % api.env.host)
|
||||
@ -431,7 +435,7 @@ def main():
|
||||
|
||||
if options.ip_address:
|
||||
print "Adding DNS records for %s" % replica_fqdn
|
||||
api.Backend.ldap2.connect(bind_dn="cn=Directory Manager", bind_pw=dirman_password)
|
||||
api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=dirman_password)
|
||||
|
||||
domain = replica_fqdn.split(".")
|
||||
name = domain.pop(0)
|
||||
|
@ -32,6 +32,7 @@ from ipapython.ipautil import user_input
|
||||
from ipaserver.install import certs, dsinstance, httpinstance, installutils
|
||||
from ipalib import api
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
from ipaserver.plugins.ldap2 import ldap2
|
||||
|
||||
def get_realm_name():
|
||||
@ -66,9 +67,9 @@ def parse_options():
|
||||
|
||||
def set_ds_cert_name(cert_name, dm_password):
|
||||
conn = ldap2(shared_instance=False, base_dn='')
|
||||
conn.connect(bind_dn='cn=directory manager', bind_pw=dm_password)
|
||||
conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=dm_password)
|
||||
mod = {'nssslpersonalityssl': cert_name}
|
||||
conn.update_entry('cn=RSA,cn=encryption,cn=config', mod)
|
||||
conn.update_entry(DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')), mod)
|
||||
conn.disconnect()
|
||||
|
||||
def choose_server_cert(server_certs):
|
||||
|
@ -60,11 +60,11 @@ from ipapython.ipautil import *
|
||||
from ipapython import ipautil
|
||||
from ipalib import api, errors, util
|
||||
from ipapython.config import IPAOptionParser
|
||||
from ipalib.dn import DN
|
||||
from ipalib.x509 import load_certificate_from_file, load_certificate_chain_from_file
|
||||
from ipalib.util import validate_domain_name
|
||||
from ipapython import services as ipaservices
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
|
||||
pw_name = None
|
||||
uninstalling = False
|
||||
@ -530,13 +530,13 @@ def set_subject_in_config(realm_name, dm_password, suffix, subject_base):
|
||||
)
|
||||
try:
|
||||
conn = ldap2(shared_instance=False, ldap_uri=ldapuri, base_dn=suffix)
|
||||
conn.connect(bind_dn='cn=directory manager', bind_pw=dm_password)
|
||||
conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=dm_password)
|
||||
except errors.ExecutionError, e:
|
||||
root_logger.critical("Could not connect to the Directory Server on %s" % realm_name)
|
||||
raise e
|
||||
(dn, entry_attrs) = conn.get_ipa_config()
|
||||
if 'ipacertificatesubjectbase' not in entry_attrs:
|
||||
mod = {'ipacertificatesubjectbase': subject_base}
|
||||
mod = {'ipacertificatesubjectbase': str(subject_base)}
|
||||
conn.update_entry(dn, mod)
|
||||
conn.disconnect()
|
||||
|
||||
@ -770,7 +770,7 @@ def main():
|
||||
realm_name = options.realm_name.upper()
|
||||
|
||||
if not options.subject:
|
||||
options.subject = "O=%s" % realm_name
|
||||
options.subject = DN(('O', realm_name))
|
||||
|
||||
if not options.dm_password:
|
||||
dm_password = read_dm_password()
|
||||
@ -840,10 +840,10 @@ def main():
|
||||
target_fname = '/etc/ipa/default.conf'
|
||||
fd = open(target_fname, "w")
|
||||
fd.write("[global]\n")
|
||||
fd.write("host=" + host_name + "\n")
|
||||
fd.write("basedn=" + ipautil.realm_to_suffix(realm_name) + "\n")
|
||||
fd.write("realm=" + realm_name + "\n")
|
||||
fd.write("domain=" + domain_name + "\n")
|
||||
fd.write("host=%s\n" % host_name)
|
||||
fd.write("basedn=%s\n" % ipautil.realm_to_suffix(realm_name))
|
||||
fd.write("realm=%s\n" % realm_name)
|
||||
fd.write("domain=%s\n" % domain_name)
|
||||
fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % format_netloc(host_name))
|
||||
fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % dsinstance.realm_to_serverid(realm_name))
|
||||
fd.write("enable_ra=True\n")
|
||||
@ -1046,7 +1046,7 @@ def main():
|
||||
persistent_search=options.persistent_search,
|
||||
serial_autoincrement=options.serial_autoincrement)
|
||||
if options.setup_dns:
|
||||
api.Backend.ldap2.connect(bind_dn="cn=Directory Manager", bind_pw=dm_password)
|
||||
api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=dm_password)
|
||||
|
||||
bind.create_instance()
|
||||
print ""
|
||||
|
@ -253,7 +253,7 @@ def update_dbmodules(realm, filename="/etc/krb5.conf"):
|
||||
newfile.append('#%s' % line)
|
||||
prefix = ''
|
||||
continue
|
||||
|
||||
|
||||
newfile.append('%s%s' % (prefix, line))
|
||||
|
||||
# Append updated dbmodules information
|
||||
|
@ -26,10 +26,10 @@ try:
|
||||
from ipaserver.install.dsinstance import config_dirname, realm_to_serverid
|
||||
from ipaserver.install.installutils import is_ipa_configured, ScriptError
|
||||
from ipapython.ipautil import wait_for_open_ports, wait_for_open_socket
|
||||
from ipalib import api, errors
|
||||
from ipapython import sysrestore
|
||||
from ipapython import config
|
||||
from ipalib import api, errors
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
import ldap
|
||||
import ldap.sasl
|
||||
import ldapurl
|
||||
@ -107,8 +107,7 @@ def emit_err(err):
|
||||
sys.stderr.write(err + '\n')
|
||||
|
||||
def get_config(dirsrv):
|
||||
base = "cn=%s,cn=masters,cn=ipa,cn=etc,%s" % (api.env.host,
|
||||
api.env.basedn)
|
||||
base = DN(('cn', api.env.host), ('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
|
||||
srcfilter = '(ipaConfigString=enabledService)'
|
||||
attrs = ['cn', 'ipaConfigString']
|
||||
if not dirsrv.is_running():
|
||||
@ -127,7 +126,7 @@ def get_config(dirsrv):
|
||||
wait_for_open_ports(host, [int(port)], timeout=api.env.startup_timeout)
|
||||
con = ldap.initialize(api.env.ldap_uri)
|
||||
con.sasl_interactive_bind_s('', SASL_EXTERNAL)
|
||||
res = con.search_st(base,
|
||||
res = con.search_st(str(base),
|
||||
ldap.SCOPE_SUBTREE,
|
||||
filterstr=srcfilter,
|
||||
attrlist=attrs,
|
||||
@ -138,12 +137,10 @@ def get_config(dirsrv):
|
||||
"Directory Server is stopped", 3)
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
masters_list = []
|
||||
dn = str(DN('cn=masters,cn=ipa,cn=etc,%s' % api.env.basedn))
|
||||
dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
|
||||
attrs = ['cn']
|
||||
try:
|
||||
entries = con.search_s(dn,
|
||||
ldap.SCOPE_ONELEVEL,
|
||||
attrlist=attrs,)
|
||||
entries = con.search_s(str(dn), ldap.SCOPE_ONELEVEL, attrlist=attrs)
|
||||
except Exception, e:
|
||||
masters_list.append("No master found because of error: %s" % str(e))
|
||||
else:
|
||||
|
@ -31,12 +31,12 @@ import SSSDConfig
|
||||
|
||||
from optparse import OptionParser
|
||||
from ipalib import api, errors
|
||||
from ipalib.dn import DN
|
||||
from ipapython import sysrestore
|
||||
from ipapython import ipautil
|
||||
from ipaclient import ipadiscovery
|
||||
from ipaclient import ipachangeconf
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
from ipapython import services as ipaservices
|
||||
|
||||
AUTOFS_CONF = '/etc/sysconfig/autofs'
|
||||
|
@ -41,6 +41,7 @@ try:
|
||||
from ipapython import certmonger
|
||||
from ipapython.config import IPAOptionParser
|
||||
from ipalib import api, errors
|
||||
from ipapython.dn import DN
|
||||
import SSSDConfig
|
||||
from ConfigParser import RawConfigParser
|
||||
from optparse import SUPPRESS_HELP, OptionGroup
|
||||
@ -510,8 +511,8 @@ def configure_ldap_conf(fstore, cli_basedn, cli_realm, cli_domain, cli_server, d
|
||||
{'name':'ldap_version', 'type':'option', 'value':'3'},
|
||||
{'name':'base', 'type':'option', 'value':cli_basedn},
|
||||
{'name':'empty', 'type':'empty'},
|
||||
{'name':'nss_base_passwd', 'type':'option', 'value':'cn=users,cn=accounts,'+cli_basedn+'?sub'},
|
||||
{'name':'nss_base_group', 'type':'option', 'value':'cn=groups,cn=accounts,'+cli_basedn+'?sub'},
|
||||
{'name':'nss_base_passwd', 'type':'option', 'value':str(DN(('cn', 'users'), ('cn', 'accounts'), cli_basedn))+'?sub'},
|
||||
{'name':'nss_base_group', 'type':'option', 'value':str(DN(('cn', 'groups'), ('cn', 'accounts'), cli_basedn))+'?sub'},
|
||||
{'name':'nss_schema', 'type':'option', 'value':'rfc2307bis'},
|
||||
{'name':'nss_map_attribute', 'type':'option', 'value':'uniqueMember member'},
|
||||
{'name':'nss_initgroups_ignoreusers', 'type':'option', 'value':'root,dirsrv'},
|
||||
@ -555,8 +556,8 @@ def configure_nslcd_conf(fstore, cli_basedn, cli_realm, cli_domain, cli_server,
|
||||
{'name':'ldap_version', 'type':'option', 'value':'3'},
|
||||
{'name':'base', 'type':'option', 'value':cli_basedn},
|
||||
{'name':'empty', 'type':'empty'},
|
||||
{'name':'base passwd', 'type':'option', 'value':'cn=users,cn=accounts,'+cli_basedn},
|
||||
{'name':'base group', 'type':'option', 'value':'cn=groups,cn=accounts,'+cli_basedn},
|
||||
{'name':'base passwd', 'type':'option', 'value':str(DN(('cn', 'users'), ('cn', 'accounts'), cli_basedn))},
|
||||
{'name':'base group', 'type':'option', 'value':str(DN(('cn', 'groups'), ('cn', 'accounts'), cli_basedn))},
|
||||
{'name':'map group', 'type':'option', 'value':'uniqueMember member'},
|
||||
{'name':'timelimit', 'type':'option', 'value':'15'},
|
||||
{'name':'empty', 'type':'empty'}]
|
||||
@ -743,9 +744,9 @@ def configure_certmonger(fstore, subject_base, cli_realm, hostname, options):
|
||||
# Request our host cert
|
||||
if started:
|
||||
client_nss_nickname = client_nss_nickname_format % hostname
|
||||
subject = 'CN=%s,%s' % (hostname, subject_base)
|
||||
subject = DN(('CN', hostname), subject_base)
|
||||
try:
|
||||
run(["ipa-getcert", "request", "-d", "/etc/pki/nssdb", "-n", client_nss_nickname, "-N", subject, "-K", principal])
|
||||
run(["ipa-getcert", "request", "-d", "/etc/pki/nssdb", "-n", client_nss_nickname, "-N", str(subject), "-K", principal])
|
||||
except:
|
||||
root_logger.error(
|
||||
"%s request for host certificate failed", cmonger.service_name)
|
||||
@ -1337,7 +1338,7 @@ def install(options, env, fstore, statestore):
|
||||
cli_basedn = ds.basedn
|
||||
cli_basedn_source = ds.basedn_source
|
||||
root_logger.debug("will use discovered basedn: %s", cli_basedn)
|
||||
subject_base = "O=%s" % cli_realm
|
||||
subject_base = DN(('O', cli_realm))
|
||||
|
||||
# Now do a sanity check on the other servers
|
||||
if options.server and len(options.server) > 1:
|
||||
@ -1431,7 +1432,7 @@ def install(options, env, fstore, statestore):
|
||||
root_logger.error("Test kerberos configuration failed")
|
||||
return CLIENT_INSTALL_ERROR
|
||||
env['KRB5_CONFIG'] = krb_name
|
||||
join_args = ["/usr/sbin/ipa-join", "-s", cli_server[0], "-b", realm_to_suffix(cli_realm)]
|
||||
join_args = ["/usr/sbin/ipa-join", "-s", cli_server[0], "-b", str(realm_to_suffix(cli_realm))]
|
||||
if options.debug:
|
||||
join_args.append("-d")
|
||||
env['XMLRPC_TRACE_CURL'] = 'yes'
|
||||
@ -1508,6 +1509,7 @@ def install(options, env, fstore, statestore):
|
||||
start = start + 29
|
||||
subject_base = stderr[start:]
|
||||
subject_base = subject_base.strip()
|
||||
subject_base = DN(subject_base)
|
||||
|
||||
finally:
|
||||
if options.principal is not None:
|
||||
|
@ -28,7 +28,7 @@ from dns.exception import DNSException
|
||||
|
||||
from ipapython.ipautil import run, CalledProcessError, valid_ip, get_ipa_basedn, \
|
||||
realm_to_suffix, format_netloc
|
||||
|
||||
from ipapython.dn import DN
|
||||
|
||||
NOT_FQDN = -1
|
||||
NO_LDAP_SERVER = -2
|
||||
@ -320,7 +320,7 @@ class IPADiscovery(object):
|
||||
root_logger.debug(
|
||||
"Search for (objectClass=krbRealmContainer) in %s (sub)",
|
||||
self.basedn)
|
||||
lret = lh.search_s("cn=kerberos,"+self.basedn, ldap.SCOPE_SUBTREE, "(objectClass=krbRealmContainer)")
|
||||
lret = lh.search_s(str(DN(('cn', 'kerberos'), self.basedn)), ldap.SCOPE_SUBTREE, "(objectClass=krbRealmContainer)")
|
||||
if not lret:
|
||||
#something very wrong
|
||||
return [REALM_NOT_FOUND]
|
||||
|
@ -878,7 +878,7 @@ from backend import Backend
|
||||
from frontend import Command, LocalOrRemote, Updater
|
||||
from frontend import Object, Method, Property
|
||||
from crud import Create, Retrieve, Update, Delete, Search
|
||||
from parameters import DefaultFrom, Bool, Flag, Int, Decimal, Bytes, Str, IA5Str, Password
|
||||
from parameters import DefaultFrom, Bool, Flag, Int, Decimal, Bytes, Str, IA5Str, Password, DNParam
|
||||
from parameters import BytesEnum, StrEnum, AccessTime, File
|
||||
from errors import SkipPluginModule
|
||||
from text import _, ngettext, GettextFactory, NGettextFactory
|
||||
|
@ -254,32 +254,6 @@ class ACI:
|
||||
# We got this far so lets declare them the same
|
||||
return True
|
||||
|
||||
def extract_group_cns(aci_list, client):
|
||||
"""
|
||||
Extracts all the cn's from a list of aci's and returns them as a hash
|
||||
from group_dn to group_cn.
|
||||
|
||||
It first tries to cheat by looking at the first rdn for the
|
||||
group dn. If that's not cn for some reason, it looks up the group.
|
||||
"""
|
||||
group_dn_to_cn = {}
|
||||
for aci in aci_list:
|
||||
for dn in (aci.source_group, aci.dest_group):
|
||||
if not group_dn_to_cn.has_key(dn):
|
||||
rdn_list = ldap.explode_dn(dn, 0)
|
||||
first_rdn = rdn_list[0]
|
||||
(type,value) = first_rdn.split('=')
|
||||
if type == "cn":
|
||||
group_dn_to_cn[dn] = value
|
||||
else:
|
||||
try:
|
||||
group = client.get_entry_by_dn(dn, ['cn'])
|
||||
group_dn_to_cn[dn] = group.getValue('cn')
|
||||
except Exception:
|
||||
group_dn_to_cn[dn] = 'unknown'
|
||||
|
||||
return group_dn_to_cn
|
||||
|
||||
if __name__ == '__main__':
|
||||
# a = ACI('(targetattr="title")(targetfilter="(memberOf=cn=bar,cn=groups,cn=accounts ,dc=example,dc=com)")(version 3.0;acl "foobar";allow (write) groupdn="ldap:///cn=foo,cn=groups,cn=accounts,dc=example,dc=com";)')
|
||||
# print a
|
||||
|
@ -35,6 +35,7 @@ import os
|
||||
from os import path
|
||||
import sys
|
||||
from socket import getfqdn
|
||||
from ipapython.dn import DN
|
||||
|
||||
from base import check_name
|
||||
from constants import CONFIG_SECTION
|
||||
@ -256,12 +257,14 @@ class Env(object):
|
||||
value = m[value]
|
||||
elif value.isdigit():
|
||||
value = int(value)
|
||||
elif key in ('basedn'):
|
||||
value = DN(value)
|
||||
else:
|
||||
try:
|
||||
value = float(value)
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
assert type(value) in (unicode, int, float, bool, NoneType)
|
||||
assert type(value) in (unicode, int, float, bool, NoneType, DN)
|
||||
object.__setattr__(self, key, value)
|
||||
self.__d[key] = value
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
All constants centralised in one file.
|
||||
"""
|
||||
import socket
|
||||
from ipapython.dn import DN
|
||||
from ipapython.version import VERSION
|
||||
try:
|
||||
FQDN = socket.getfqdn()
|
||||
@ -69,44 +70,44 @@ DEFAULT_CONFIG = (
|
||||
# Domain, realm, basedn:
|
||||
('domain', 'example.com'),
|
||||
('realm', 'EXAMPLE.COM'),
|
||||
('basedn', 'dc=example,dc=com'),
|
||||
('basedn', DN(('dc', 'example'), ('dc', 'com'))),
|
||||
|
||||
# LDAP containers:
|
||||
('container_accounts', 'cn=accounts'),
|
||||
('container_user', 'cn=users,cn=accounts'),
|
||||
('container_group', 'cn=groups,cn=accounts'),
|
||||
('container_service', 'cn=services,cn=accounts'),
|
||||
('container_host', 'cn=computers,cn=accounts'),
|
||||
('container_hostgroup', 'cn=hostgroups,cn=accounts'),
|
||||
('container_rolegroup', 'cn=roles,cn=accounts'),
|
||||
('container_permission', 'cn=permissions,cn=pbac'),
|
||||
('container_privilege', 'cn=privileges,cn=pbac'),
|
||||
('container_automount', 'cn=automount'),
|
||||
('container_policies', 'cn=policies'),
|
||||
('container_configs', 'cn=configs,cn=policies'),
|
||||
('container_roles', 'cn=roles,cn=policies'),
|
||||
('container_applications', 'cn=applications,cn=configs,cn=policies'),
|
||||
('container_policygroups', 'cn=policygroups,cn=configs,cn=policies'),
|
||||
('container_policylinks', 'cn=policylinks,cn=configs,cn=policies'),
|
||||
('container_netgroup', 'cn=ng,cn=alt'),
|
||||
('container_hbac', 'cn=hbac'),
|
||||
('container_hbacservice', 'cn=hbacservices,cn=hbac'),
|
||||
('container_hbacservicegroup', 'cn=hbacservicegroups,cn=hbac'),
|
||||
('container_dns', 'cn=dns'),
|
||||
('container_virtual', 'cn=virtual operations,cn=etc'),
|
||||
('container_sudorule', 'cn=sudorules,cn=sudo'),
|
||||
('container_sudocmd', 'cn=sudocmds,cn=sudo'),
|
||||
('container_sudocmdgroup', 'cn=sudocmdgroups,cn=sudo'),
|
||||
('container_entitlements', 'cn=entitlements,cn=etc'),
|
||||
('container_automember', 'cn=automember,cn=etc'),
|
||||
('container_selinux', 'cn=usermap,cn=selinux'),
|
||||
('container_s4u2proxy', 'cn=s4u2proxy,cn=etc'),
|
||||
('container_cifsdomains', 'cn=ad,cn=etc'),
|
||||
('container_trusts', 'cn=trusts'),
|
||||
('container_adtrusts', 'cn=ad,cn=trusts'),
|
||||
('container_ranges', 'cn=ranges,cn=etc'),
|
||||
('container_dna', 'cn=dna,cn=ipa,cn=etc'),
|
||||
('container_dna_posix_ids', 'cn=posix-ids,cn=dna,cn=ipa,cn=etc'),
|
||||
('container_accounts', DN(('cn', 'accounts'))),
|
||||
('container_user', DN(('cn', 'users'), ('cn', 'accounts'))),
|
||||
('container_group', DN(('cn', 'groups'), ('cn', 'accounts'))),
|
||||
('container_service', DN(('cn', 'services'), ('cn', 'accounts'))),
|
||||
('container_host', DN(('cn', 'computers'), ('cn', 'accounts'))),
|
||||
('container_hostgroup', DN(('cn', 'hostgroups'), ('cn', 'accounts'))),
|
||||
('container_rolegroup', DN(('cn', 'roles'), ('cn', 'accounts'))),
|
||||
('container_permission', DN(('cn', 'permissions'), ('cn', 'pbac'))),
|
||||
('container_privilege', DN(('cn', 'privileges'), ('cn', 'pbac'))),
|
||||
('container_automount', DN(('cn', 'automount'))),
|
||||
('container_policies', DN(('cn', 'policies'))),
|
||||
('container_configs', DN(('cn', 'configs'), ('cn', 'policies'))),
|
||||
('container_roles', DN(('cn', 'roles'), ('cn', 'policies'))),
|
||||
('container_applications', DN(('cn', 'applications'), ('cn', 'configs'), ('cn', 'policies'))),
|
||||
('container_policygroups', DN(('cn', 'policygroups'), ('cn', 'configs'), ('cn', 'policies'))),
|
||||
('container_policylinks', DN(('cn', 'policylinks'), ('cn', 'configs'), ('cn', 'policies'))),
|
||||
('container_netgroup', DN(('cn', 'ng'), ('cn', 'alt'))),
|
||||
('container_hbac', DN(('cn', 'hbac'))),
|
||||
('container_hbacservice', DN(('cn', 'hbacservices'), ('cn', 'hbac'))),
|
||||
('container_hbacservicegroup', DN(('cn', 'hbacservicegroups'), ('cn', 'hbac'))),
|
||||
('container_dns', DN(('cn', 'dns'))),
|
||||
('container_virtual', DN(('cn', 'virtual operations'), ('cn', 'etc'))),
|
||||
('container_sudorule', DN(('cn', 'sudorules'), ('cn', 'sudo'))),
|
||||
('container_sudocmd', DN(('cn', 'sudocmds'), ('cn', 'sudo'))),
|
||||
('container_sudocmdgroup', DN(('cn', 'sudocmdgroups'), ('cn', 'sudo'))),
|
||||
('container_entitlements', DN(('cn', 'entitlements'), ('cn', 'etc'))),
|
||||
('container_automember', DN(('cn', 'automember'), ('cn', 'etc'))),
|
||||
('container_selinux', DN(('cn', 'usermap'), ('cn', 'selinux'))),
|
||||
('container_s4u2proxy', DN(('cn', 's4u2proxy'), ('cn', 'etc'))),
|
||||
('container_cifsdomains', DN(('cn', 'ad'), ('cn', 'etc'))),
|
||||
('container_trusts', DN(('cn', 'trusts'))),
|
||||
('container_adtrusts', DN(('cn', 'ad'), ('cn', 'trusts'))),
|
||||
('container_ranges', DN(('cn', 'ranges'), ('cn', 'etc'))),
|
||||
('container_dna', DN(('cn', 'dna'), ('cn', 'ipa'), ('cn', 'etc'))),
|
||||
('container_dna_posix_ids', DN(('cn', 'posix-ids'), ('cn', 'dna'), ('cn', 'ipa'), ('cn', 'etc'))),
|
||||
|
||||
# Ports, hosts, and URIs:
|
||||
# FIXME: let's renamed xmlrpc_uri to rpc_xml_uri
|
||||
|
@ -1,213 +0,0 @@
|
||||
# Authors:
|
||||
# Pavel Zuna <pzuna@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2009 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, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Encoding capabilities.
|
||||
"""
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
class EncoderSettings(object):
|
||||
"""
|
||||
Container for encoder settings.
|
||||
"""
|
||||
encode_to = 'utf-8'
|
||||
encode_none = False
|
||||
encode_dict_keys = False
|
||||
encode_dict_keys_postprocess = True
|
||||
encode_dict_vals = True
|
||||
encode_dict_vals_postprocess = True
|
||||
encode_postprocessor = staticmethod(lambda x: x)
|
||||
|
||||
decode_from = 'utf-8'
|
||||
decode_none = False
|
||||
decode_dict_keys = False
|
||||
decode_dict_keys_postprocess = True
|
||||
decode_dict_vals = True
|
||||
decode_dict_vals_postprocess = True
|
||||
decode_dict_vals_table = dict()
|
||||
decode_dict_vals_table_keygen = staticmethod(lambda x, y: x)
|
||||
decode_postprocessor = staticmethod(lambda x: x)
|
||||
|
||||
|
||||
class Encoder(object):
|
||||
"""
|
||||
Base class implementing encoding of python scalar types to strings
|
||||
and vise-versa.
|
||||
"""
|
||||
|
||||
encoder_settings = EncoderSettings()
|
||||
|
||||
def __init__(self):
|
||||
# each instance should have its own settings
|
||||
self.encoder_settings = EncoderSettings()
|
||||
|
||||
def _decode_dict_val(self, key, val):
|
||||
f = self.encoder_settings.decode_dict_vals_table.get(
|
||||
self.encoder_settings.decode_dict_vals_table_keygen(key, val)
|
||||
)
|
||||
if f:
|
||||
return val
|
||||
return self.decode(val)
|
||||
|
||||
def encode(self, var):
|
||||
"""
|
||||
Encode any python built-in python type variable into `self.encode_to`.
|
||||
|
||||
Compound types have their individual members encoded.
|
||||
|
||||
Returns an encoded copy of 'var'.
|
||||
"""
|
||||
if isinstance(var, str):
|
||||
return var
|
||||
elif isinstance(var, unicode):
|
||||
return self.encoder_settings.encode_postprocessor(
|
||||
var.encode(self.encoder_settings.encode_to)
|
||||
)
|
||||
elif isinstance(var, bool):
|
||||
if var:
|
||||
var = 'TRUE'
|
||||
else:
|
||||
var = 'FALSE'
|
||||
return self.encoder_settings.encode_postprocessor(
|
||||
var.encode(self.encoder_settings.encode_to)
|
||||
)
|
||||
elif isinstance(var, (float, Decimal, int, long)):
|
||||
return self.encoder_settings.encode_postprocessor(
|
||||
str(var).encode(self.encoder_settings.encode_to)
|
||||
)
|
||||
elif isinstance(var, list):
|
||||
return [self.encode(m) for m in var]
|
||||
elif isinstance(var, tuple):
|
||||
return tuple(self.encode(m) for m in var)
|
||||
elif isinstance(var, dict):
|
||||
if self.encoder_settings.encode_dict_keys:
|
||||
dct = dict()
|
||||
if not self.encoder_settings.encode_dict_keys_postprocess:
|
||||
tmp = self.encoder_settings.encode_postprocessor
|
||||
self.encoder_settings.encode_postprocessor = lambda x: x
|
||||
for (k, v) in var.iteritems():
|
||||
dct[self.encode(k)] = v
|
||||
if not self.encoder_settings.encode_dict_keys_postprocess:
|
||||
self.encoder_settings.encode_postprocessor = tmp
|
||||
else:
|
||||
dct = dict(var)
|
||||
if self.encoder_settings.encode_dict_vals:
|
||||
if not self.encoder_settings.encode_dict_vals_postprocess:
|
||||
tmp = self.encoder_settings.encode_postprocessor
|
||||
self.encoder_settings.encode_postprocessor = lambda x: x
|
||||
for (k, v) in dct.iteritems():
|
||||
dct[k] = self.encode(v)
|
||||
if not self.encoder_settings.encode_dict_vals_postprocess:
|
||||
self.encoder_settings.encode_postprocessor = tmp
|
||||
return dct
|
||||
elif var is None:
|
||||
if self.encoder_settings.encode_none:
|
||||
return self.encoder_settings.encode_postprocessor(
|
||||
str(var).encode(self.encoder_settings.encode_to)
|
||||
)
|
||||
return None
|
||||
raise TypeError('python built-in type expected, got \'%s\'', type(var))
|
||||
|
||||
def decode(self, var):
|
||||
"""
|
||||
Decode strings in `self.decode_from` into python strings.
|
||||
|
||||
Compound types have their individual members decoded.
|
||||
|
||||
Dictionaries can have their values decoded into other types
|
||||
by looking up keys in `self.decode_dict_vals_table`.
|
||||
|
||||
Returns a decoded copy of 'var'.
|
||||
"""
|
||||
if isinstance(var, unicode):
|
||||
return var
|
||||
elif isinstance(var, str):
|
||||
return self.encoder_settings.decode_postprocessor(
|
||||
var.decode(self.encoder_settings.decode_from)
|
||||
)
|
||||
elif isinstance(var, (bool, float, Decimal, int, long)):
|
||||
return var
|
||||
elif isinstance(var, list):
|
||||
return [self.decode(m) for m in var]
|
||||
elif isinstance(var, tuple):
|
||||
return tuple(self.decode(m) for m in var)
|
||||
elif isinstance(var, dict):
|
||||
if self.encoder_settings.decode_dict_keys:
|
||||
dct = dict()
|
||||
if not self.encoder_settings.decode_dict_keys_postprocess:
|
||||
tmp = self.encoder_settings.decode_postprocessor
|
||||
self.encoder_settings.decode_postprocessor = lambda x: x
|
||||
for (k, v) in var.iteritems():
|
||||
dct[self.decode(k)] = v
|
||||
if not self.encoder_settings.decode_dict_keys_postprocess:
|
||||
self.encoder_settings.decode_postprocessor = tmp
|
||||
else:
|
||||
dct = dict(var)
|
||||
if self.encoder_settings.decode_dict_vals:
|
||||
if not self.encoder_settings.decode_dict_vals_postprocess:
|
||||
tmp = self.encoder_settings.decode_postprocessor
|
||||
self.encoder_settings.decode_postprocessor = lambda x: x
|
||||
for (k, v) in dct.iteritems():
|
||||
dct[k] = self._decode_dict_val(k, v)
|
||||
if not self.encoder_settings.decode_dict_vals_postprocess:
|
||||
self.encoder_settings.decode_postprocessor = tmp
|
||||
return dct
|
||||
elif var is None:
|
||||
if self.encoder_settings.decode_none:
|
||||
return self.encoder_settings.decode_postprocessor(
|
||||
str(var).decode(self.encoder_settings.decode_from)
|
||||
)
|
||||
return None
|
||||
raise TypeError('python built-in type expected, got \'%s\'', type(var))
|
||||
|
||||
## ENCODER METHOD DECORATORS
|
||||
|
||||
def encode_args(*outer_args):
|
||||
def decorate(f):
|
||||
def new_f(*args, **kwargs):
|
||||
assert isinstance(args[0], Encoder), \
|
||||
'first argument not Encoder instance'
|
||||
new_args = list(args)
|
||||
for a in outer_args:
|
||||
if isinstance(a, int):
|
||||
if a < len(args):
|
||||
new_args[a] = args[0].encode(args[a])
|
||||
elif isinstance(a, basestring):
|
||||
if a in kwargs:
|
||||
kwargs[a] = args[0].encode(kwargs[a])
|
||||
else:
|
||||
raise TypeError(
|
||||
'encode_args takes a list of ints and basestrings'
|
||||
)
|
||||
return f(*new_args, **kwargs)
|
||||
new_f.func_name = f.func_name
|
||||
return new_f
|
||||
return decorate
|
||||
|
||||
|
||||
def decode_retval():
|
||||
def decorate(f):
|
||||
def new_f(*args, **kwargs):
|
||||
assert isinstance(args[0], Encoder), \
|
||||
'first argument not Encoder instance'
|
||||
return args[0].decode(f(*args, **kwargs))
|
||||
new_f.func_name = f.func_name
|
||||
return new_f
|
||||
return decorate
|
||||
|
@ -112,7 +112,7 @@ from errors import ConversionError, RequirementError, ValidationError
|
||||
from errors import PasswordMismatch
|
||||
from constants import NULLS, TYPE_ERROR, CALLABLE_ERROR
|
||||
from text import Gettext, FixMe
|
||||
|
||||
from ipapython.dn import DN
|
||||
|
||||
class DefaultFrom(ReadOnly):
|
||||
"""
|
||||
@ -1845,6 +1845,23 @@ class AccessTime(Str):
|
||||
return None
|
||||
|
||||
|
||||
class DNParam(Param):
|
||||
type = DN
|
||||
|
||||
def _convert_scalar(self, value, index=None):
|
||||
"""
|
||||
Convert a single scalar value.
|
||||
"""
|
||||
if type(value) is self.type:
|
||||
return value
|
||||
|
||||
try:
|
||||
dn = DN(value)
|
||||
except Exception, e:
|
||||
raise ConversionError(name=self.get_param_name(), index=index,
|
||||
error=ugettext(e))
|
||||
return dn
|
||||
|
||||
def create_param(spec):
|
||||
"""
|
||||
Create an `Str` instance from the shorthand ``spec``.
|
||||
|
@ -123,24 +123,22 @@ from ipalib import api, crud, errors
|
||||
from ipalib import Object, Command
|
||||
from ipalib import Flag, Int, Str, StrEnum
|
||||
from ipalib.aci import ACI
|
||||
from ipalib.dn import DN
|
||||
from ipalib import output
|
||||
from ipalib import _, ngettext
|
||||
from ipalib.plugins.baseldap import gen_pkey_only_option
|
||||
if api.env.in_server and api.env.context in ['lite', 'server']:
|
||||
from ldap import explode_dn
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
|
||||
ACI_NAME_PREFIX_SEP = ":"
|
||||
|
||||
_type_map = {
|
||||
'user': 'ldap:///uid=*,%s,%s' % (api.env.container_user, api.env.basedn),
|
||||
'group': 'ldap:///cn=*,%s,%s' % (api.env.container_group, api.env.basedn),
|
||||
'host': 'ldap:///fqdn=*,%s,%s' % (api.env.container_host, api.env.basedn),
|
||||
'hostgroup': 'ldap:///cn=*,%s,%s' % (api.env.container_hostgroup, api.env.basedn),
|
||||
'service': 'ldap:///krbprincipalname=*,%s,%s' % (api.env.container_service, api.env.basedn),
|
||||
'netgroup': 'ldap:///ipauniqueid=*,%s,%s' % (api.env.container_netgroup, api.env.basedn),
|
||||
'dnsrecord': 'ldap:///idnsname=*,%s,%s' % (api.env.container_dns, api.env.basedn),
|
||||
'user': 'ldap:///' + str(DN(('uid', '*'), api.env.container_user, api.env.basedn)),
|
||||
'group': 'ldap:///' + str(DN(('cn', '*'), api.env.container_group, api.env.basedn)),
|
||||
'host': 'ldap:///' + str(DN(('fqdn', '*'), api.env.container_host, api.env.basedn)),
|
||||
'hostgroup': 'ldap:///' + str(DN(('cn', '*'), api.env.container_hostgroup, api.env.basedn)),
|
||||
'service': 'ldap:///' + str(DN(('krbprincipalname', '*'), api.env.container_service, api.env.basedn)),
|
||||
'netgroup': 'ldap:///' + str(DN(('ipauniqueid', '*'), api.env.container_netgroup, api.env.basedn)),
|
||||
'dnsrecord': 'ldap:///' + str(DN(('idnsname', '*'), api.env.container_dns, api.env.basedn)),
|
||||
}
|
||||
|
||||
_valid_permissions_values = [
|
||||
@ -247,7 +245,7 @@ def _make_aci(ldap, current, aciname, kw):
|
||||
if 'test' in kw and not kw.get('test'):
|
||||
raise e
|
||||
else:
|
||||
entry_attrs = {'dn': 'cn=%s,%s' % (kw['permission'], api.env.container_permission)}
|
||||
entry_attrs = {'dn': DN(('cn', kw['permission']), api.env.container_permission)}
|
||||
elif group:
|
||||
# Not so friendly with groups. This will raise
|
||||
try:
|
||||
@ -343,10 +341,9 @@ def _aci_to_kw(ldap, a, test=False, pkey_only=False):
|
||||
else:
|
||||
# See if the target is a group. If so we set the
|
||||
# targetgroup attr, otherwise we consider it a subtree
|
||||
if api.env.container_group in target:
|
||||
targetdn = unicode(target.replace('ldap:///',''))
|
||||
target = DN(targetdn)
|
||||
kw['targetgroup'] = target['cn']
|
||||
targetdn = DN(target.replace('ldap:///',''))
|
||||
if targetdn.endswith(DN(api.env.container_group, api.env.basedn)):
|
||||
kw['targetgroup'] = targetdn[0]['cn']
|
||||
else:
|
||||
kw['subtree'] = unicode(target)
|
||||
|
||||
@ -357,15 +354,16 @@ def _aci_to_kw(ldap, a, test=False, pkey_only=False):
|
||||
elif groupdn == 'anyone':
|
||||
pass
|
||||
else:
|
||||
if groupdn.startswith('cn='):
|
||||
dn = ''
|
||||
groupdn = DN(groupdn)
|
||||
if len(groupdn) and groupdn[0].attr == 'cn':
|
||||
dn = DN()
|
||||
entry_attrs = {}
|
||||
try:
|
||||
(dn, entry_attrs) = ldap.get_entry(groupdn, ['cn'])
|
||||
except errors.NotFound, e:
|
||||
# FIXME, use real name here
|
||||
if test:
|
||||
dn = 'cn=%s,%s' % ('test', api.env.container_permission)
|
||||
dn = DN(('cn', 'test'), api.env.container_permission)
|
||||
entry_attrs = {'cn': [u'test']}
|
||||
if api.env.container_permission in dn:
|
||||
kw['permission'] = entry_attrs['cn'][0]
|
||||
@ -801,11 +799,11 @@ class aci_find(crud.Search):
|
||||
if kw.get('group'):
|
||||
for a in acis:
|
||||
groupdn = a.bindrule['expression']
|
||||
groupdn = groupdn.replace('ldap:///','')
|
||||
cn = None
|
||||
if groupdn.startswith('cn='):
|
||||
cn = explode_dn(groupdn)[0]
|
||||
cn = cn.replace('cn=','')
|
||||
groupdn = DN(groupdn.replace('ldap:///',''))
|
||||
try:
|
||||
cn = groupdn[0]['cn'].value
|
||||
except (IndexError, KeyError):
|
||||
cn = None
|
||||
if cn is None or cn != kw['group']:
|
||||
try:
|
||||
results.remove(a)
|
||||
@ -818,9 +816,11 @@ class aci_find(crud.Search):
|
||||
if 'target' in a.target:
|
||||
target = a.target['target']['expression']
|
||||
if api.env.container_group in target:
|
||||
targetdn = unicode(target.replace('ldap:///',''))
|
||||
cn = explode_dn(targetdn)[0]
|
||||
cn = cn.replace('cn=','')
|
||||
targetdn = DN(target.replace('ldap:///',''))
|
||||
try:
|
||||
cn = targetdn[0]['cn']
|
||||
except (IndexError, KeyError):
|
||||
cn = None
|
||||
if cn == kw['targetgroup']:
|
||||
found = True
|
||||
if not found:
|
||||
|
@ -22,8 +22,8 @@ from ipalib import Str, StrEnum
|
||||
from ipalib.plugins.baseldap import *
|
||||
from ipalib import _, ngettext
|
||||
from ipalib.request import context
|
||||
from ipalib.dn import *
|
||||
import ldap as _ldap
|
||||
from ipapython.dn import DN
|
||||
|
||||
__doc__ = _("""
|
||||
Auto Membership Rule.
|
||||
@ -200,19 +200,16 @@ class automember(LDAPObject):
|
||||
parent_dn = self.container_dn
|
||||
grouptype = options['type']
|
||||
try:
|
||||
ndn = DN(('cn', keys[-1]), ('cn', grouptype), DN(parent_dn))
|
||||
ndn = DN(('cn', keys[-1]), ('cn', grouptype), parent_dn)
|
||||
except IndexError:
|
||||
ndn = DN(('cn', grouptype), DN(parent_dn))
|
||||
parent_dn = str(ndn)
|
||||
return parent_dn
|
||||
ndn = DN(('cn', grouptype), parent_dn)
|
||||
return ndn
|
||||
|
||||
def check_attr(self, attr):
|
||||
"""
|
||||
Verify that the user supplied key is a valid attribute in the schema
|
||||
"""
|
||||
ldap = self.api.Backend.ldap2
|
||||
if not ldap.schema:
|
||||
ldap.get_schema()
|
||||
obj = ldap.schema.get_obj(_ldap.schema.AttributeType, attr)
|
||||
if obj is not None:
|
||||
return obj
|
||||
@ -238,6 +235,7 @@ class automember_add(LDAPCreate):
|
||||
msg_summary = _('Added automember rule "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
entry_attrs['cn'] = keys[-1]
|
||||
if not automember_container_exists(self.api.Backend.ldap2):
|
||||
@ -284,6 +282,7 @@ class automember_add_condition(LDAPUpdate):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# Check to see if the automember rule exists
|
||||
try:
|
||||
(tdn, test_attrs) = ldap.get_entry(dn, [])
|
||||
@ -370,6 +369,7 @@ class automember_remove_condition(LDAPUpdate):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# Check to see if the automember rule exists
|
||||
try:
|
||||
(tdn, test_attrs) = ldap.get_entry(dn, [])
|
||||
@ -479,10 +479,10 @@ class automember_find(LDAPSearch):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, filters, attrs_list, base_dn, scope, *args, **options):
|
||||
assert isinstance(base_dn, DN)
|
||||
scope = ldap.SCOPE_SUBTREE
|
||||
ndn = DN(('cn', options['type']), DN(base_dn))
|
||||
base_dn = str(ndn)
|
||||
return (filters, base_dn, scope)
|
||||
ndn = DN(('cn', options['type']), base_dn)
|
||||
return (filters, ndn, scope)
|
||||
|
||||
api.register(automember_find)
|
||||
|
||||
@ -520,7 +520,6 @@ class automember_default_group_set(LDAPUpdate):
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
dn = DN(('cn', options['type']), api.env.container_automember)
|
||||
dn = str(dn)
|
||||
entry_attrs['automemberdefaultgroup'] = self.obj.dn_exists(options['type'], options['automemberdefaultgroup'])
|
||||
return dn
|
||||
|
||||
@ -542,7 +541,6 @@ class automember_default_group_remove(LDAPUpdate):
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
dn = DN(('cn', options['type']), api.env.container_automember)
|
||||
dn = str(dn)
|
||||
attr = 'automemberdefaultgroup'
|
||||
|
||||
(dn, entry_attrs_) = ldap.get_entry(
|
||||
@ -556,6 +554,7 @@ class automember_default_group_remove(LDAPUpdate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if 'automemberdefaultgroup' not in entry_attrs:
|
||||
entry_attrs['automemberdefaultgroup'] = unicode(_('No default (fallback) group set'))
|
||||
return dn
|
||||
@ -576,10 +575,10 @@ class automember_default_group_show(LDAPRetrieve):
|
||||
|
||||
def pre_callback(self, ldap, dn, attrs_list, *keys, **options):
|
||||
dn = DN(('cn', options['type']), api.env.container_automember)
|
||||
dn = str(dn)
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if 'automemberdefaultgroup' not in entry_attrs:
|
||||
entry_attrs['automemberdefaultgroup'] = unicode(_('No default (fallback) group set'))
|
||||
return dn
|
||||
|
@ -227,6 +227,7 @@ class automountlocation_add(LDAPCreate):
|
||||
msg_summary = _('Added automount location "%(value)s"')
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# create auto.master for the new location
|
||||
self.api.Command['automountmap_add'](keys[-1], u'auto.master')
|
||||
|
||||
@ -595,6 +596,7 @@ class automountmap_del(LDAPDelete):
|
||||
msg_summary = _('Deleted automount map "%(value)s"')
|
||||
|
||||
def post_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# delete optional parental connection (direct maps may not have this)
|
||||
try:
|
||||
(dn_, entry_attrs) = ldap.find_entry_by_attr(
|
||||
@ -718,7 +720,7 @@ class automountkey(LDAPObject):
|
||||
(kwargs['automountkey'], kwargs['automountinformation'])
|
||||
else:
|
||||
sfilter = '(automountkey=%s)' % kwargs['automountkey']
|
||||
basedn = 'automountmapname=%s,cn=%s,%s' % (parent_keys[1], parent_keys[0], self.container_dn)
|
||||
basedn = DN(('automountmapname', parent_keys[1]), ('cn', parent_keys[0]), self.container_dn)
|
||||
attrs_list = ['*']
|
||||
(entries, truncated) = ldap.find_entries(sfilter, attrs_list,
|
||||
basedn, _ldap.SCOPE_ONELEVEL)
|
||||
@ -790,6 +792,7 @@ class automountkey_add(LDAPCreate):
|
||||
internal_options = ['description', 'add_operation']
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
options.pop('add_operation', None)
|
||||
options.pop('description', None)
|
||||
self.obj.check_key_uniqueness(keys[-2], keys[-1], **options)
|
||||
@ -926,6 +929,7 @@ class automountkey_mod(LDAPUpdate):
|
||||
yield key
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if 'newautomountkey' in options:
|
||||
entry_attrs['automountkey'] = options['newautomountkey']
|
||||
if 'newautomountinformation' in options:
|
||||
|
@ -34,7 +34,7 @@ from ipalib.cli import to_cli, from_cli
|
||||
from ipalib import output
|
||||
from ipalib.text import _
|
||||
from ipalib.util import json_serialize, validate_hostname
|
||||
from ipalib.dn import *
|
||||
from ipapython.dn import DN, RDN
|
||||
|
||||
global_output_params = (
|
||||
Flag('has_password',
|
||||
@ -200,6 +200,7 @@ def validate_attribute(ugettext, name, attr):
|
||||
raise errors.ValidationError(name=name, error='Invalid format. Should be name=value')
|
||||
|
||||
def get_effective_rights(ldap, dn, attrs=None):
|
||||
assert isinstance(dn, DN)
|
||||
if attrs is None:
|
||||
attrs = ['*', 'nsaccountlock', 'cospriority']
|
||||
rights = ldap.get_effective_rights(dn, attrs)
|
||||
@ -332,6 +333,7 @@ def add_external_pre_callback(membertype, ldap, dn, keys, options):
|
||||
|
||||
membertype is the type of member
|
||||
"""
|
||||
assert isinstance(dn, DN)
|
||||
# validate hostname with allowed underscore characters, non-fqdn
|
||||
# hostnames are allowed
|
||||
def validate_host(hostname):
|
||||
@ -361,12 +363,14 @@ def add_external_post_callback(memberattr, membertype, externalattr, ldap, compl
|
||||
membertype is the type of member: user,
|
||||
externalattr is one of externaluser,
|
||||
"""
|
||||
assert isinstance(dn, DN)
|
||||
completed_external = 0
|
||||
normalize = options.get('external_callback_normalize', True)
|
||||
# Sift through the failures. We assume that these are all
|
||||
# entries that aren't stored in IPA, aka external entries.
|
||||
if memberattr in failed and membertype in failed[memberattr]:
|
||||
(dn, entry_attrs_) = ldap.get_entry(dn, [externalattr])
|
||||
assert isinstance(dn, DN)
|
||||
members = entry_attrs.get(memberattr, [])
|
||||
external_entries = entry_attrs_.get(externalattr, [])
|
||||
lc_external_entries = set(e.lower() for e in external_entries)
|
||||
@ -374,6 +378,7 @@ def add_external_post_callback(memberattr, membertype, externalattr, ldap, compl
|
||||
for entry in failed[memberattr][membertype]:
|
||||
membername = entry[0].lower()
|
||||
member_dn = api.Object[membertype].get_dn(membername)
|
||||
assert isinstance(member_dn, DN)
|
||||
if (membername not in lc_external_entries and
|
||||
member_dn not in members):
|
||||
# Not an IPA entry, assume external
|
||||
@ -406,6 +411,7 @@ def add_external_post_callback(memberattr, membertype, externalattr, ldap, compl
|
||||
return (completed + completed_external, dn)
|
||||
|
||||
def remove_external_post_callback(memberattr, membertype, externalattr, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# Run through the failures and gracefully remove any member defined
|
||||
# as an external member.
|
||||
if memberattr in failed and membertype in failed[memberattr]:
|
||||
@ -440,7 +446,7 @@ def host_is_master(ldap, fqdn):
|
||||
|
||||
Raises an exception if a master, otherwise returns nothing.
|
||||
"""
|
||||
master_dn = str(DN('cn=%s' % fqdn, 'cn=masters,cn=ipa,cn=etc', api.env.basedn))
|
||||
master_dn = DN(('cn', fqdn), ('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
|
||||
try:
|
||||
(dn, entry_attrs) = ldap.get_entry(master_dn, ['objectclass'])
|
||||
raise errors.ValidationError(name='hostname', error=_('An IPA master host cannot be deleted or disabled'))
|
||||
@ -518,9 +524,11 @@ class LDAPObject(Object):
|
||||
return self.backend.make_dn_from_attr(
|
||||
self.primary_key.name, keys[-1], parent_dn
|
||||
)
|
||||
assert isinstance(parent_dn, DN)
|
||||
return parent_dn
|
||||
|
||||
def get_primary_key_from_dn(self, dn):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
if self.rdn_attribute:
|
||||
(dn, entry_attrs) = self.backend.get_entry(
|
||||
@ -532,8 +540,6 @@ class LDAPObject(Object):
|
||||
return ''
|
||||
except errors.NotFound:
|
||||
pass
|
||||
# DN object assures we're returning a decoded (unescaped) value
|
||||
dn = DN(dn)
|
||||
try:
|
||||
return dn[self.primary_key.name]
|
||||
except KeyError:
|
||||
@ -567,7 +573,7 @@ class LDAPObject(Object):
|
||||
for member in entry_attrs.setdefault(attr, []):
|
||||
for ldap_obj_name in self.attribute_members[attr]:
|
||||
ldap_obj = self.api.Object[ldap_obj_name]
|
||||
if member.find(ldap_obj.container_dn) > 0:
|
||||
if ldap_obj.container_dn in member:
|
||||
new_attr = '%s_%s' % (attr, ldap_obj.name)
|
||||
entry_attrs.setdefault(new_attr, []).append(
|
||||
ldap_obj.get_primary_key_from_dn(member)
|
||||
@ -623,7 +629,6 @@ class LDAPObject(Object):
|
||||
|
||||
def __json__(self):
|
||||
ldap = self.backend
|
||||
ldap.get_schema()
|
||||
json_dict = dict(
|
||||
(a, getattr(self, a)) for a in self.json_friendly_attributes
|
||||
)
|
||||
@ -777,52 +782,47 @@ last, after all sets and adds."""),
|
||||
|
||||
_callback_registry = dict(pre={}, post={}, exc={}, interactive_prompt={})
|
||||
|
||||
def _convert_2_dict(self, attrs):
|
||||
def _convert_2_dict(self, ldap, attrs):
|
||||
"""
|
||||
Convert a string in the form of name/value pairs into a dictionary.
|
||||
|
||||
:param attrs: A list of name/value pair strings, in the "name=value"
|
||||
format. May also be a single string, or None.
|
||||
"""
|
||||
if attrs is None:
|
||||
return {}
|
||||
|
||||
if not isinstance(attrs, (tuple, list)):
|
||||
attrs = [attrs]
|
||||
|
||||
newdict = {}
|
||||
if attrs is None:
|
||||
attrs = []
|
||||
elif not type(attrs) in (list, tuple):
|
||||
attrs = [attrs]
|
||||
for a in attrs:
|
||||
m = re.match("^\s*(?P<attr>.*?)\s*=\s*(?P<value>.*?)\s*$", a)
|
||||
attr = str(m.group('attr').lower())
|
||||
value = m.group('value')
|
||||
|
||||
m = re.match("\s*(.*?)\s*=\s*(.*?)\s*$", a)
|
||||
attr = str(m.group(1)).lower()
|
||||
value = m.group(2)
|
||||
if attr in self.obj.params and attr not in self.params:
|
||||
# The attribute is managed by IPA, but it didn't get cloned
|
||||
# to the command. This happens with no_update/no_create attrs.
|
||||
raise errors.ValidationError(
|
||||
name=attr, error=_('attribute is not configurable'))
|
||||
if len(value) == 0:
|
||||
# None means "delete this attribute"
|
||||
value = None
|
||||
|
||||
newdict.setdefault(attr, []).append(value)
|
||||
if ldap.has_dn_syntax(attr):
|
||||
value = DN(value)
|
||||
|
||||
if attr in newdict:
|
||||
if type(value) in (tuple,):
|
||||
newdict[attr] += list(value)
|
||||
else:
|
||||
newdict[attr].append(value)
|
||||
else:
|
||||
if type(value) in (tuple,):
|
||||
newdict[attr] = list(value)
|
||||
else:
|
||||
newdict[attr] = [value]
|
||||
return newdict
|
||||
|
||||
def _convert_entry(self, entry_attrs):
|
||||
result = {}
|
||||
for attr, val in entry_attrs.iteritems():
|
||||
if val is None:
|
||||
val = []
|
||||
elif not isinstance(val, (tuple, list)):
|
||||
val = [val]
|
||||
|
||||
result[attr] = []
|
||||
for v in val:
|
||||
if isinstance(v, str):
|
||||
# This is a Binary value, base64 encode it
|
||||
v = base64.b64encode(v)
|
||||
result[attr].append(unicode(v))
|
||||
|
||||
return result
|
||||
|
||||
def process_attr_options(self, entry_attrs, dn, keys, options):
|
||||
"""
|
||||
Process all --setattr, --addattr, and --delattr options and add the
|
||||
@ -847,14 +847,15 @@ last, after all sets and adds."""),
|
||||
:param keys: List of command arguments
|
||||
:param options: List of options
|
||||
"""
|
||||
|
||||
if all(k not in options for k in ("setattr", "addattr", "delattr")):
|
||||
return
|
||||
|
||||
ldap = self.obj.backend
|
||||
|
||||
adddict = self._convert_2_dict(options.get('addattr', []))
|
||||
setdict = self._convert_2_dict(options.get('setattr', []))
|
||||
deldict = self._convert_2_dict(options.get('delattr', []))
|
||||
adddict = self._convert_2_dict(ldap, options.get('addattr', []))
|
||||
setdict = self._convert_2_dict(ldap, options.get('setattr', []))
|
||||
deldict = self._convert_2_dict(ldap, options.get('delattr', []))
|
||||
|
||||
setattrs = set(setdict.keys())
|
||||
addattrs = set(adddict.keys())
|
||||
@ -865,24 +866,24 @@ last, after all sets and adds."""),
|
||||
direct_del = delattrs
|
||||
needldapattrs = []
|
||||
else:
|
||||
assert isinstance(dn, DN)
|
||||
direct_add = setattrs & addattrs
|
||||
direct_del = setattrs & delattrs
|
||||
needldapattrs = list((addattrs | delattrs) - setattrs)
|
||||
|
||||
mod_attrs = self._convert_entry(entry_attrs)
|
||||
|
||||
for attr, val in setdict.iteritems():
|
||||
mod_attrs[attr] = val
|
||||
entry_attrs[attr] = val
|
||||
|
||||
for attr in direct_add:
|
||||
mod_attrs.setdefault(attr, []).extend(adddict[attr])
|
||||
entry_attrs.setdefault(attr, []).extend(adddict[attr])
|
||||
|
||||
for attr in direct_del:
|
||||
for delval in deldict[attr]:
|
||||
try:
|
||||
mod_attrs[attr].remove(delval)
|
||||
entry_attrs[attr].remove(delval)
|
||||
except ValueError:
|
||||
raise errors.AttrValueNotFound(attr=attr, value=delval)
|
||||
raise errors.AttrValueNotFound(attr=attr,
|
||||
value=delval)
|
||||
|
||||
if needldapattrs:
|
||||
try:
|
||||
@ -901,27 +902,28 @@ last, after all sets and adds."""),
|
||||
raise errors.ValidationError(name=del_nonexisting.pop(),
|
||||
error=_('No such attribute on this entry'))
|
||||
|
||||
old_entry = self._convert_entry(old_entry)
|
||||
|
||||
for attr in needldapattrs:
|
||||
mod_attrs[attr] = old_entry.get(attr, [])
|
||||
entry_attrs[attr] = old_entry.get(attr, [])
|
||||
|
||||
if attr in addattrs:
|
||||
mod_attrs[attr].extend(adddict.get(attr, []))
|
||||
entry_attrs[attr].extend(adddict.get(attr, []))
|
||||
|
||||
for delval in deldict.get(attr, []):
|
||||
try:
|
||||
mod_attrs[attr].remove(delval)
|
||||
entry_attrs[attr].remove(delval)
|
||||
except ValueError:
|
||||
if isinstance(delval, str):
|
||||
# This is a Binary value, base64 encode it
|
||||
delval = unicode(base64.b64encode(delval))
|
||||
raise errors.AttrValueNotFound(attr=attr, value=delval)
|
||||
|
||||
# normalize all values
|
||||
changedattrs = setattrs | addattrs | delattrs
|
||||
for attr in changedattrs:
|
||||
value = mod_attrs[attr]
|
||||
if attr in self.params and self.params[attr].attribute:
|
||||
param = self.params[attr]
|
||||
# convert single-value params to scalars
|
||||
param = self.params[attr]
|
||||
value = entry_attrs[attr]
|
||||
if not param.multivalue:
|
||||
if len(value) == 1:
|
||||
value = value[0]
|
||||
@ -931,19 +933,19 @@ last, after all sets and adds."""),
|
||||
raise errors.OnlyOneValueAllowed(attr=attr)
|
||||
# validate, convert and encode params
|
||||
try:
|
||||
value = param(value)
|
||||
value = param(value)
|
||||
except errors.ValidationError, err:
|
||||
raise errors.ValidationError(name=attr, error=err.error)
|
||||
except errors.ConversionError, err:
|
||||
raise errors.ConversionError(name=attr, error=err.error)
|
||||
entry_attrs[attr] = value
|
||||
else:
|
||||
# unknown attribute: remove duplicite and invalid values
|
||||
value = list(set([val for val in value if val]))
|
||||
if not value:
|
||||
value = None
|
||||
elif isinstance(value, (tuple, list)) and len(value) == 1:
|
||||
value = value[0]
|
||||
entry_attrs[attr] = value
|
||||
entry_attrs[attr] = list(set([val for val in entry_attrs[attr] if val]))
|
||||
if not entry_attrs[attr]:
|
||||
entry_attrs[attr] = None
|
||||
elif isinstance(entry_attrs[attr], (tuple, list)) and len(entry_attrs[attr]) == 1:
|
||||
entry_attrs[attr] = entry_attrs[attr][0]
|
||||
|
||||
@classmethod
|
||||
def register_pre_callback(cls, callback, first=False):
|
||||
@ -1021,8 +1023,13 @@ class LDAPCreate(BaseLDAPCommand, crud.Create):
|
||||
entry_attrs[self.obj.uuid_attribute] = 'autogenerate'
|
||||
|
||||
dn = self.obj.get_dn(*keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
if self.obj.rdn_attribute:
|
||||
if not dn.startswith('%s=' % self.obj.primary_key.name):
|
||||
try:
|
||||
dn_attr = dn[0].attr
|
||||
except (IndexError, KeyError):
|
||||
dn_attr = None
|
||||
if dn_attr != self.obj.primary_key.name:
|
||||
self.obj.handle_duplicate_entry(*keys)
|
||||
dn = ldap.make_dn(
|
||||
entry_attrs, self.obj.rdn_attribute, self.obj.container_dn
|
||||
@ -1038,9 +1045,9 @@ class LDAPCreate(BaseLDAPCommand, crud.Create):
|
||||
for callback in self.get_callbacks('pre'):
|
||||
dn = callback(
|
||||
self, ldap, dn, entry_attrs, attrs_list, *keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
_check_single_value_attrs(self.params, entry_attrs)
|
||||
ldap.get_schema()
|
||||
_check_limit_object_class(self.api.Backend.ldap2.schema.attribute_types(self.obj.limit_object_classes), entry_attrs.keys(), allow_only=True)
|
||||
_check_limit_object_class(self.api.Backend.ldap2.schema.attribute_types(self.obj.disallow_object_classes), entry_attrs.keys(), allow_only=False)
|
||||
|
||||
@ -1074,16 +1081,19 @@ class LDAPCreate(BaseLDAPCommand, crud.Create):
|
||||
self.obj.primary_key.name, keys[-1], object_class, attrs_list,
|
||||
self.obj.container_dn
|
||||
)
|
||||
assert isinstance(dn, DN)
|
||||
else:
|
||||
(dn, entry_attrs) = self._exc_wrapper(keys, options, ldap.get_entry)(
|
||||
dn, attrs_list, normalize=self.obj.normalize_dn
|
||||
)
|
||||
assert isinstance(dn, DN)
|
||||
except errors.NotFound:
|
||||
self.obj.handle_not_found(*keys)
|
||||
|
||||
for callback in self.get_callbacks('post'):
|
||||
dn = callback(self, ldap, dn, entry_attrs, *keys, **options)
|
||||
|
||||
assert isinstance(dn, DN)
|
||||
entry_attrs['dn'] = dn
|
||||
|
||||
self.obj.convert_attribute_members(entry_attrs, *keys, **options)
|
||||
@ -1092,9 +1102,11 @@ class LDAPCreate(BaseLDAPCommand, crud.Create):
|
||||
return dict(result=entry_attrs, value=u'')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return dn
|
||||
|
||||
def exc_callback(self, keys, options, exc, call_func, *call_args, **call_kwargs):
|
||||
@ -1181,6 +1193,7 @@ class LDAPRetrieve(LDAPQuery):
|
||||
ldap = self.obj.backend
|
||||
|
||||
dn = self.obj.get_dn(*keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
if options.get('all', False):
|
||||
attrs_list = ['*'] + self.obj.default_attributes
|
||||
@ -1189,11 +1202,13 @@ class LDAPRetrieve(LDAPQuery):
|
||||
|
||||
for callback in self.get_callbacks('pre'):
|
||||
dn = callback(self, ldap, dn, attrs_list, *keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
try:
|
||||
(dn, entry_attrs) = self._exc_wrapper(keys, options, ldap.get_entry)(
|
||||
dn, attrs_list, normalize=self.obj.normalize_dn
|
||||
)
|
||||
assert isinstance(dn, DN)
|
||||
except errors.NotFound:
|
||||
self.obj.handle_not_found(*keys)
|
||||
|
||||
@ -1202,17 +1217,21 @@ class LDAPRetrieve(LDAPQuery):
|
||||
|
||||
for callback in self.get_callbacks('post'):
|
||||
dn = callback(self, ldap, dn, entry_attrs, *keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
self.obj.convert_attribute_members(entry_attrs, *keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
entry_attrs['dn'] = dn
|
||||
if self.obj.primary_key and keys[-1] is not None:
|
||||
return dict(result=entry_attrs, value=keys[-1])
|
||||
return dict(result=entry_attrs, value=u'')
|
||||
|
||||
def pre_callback(self, ldap, dn, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return dn
|
||||
|
||||
def exc_callback(self, keys, options, exc, call_func, *call_args, **call_kwargs):
|
||||
@ -1261,6 +1280,7 @@ class LDAPUpdate(LDAPQuery, crud.Update):
|
||||
raise errors.EmptyModlist()
|
||||
|
||||
dn = self.obj.get_dn(*keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
entry_attrs = self.args_options_2_entry(**options)
|
||||
|
||||
@ -1279,8 +1299,8 @@ class LDAPUpdate(LDAPQuery, crud.Update):
|
||||
for callback in self.get_callbacks('pre'):
|
||||
dn = callback(
|
||||
self, ldap, dn, entry_attrs, attrs_list, *keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
ldap.get_schema()
|
||||
_check_limit_object_class(self.api.Backend.ldap2.schema.attribute_types(self.obj.limit_object_classes), entry_attrs.keys(), allow_only=True)
|
||||
_check_limit_object_class(self.api.Backend.ldap2.schema.attribute_types(self.obj.disallow_object_classes), entry_attrs.keys(), allow_only=False)
|
||||
|
||||
@ -1294,10 +1314,10 @@ class LDAPUpdate(LDAPQuery, crud.Update):
|
||||
if self.obj.rdn_is_primary_key and self.obj.primary_key.name in entry_attrs:
|
||||
# RDN change
|
||||
self._exc_wrapper(keys, options, ldap.update_entry_rdn)(dn,
|
||||
unicode('%s=%s' % (self.obj.primary_key.name,
|
||||
entry_attrs[self.obj.primary_key.name])))
|
||||
RDN((self.obj.primary_key.name, entry_attrs[self.obj.primary_key.name])))
|
||||
rdnkeys = keys[:-1] + (entry_attrs[self.obj.primary_key.name], )
|
||||
dn = self.obj.get_dn(*rdnkeys)
|
||||
assert isinstance(dn, DN)
|
||||
del entry_attrs[self.obj.primary_key.name]
|
||||
options['rdnupdate'] = True
|
||||
rdnupdate = True
|
||||
@ -1306,6 +1326,7 @@ class LDAPUpdate(LDAPQuery, crud.Update):
|
||||
# to decide what to do. An EmptyModlist in this context doesn't
|
||||
# mean an error occurred, just that there were no other updates to
|
||||
# perform.
|
||||
assert isinstance(dn, DN)
|
||||
self._exc_wrapper(keys, options, ldap.update_entry)(dn, entry_attrs, normalize=self.obj.normalize_dn)
|
||||
except errors.EmptyModlist, e:
|
||||
if not rdnupdate:
|
||||
@ -1327,6 +1348,7 @@ class LDAPUpdate(LDAPQuery, crud.Update):
|
||||
|
||||
for callback in self.get_callbacks('post'):
|
||||
dn = callback(self, ldap, dn, entry_attrs, *keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
self.obj.convert_attribute_members(entry_attrs, *keys, **options)
|
||||
if self.obj.primary_key and keys[-1] is not None:
|
||||
@ -1334,9 +1356,11 @@ class LDAPUpdate(LDAPQuery, crud.Update):
|
||||
return dict(result=entry_attrs, value=u'')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return dn
|
||||
|
||||
def exc_callback(self, keys, options, exc, call_func, *call_args, **call_kwargs):
|
||||
@ -1360,11 +1384,14 @@ class LDAPDelete(LDAPMultiQuery):
|
||||
def delete_entry(pkey):
|
||||
nkeys = keys[:-1] + (pkey, )
|
||||
dn = self.obj.get_dn(*nkeys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
for callback in self.get_callbacks('pre'):
|
||||
dn = callback(self, ldap, dn, *nkeys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
def delete_subtree(base_dn):
|
||||
assert isinstance(base_dn, DN)
|
||||
truncated = True
|
||||
while truncated:
|
||||
try:
|
||||
@ -1412,9 +1439,11 @@ class LDAPDelete(LDAPMultiQuery):
|
||||
return dict(result=dict(failed=u''), value=u'')
|
||||
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return True
|
||||
|
||||
def exc_callback(self, keys, options, exc, call_func, *call_args, **call_kwargs):
|
||||
@ -1495,14 +1524,17 @@ class LDAPAddMember(LDAPModMember):
|
||||
(member_dns, failed) = self.get_member_dns(**options)
|
||||
|
||||
dn = self.obj.get_dn(*keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
for callback in self.get_callbacks('pre'):
|
||||
dn = callback(self, ldap, dn, member_dns, failed, *keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
completed = 0
|
||||
for (attr, objs) in member_dns.iteritems():
|
||||
for ldap_obj_name in objs:
|
||||
for m_dn in member_dns[attr][ldap_obj_name]:
|
||||
assert isinstance(m_dn, DN)
|
||||
if not m_dn:
|
||||
continue
|
||||
try:
|
||||
@ -1534,7 +1566,9 @@ class LDAPAddMember(LDAPModMember):
|
||||
(completed, dn) = callback(
|
||||
self, ldap, completed, failed, dn, entry_attrs, *keys,
|
||||
**options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
assert isinstance(dn, DN)
|
||||
entry_attrs['dn'] = dn
|
||||
self.obj.convert_attribute_members(entry_attrs, *keys, **options)
|
||||
return dict(
|
||||
@ -1544,9 +1578,11 @@ class LDAPAddMember(LDAPModMember):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return (completed, dn)
|
||||
|
||||
def exc_callback(self, keys, options, exc, call_func, *call_args, **call_kwargs):
|
||||
@ -1583,14 +1619,17 @@ class LDAPRemoveMember(LDAPModMember):
|
||||
(member_dns, failed) = self.get_member_dns(**options)
|
||||
|
||||
dn = self.obj.get_dn(*keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
for callback in self.get_callbacks('pre'):
|
||||
dn = callback(self, ldap, dn, member_dns, failed, *keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
completed = 0
|
||||
for (attr, objs) in member_dns.iteritems():
|
||||
for ldap_obj_name, m_dns in objs.iteritems():
|
||||
for m_dn in m_dns:
|
||||
assert isinstance(m_dn, DN)
|
||||
if not m_dn:
|
||||
continue
|
||||
try:
|
||||
@ -1625,7 +1664,9 @@ class LDAPRemoveMember(LDAPModMember):
|
||||
(completed, dn) = callback(
|
||||
self, ldap, completed, failed, dn, entry_attrs, *keys,
|
||||
**options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
assert isinstance(dn, DN)
|
||||
entry_attrs['dn'] = dn
|
||||
|
||||
self.obj.convert_attribute_members(entry_attrs, *keys, **options)
|
||||
@ -1636,9 +1677,11 @@ class LDAPRemoveMember(LDAPModMember):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return (completed, dn)
|
||||
|
||||
def exc_callback(self, keys, options, exc, call_func, *call_args, **call_kwargs):
|
||||
@ -1765,6 +1808,7 @@ class LDAPSearch(BaseLDAPCommand, crud.Search):
|
||||
base_dn = self.api.Object[self.obj.parent_object].get_dn(*args[:-1])
|
||||
else:
|
||||
base_dn = self.obj.container_dn
|
||||
assert isinstance(base_dn, DN)
|
||||
|
||||
search_kw = self.args_options_2_entry(**options)
|
||||
|
||||
@ -1812,6 +1856,7 @@ class LDAPSearch(BaseLDAPCommand, crud.Search):
|
||||
for callback in self.get_callbacks('pre'):
|
||||
(filter, base_dn, scope) = callback(
|
||||
self, ldap, filter, attrs_list, base_dn, scope, *args, **options)
|
||||
assert isinstance(base_dn, DN)
|
||||
|
||||
try:
|
||||
(entries, truncated) = self._exc_wrapper(args, options, ldap.find_entries)(
|
||||
@ -1827,14 +1872,16 @@ class LDAPSearch(BaseLDAPCommand, crud.Search):
|
||||
|
||||
if self.sort_result_entries:
|
||||
if self.obj.primary_key:
|
||||
sortfn=lambda x,y: cmp(x[1][self.obj.primary_key.name][0].lower(), y[1][self.obj.primary_key.name][0].lower())
|
||||
entries.sort(sortfn)
|
||||
def sort_key(x):
|
||||
return x[1][self.obj.primary_key.name][0].lower()
|
||||
entries.sort(key=sort_key)
|
||||
|
||||
if not options.get('raw', False):
|
||||
for e in entries:
|
||||
self.obj.convert_attribute_members(e[1], *args, **options)
|
||||
|
||||
for e in entries:
|
||||
assert isinstance(e[0], DN)
|
||||
e[1]['dn'] = e[0]
|
||||
entries = [e for (dn, e) in entries]
|
||||
|
||||
@ -1845,6 +1892,7 @@ class LDAPSearch(BaseLDAPCommand, crud.Search):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, filters, attrs_list, base_dn, scope, *args, **options):
|
||||
assert isinstance(base_dn, DN)
|
||||
return (filters, base_dn, scope)
|
||||
|
||||
def post_callback(self, ldap, entries, truncated, *args, **options):
|
||||
@ -1926,9 +1974,11 @@ class LDAPAddReverseMember(LDAPModReverseMember):
|
||||
# Ensure our target exists
|
||||
result = self.api.Command[self.show_command](keys[-1])['result']
|
||||
dn = result['dn']
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
for callback in self.get_callbacks('pre'):
|
||||
dn = callback(self, ldap, dn, *keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
if options.get('all', False):
|
||||
attrs_list = ['*'] + self.obj.default_attributes
|
||||
@ -1967,7 +2017,9 @@ class LDAPAddReverseMember(LDAPModReverseMember):
|
||||
(completed, dn) = callback(
|
||||
self, ldap, completed, failed, dn, entry_attrs, *keys,
|
||||
**options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
assert isinstance(dn, DN)
|
||||
entry_attrs['dn'] = dn
|
||||
return dict(
|
||||
completed=completed,
|
||||
@ -1976,9 +2028,11 @@ class LDAPAddReverseMember(LDAPModReverseMember):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return (completed, dn)
|
||||
|
||||
def exc_callback(self, keys, options, exc, call_func, *call_args, **call_kwargs):
|
||||
@ -2022,9 +2076,11 @@ class LDAPRemoveReverseMember(LDAPModReverseMember):
|
||||
# Ensure our target exists
|
||||
result = self.api.Command[self.show_command](keys[-1])['result']
|
||||
dn = result['dn']
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
for callback in self.get_callbacks('pre'):
|
||||
dn = callback(self, ldap, dn, *keys, **options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
if options.get('all', False):
|
||||
attrs_list = ['*'] + self.obj.default_attributes
|
||||
@ -2063,7 +2119,9 @@ class LDAPRemoveReverseMember(LDAPModReverseMember):
|
||||
(completed, dn) = callback(
|
||||
self, ldap, completed, failed, dn, entry_attrs, *keys,
|
||||
**options)
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
assert isinstance(dn, DN)
|
||||
entry_attrs['dn'] = dn
|
||||
return dict(
|
||||
completed=completed,
|
||||
@ -2072,9 +2130,11 @@ class LDAPRemoveReverseMember(LDAPModReverseMember):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return (completed, dn)
|
||||
|
||||
def exc_callback(self, keys, options, exc, call_func, *call_args, **call_kwargs):
|
||||
|
@ -19,7 +19,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from ipalib import api
|
||||
from ipalib import Bool, Int, Str, IA5Str, StrEnum
|
||||
from ipalib import Bool, Int, Str, IA5Str, StrEnum, DNParam
|
||||
from ipalib.plugins.baseldap import *
|
||||
from ipalib import _
|
||||
from ipalib.errors import ValidationError
|
||||
@ -149,7 +149,7 @@ class config(LDAPObject):
|
||||
label=_('Enable migration mode'),
|
||||
doc=_('Enable migration mode'),
|
||||
),
|
||||
Str('ipacertificatesubjectbase',
|
||||
DNParam('ipacertificatesubjectbase',
|
||||
cli_name='subject',
|
||||
label=_('Certificate Subject base'),
|
||||
doc=_('Base for certificate subjects (OU=Test,O=Example)'),
|
||||
@ -199,7 +199,7 @@ class config(LDAPObject):
|
||||
)
|
||||
|
||||
def get_dn(self, *keys, **kwargs):
|
||||
return 'cn=ipaconfig,cn=etc'
|
||||
return DN(('cn', 'ipaconfig'), ('cn', 'etc'))
|
||||
|
||||
api.register(config)
|
||||
|
||||
@ -208,6 +208,7 @@ class config_mod(LDAPUpdate):
|
||||
__doc__ = _('Modify configuration options.')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if 'ipadefaultprimarygroup' in entry_attrs:
|
||||
group=entry_attrs['ipadefaultprimarygroup']
|
||||
try:
|
||||
|
@ -35,7 +35,6 @@ from ipalib.util import (validate_zonemgr, normalize_zonemgr,
|
||||
validate_hostname, validate_dns_label, validate_domain_name,
|
||||
get_dns_forward_zone_update_policy, get_dns_reverse_zone_update_policy)
|
||||
from ipapython.ipautil import valid_ip, CheckedIPAddress, is_host_resolvable
|
||||
from ldap import explode_dn
|
||||
|
||||
__doc__ = _("""
|
||||
Domain Name System (DNS)
|
||||
@ -802,10 +801,10 @@ class DNSRecord(Str):
|
||||
|
||||
# callbacks for per-type special record behavior
|
||||
def dnsrecord_add_pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
pass
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
def dnsrecord_add_post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
pass
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
class ForwardRecord(DNSRecord):
|
||||
extra = (
|
||||
@ -817,6 +816,7 @@ class ForwardRecord(DNSRecord):
|
||||
)
|
||||
|
||||
def dnsrecord_add_pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
reverse_option = self._convert_dnsrecord_extra(self.extra[0])
|
||||
if options.get(reverse_option.name):
|
||||
records = entry_attrs.get(self.name, [])
|
||||
@ -832,6 +832,7 @@ class ForwardRecord(DNSRecord):
|
||||
setattr(context, '%s_reverse' % self.name, entry_attrs.get(self.name))
|
||||
|
||||
def dnsrecord_add_post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
rev_records = getattr(context, '%s_reverse' % self.name, [])
|
||||
|
||||
if rev_records:
|
||||
@ -1727,6 +1728,7 @@ class dnszone_add(LDAPCreate):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if not dns_container_exists(self.api.Backend.ldap2):
|
||||
raise errors.NotFound(reason=_('DNS is not configured'))
|
||||
|
||||
@ -1751,6 +1753,7 @@ class dnszone_add(LDAPCreate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if 'ip_address' in options:
|
||||
nameserver = entry_attrs['idnssoamname'][0][:-1] # ends with a dot
|
||||
nsparts = nameserver.split('.')
|
||||
@ -1813,6 +1816,7 @@ class dnszone_find(LDAPSearch):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *args, **options):
|
||||
assert isinstance(base_dn, DN)
|
||||
if options.get('forward_only', False):
|
||||
search_kw = {}
|
||||
search_kw['idnsname'] = _valid_reverse_zones.keys()
|
||||
@ -1980,6 +1984,7 @@ class dnsrecord(LDAPObject):
|
||||
)
|
||||
|
||||
def _nsrecord_pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
nsrecords = entry_attrs.get('nsrecord')
|
||||
if options.get('force', False) or nsrecords is None:
|
||||
return
|
||||
@ -1987,6 +1992,7 @@ class dnsrecord(LDAPObject):
|
||||
check_ns_rec_resolvable(keys[0], nsrecord)
|
||||
|
||||
def _ptrrecord_pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
ptrrecords = entry_attrs.get('ptrrecord')
|
||||
if ptrrecords is None:
|
||||
return
|
||||
@ -2015,6 +2021,7 @@ class dnsrecord(LDAPObject):
|
||||
% dict(name=zone_name, count=zone_len, user_count=ip_addr_comp_count)))
|
||||
|
||||
def run_precallback_validators(self, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
ldap = self.api.Backend.ldap2
|
||||
|
||||
for rtype in entry_attrs:
|
||||
@ -2049,7 +2056,7 @@ class dnsrecord(LDAPObject):
|
||||
|
||||
def get_dns_masters(self):
|
||||
ldap = self.api.Backend.ldap2
|
||||
base_dn = 'cn=masters,cn=ipa,cn=etc,%s' % self.api.env.basedn
|
||||
base_dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), self.api.env.basedn)
|
||||
ldap_filter = '(&(objectClass=ipaConfigObject)(cn=DNS))'
|
||||
dns_masters = []
|
||||
|
||||
@ -2058,9 +2065,12 @@ class dnsrecord(LDAPObject):
|
||||
|
||||
for entry in entries:
|
||||
master_dn = entry[0]
|
||||
if master_dn.startswith('cn='):
|
||||
master = explode_dn(master_dn)[1].replace('cn=','')
|
||||
assert isinstance(master_dn, DN)
|
||||
try:
|
||||
master = master_dn[1]['cn']
|
||||
dns_masters.append(master)
|
||||
except (IndexError, KeyError):
|
||||
pass
|
||||
except errors.NotFound:
|
||||
return []
|
||||
|
||||
@ -2254,6 +2264,7 @@ class dnsrecord_add(LDAPCreate):
|
||||
kw.update(user_options)
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
precallback_attrs = []
|
||||
processed_attrs = []
|
||||
for option in options:
|
||||
@ -2354,6 +2365,7 @@ class dnsrecord_add(LDAPCreate):
|
||||
raise exc
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
for attr in getattr(context, 'dnsrecord_precallback_attrs', []):
|
||||
param = self.params[attr]
|
||||
param.dnsrecord_add_post_callback(ldap, dn, entry_attrs, *keys, **options)
|
||||
@ -2382,6 +2394,7 @@ class dnsrecord_mod(LDAPUpdate):
|
||||
return super(dnsrecord_mod, self).args_options_2_entry(*keys, **options)
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if options.get('rename') and self.obj.is_pkey_zone_record(*keys):
|
||||
# zone rename is not allowed
|
||||
raise errors.ValidationError(name='rename',
|
||||
@ -2466,10 +2479,12 @@ class dnsrecord_mod(LDAPUpdate):
|
||||
return result
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if self.obj.is_pkey_zone_record(*keys):
|
||||
entry_attrs[self.obj.primary_key.name] = [_dns_zone_record]
|
||||
|
||||
self.obj.postprocess_record(entry_attrs, **options)
|
||||
return dn
|
||||
|
||||
def interactive_prompt_callback(self, kw):
|
||||
try:
|
||||
@ -2564,6 +2579,7 @@ class dnsrecord_del(LDAPUpdate):
|
||||
yield option
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(dn_, old_entry) = ldap.get_entry(
|
||||
dn, _record_attributes,
|
||||
@ -2626,9 +2642,11 @@ class dnsrecord_del(LDAPUpdate):
|
||||
return result
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if self.obj.is_pkey_zone_record(*keys):
|
||||
entry_attrs[self.obj.primary_key.name] = [_dns_zone_record]
|
||||
self.obj.postprocess_record(entry_attrs, **options)
|
||||
return dn
|
||||
|
||||
def args_options_2_entry(self, *keys, **options):
|
||||
self.obj.has_cli_options(options, self.no_option_msg)
|
||||
@ -2697,6 +2715,7 @@ class dnsrecord_show(LDAPRetrieve):
|
||||
)
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if self.obj.is_pkey_zone_record(*keys):
|
||||
entry_attrs[self.obj.primary_key.name] = [_dns_zone_record]
|
||||
self.obj.postprocess_record(entry_attrs, **options)
|
||||
@ -2723,6 +2742,7 @@ class dnsrecord_find(LDAPSearch):
|
||||
yield option
|
||||
|
||||
def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *args, **options):
|
||||
assert isinstance(base_dn, DN)
|
||||
# include zone record (root entry) in the search
|
||||
return (filter, base_dn, ldap.SCOPE_SUBTREE)
|
||||
|
||||
@ -2774,7 +2794,7 @@ class dns_is_enabled(Command):
|
||||
NO_CLI = True
|
||||
has_output = output.standard_value
|
||||
|
||||
base_dn = 'cn=masters,cn=ipa,cn=etc,%s' % api.env.basedn
|
||||
base_dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
|
||||
filter = '(&(objectClass=ipaConfigObject)(cn=DNS))'
|
||||
|
||||
def execute(self, *args, **options):
|
||||
|
@ -318,6 +318,7 @@ class entitle_consume(LDAPUpdate):
|
||||
return result
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
quantity = keys[-1]
|
||||
|
||||
os.environ['LANG'] = 'en_US'
|
||||
@ -361,6 +362,7 @@ class entitle_consume(LDAPUpdate):
|
||||
Returning the certificates isn't very interesting. Return the
|
||||
status of entitlements instead.
|
||||
"""
|
||||
assert isinstance(dn, DN)
|
||||
if 'usercertificate' in entry_attrs:
|
||||
del entry_attrs['usercertificate']
|
||||
if 'userpkcs12' in entry_attrs:
|
||||
@ -504,7 +506,7 @@ class entitle_register(LDAPCreate):
|
||||
"""
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
dn = '%s,%s' % (self.obj.container_dn, self.api.env.basedn)
|
||||
dn = DN(self.obj.container_dn, self.api.env.basedn)
|
||||
if not ldap.can_add(dn):
|
||||
raise errors.ACIError(info='No permission to register')
|
||||
os.environ['LANG'] = 'en_US'
|
||||
@ -604,6 +606,7 @@ class entitle_import(LDAPUpdate):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(db, uuid, certfile, keyfile) = get_uuid(ldap)
|
||||
if db is not None:
|
||||
@ -622,7 +625,7 @@ class entitle_import(LDAPUpdate):
|
||||
raise errors.CertificateFormatError(error=_('Not an entitlement certificate'))
|
||||
except M2Crypto.X509.X509Error:
|
||||
raise errors.CertificateFormatError(error=_('Not an entitlement certificate'))
|
||||
dn = 'ipaentitlementid=%s,%s' % (entry_attrs['ipaentitlementid'], dn)
|
||||
dn = DN(('ipaentitlementid', entry_attrs['ipaentitlementid']), dn)
|
||||
(dn, current_attrs) = ldap.get_entry(
|
||||
dn, ['*'], normalize=self.obj.normalize_dn
|
||||
)
|
||||
@ -689,6 +692,7 @@ class entitle_sync(LDAPUpdate):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
os.environ['LANG'] = 'en_US'
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
|
||||
@ -719,6 +723,7 @@ class entitle_sync(LDAPUpdate):
|
||||
Returning the certificates isn't very interesting. Return the
|
||||
status of entitlements instead.
|
||||
"""
|
||||
assert isinstance(dn, DN)
|
||||
if 'usercertificate' in entry_attrs:
|
||||
del entry_attrs['usercertificate']
|
||||
if 'userpkcs12' in entry_attrs:
|
||||
|
@ -156,6 +156,7 @@ class group_add(LDAPCreate):
|
||||
# As both 'external' and 'nonposix' options have default= set for
|
||||
# them, they will always be present in options dict, thus we can
|
||||
# safely reference the values
|
||||
assert isinstance(dn, DN)
|
||||
if options['external']:
|
||||
entry_attrs['objectclass'].append('ipaexternalgroup')
|
||||
if 'gidnumber' in options:
|
||||
@ -176,6 +177,7 @@ class group_del(LDAPDelete):
|
||||
msg_summary = _('Deleted group "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
config = ldap.get_ipa_config()[1]
|
||||
def_primary_group = config.get('ipadefaultprimarygroup', '')
|
||||
def_primary_group_dn = group_dn = self.obj.get_dn(def_primary_group)
|
||||
@ -192,6 +194,7 @@ class group_del(LDAPDelete):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
api.Command['pwpolicy_del'](keys[-1])
|
||||
except errors.NotFound:
|
||||
@ -220,6 +223,7 @@ class group_mod(LDAPUpdate):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if ('posix' in options and options['posix']) or 'gidnumber' in options:
|
||||
(dn, old_entry_attrs) = ldap.get_entry(dn, ['objectclass'])
|
||||
if 'ipaexternalgroup' in old_entry_attrs['objectclass']:
|
||||
@ -275,6 +279,7 @@ class group_find(LDAPSearch):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *args, **options):
|
||||
assert isinstance(base_dn, DN)
|
||||
# if looking for private groups, we need to create a new search filter,
|
||||
# because private groups have different object classes
|
||||
if options['private']:
|
||||
@ -319,6 +324,7 @@ class group_add_member(LDAPAddMember):
|
||||
)
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
result = (completed, dn)
|
||||
if 'ipaexternalmember' in options:
|
||||
if not _dcerpc_bindings_installed:
|
||||
@ -367,6 +373,7 @@ class group_remove_member(LDAPRemoveMember):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if keys[0] == protected_group_name:
|
||||
result = api.Command.group_show(protected_group_name)
|
||||
users_left = set(result['result'].get('member_user', []))
|
||||
@ -377,6 +384,7 @@ class group_remove_member(LDAPRemoveMember):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
result = (completed, dn)
|
||||
if 'ipaexternalmember' in options:
|
||||
sids = options['ipaexternalmember']
|
||||
|
@ -231,6 +231,7 @@ class hbacrule_add(LDAPCreate):
|
||||
msg_summary = _('Added HBAC rule "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# HBAC rules are enabled by default
|
||||
entry_attrs['ipaenabledflag'] = 'TRUE'
|
||||
return dn
|
||||
@ -244,6 +245,7 @@ class hbacrule_del(LDAPDelete):
|
||||
msg_summary = _('Deleted HBAC rule "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
kw = dict(seealso=keys[0])
|
||||
_entries = api.Command.selinuxusermap_find(None, **kw)
|
||||
if _entries['count']:
|
||||
@ -260,6 +262,7 @@ class hbacrule_mod(LDAPUpdate):
|
||||
msg_summary = _('Modified HBAC rule "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(dn, entry_attrs) = ldap.get_entry(dn, attrs_list)
|
||||
except errors.NotFound:
|
||||
@ -436,6 +439,7 @@ class hbacrule_add_user(LDAPAddMember):
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(dn, entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
|
||||
except errors.NotFound:
|
||||
@ -464,6 +468,7 @@ class hbacrule_add_host(LDAPAddMember):
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(dn, entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
|
||||
except errors.NotFound:
|
||||
@ -492,6 +497,7 @@ class hbacrule_add_sourcehost(LDAPAddMember):
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(dn, entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
|
||||
except errors.NotFound:
|
||||
@ -502,6 +508,7 @@ class hbacrule_add_sourcehost(LDAPAddMember):
|
||||
return add_external_pre_callback('host', ldap, dn, keys, options)
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return add_external_post_callback('sourcehost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options)
|
||||
|
||||
api.register(hbacrule_add_sourcehost)
|
||||
@ -514,6 +521,7 @@ class hbacrule_remove_sourcehost(LDAPRemoveMember):
|
||||
member_count_out = ('%i object removed.', '%i objects removed.')
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return remove_external_post_callback('sourcehost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options)
|
||||
|
||||
api.register(hbacrule_remove_sourcehost)
|
||||
@ -526,6 +534,7 @@ class hbacrule_add_service(LDAPAddMember):
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(dn, entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
|
||||
except errors.NotFound:
|
||||
|
@ -38,10 +38,10 @@ from ipalib.plugins.dns import (dns_container_exists, _record_types,
|
||||
from ipalib.plugins.dns import get_reverse_zone
|
||||
from ipalib import _, ngettext
|
||||
from ipalib import x509
|
||||
from ipalib.dn import *
|
||||
from ipalib.request import context
|
||||
from ipalib.util import validate_sshpubkey, output_sshpubkey
|
||||
from ipapython.ipautil import ipa_generate_password, CheckedIPAddress, make_sshfp
|
||||
from ipapython.dn import DN
|
||||
|
||||
__doc__ = _("""
|
||||
Hosts/Machines
|
||||
@ -379,6 +379,7 @@ class host_add(LDAPCreate):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if options.get('ip_address') and dns_container_exists(ldap):
|
||||
parts = keys[-1].split('.')
|
||||
host = parts[0]
|
||||
@ -423,6 +424,7 @@ class host_add(LDAPCreate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
exc = None
|
||||
if dns_container_exists(ldap):
|
||||
try:
|
||||
@ -483,6 +485,7 @@ class host_del(LDAPDelete):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# If we aren't given a fqdn, find it
|
||||
if _hostname_validator(None, keys[-1]) is not None:
|
||||
hostentry = api.Command['host_show'](keys[-1])['result']
|
||||
@ -599,6 +602,7 @@ class host_mod(LDAPUpdate):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# Allow an existing OTP to be reset but don't allow a OTP to be
|
||||
# added to an enrolled host.
|
||||
if options.get('userpassword') or options.get('random'):
|
||||
@ -690,6 +694,7 @@ class host_mod(LDAPUpdate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if options.get('random', False):
|
||||
entry_attrs['randompassword'] = unicode(getattr(context, 'randompassword'))
|
||||
set_certificate_attrs(entry_attrs)
|
||||
@ -728,6 +733,7 @@ class host_find(LDAPSearch):
|
||||
yield option
|
||||
|
||||
def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *args, **options):
|
||||
assert isinstance(base_dn, DN)
|
||||
if 'locality' in attrs_list:
|
||||
attrs_list.remove('locality')
|
||||
attrs_list.append('l')
|
||||
@ -808,6 +814,7 @@ class host_show(LDAPRetrieve):
|
||||
member_attributes = ['managedby']
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.get_password_attributes(ldap, dn, entry_attrs)
|
||||
if entry_attrs['has_password']:
|
||||
# If an OTP is set there is no keytab, at least not one
|
||||
@ -891,8 +898,7 @@ class host_disable(LDAPQuery):
|
||||
try:
|
||||
serial = unicode(x509.get_serial_number(cert, x509.DER))
|
||||
try:
|
||||
result = api.Command['cert_show'](unicode(serial))['result'
|
||||
]
|
||||
result = api.Command['cert_show'](unicode(serial))['result']
|
||||
if 'revocation_reason' not in result:
|
||||
try:
|
||||
api.Command['cert_revoke'](unicode(serial), revocation_reason=4)
|
||||
@ -928,6 +934,7 @@ class host_disable(LDAPQuery):
|
||||
)
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.suppress_netgroup_memberof(entry_attrs)
|
||||
return dn
|
||||
|
||||
@ -941,6 +948,7 @@ class host_add_managedby(LDAPAddMember):
|
||||
allow_same = True
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.suppress_netgroup_memberof(entry_attrs)
|
||||
return (completed, dn)
|
||||
|
||||
@ -954,6 +962,7 @@ class host_remove_managedby(LDAPRemoveMember):
|
||||
has_output_params = LDAPRemoveMember.has_output_params + host_output_params
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.suppress_netgroup_memberof(entry_attrs)
|
||||
return (completed, dn)
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
from ipalib.plugins.baseldap import *
|
||||
from ipalib import api, Int, _, ngettext, errors
|
||||
from ipalib.plugins.netgroup import NETGROUP_PATTERN, NETGROUP_PATTERN_ERRMSG
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
|
||||
__doc__ = _("""
|
||||
Groups of hosts.
|
||||
@ -119,6 +119,7 @@ class hostgroup_add(LDAPCreate):
|
||||
msg_summary = _('Added hostgroup "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
# check duplicity with hostgroups first to provide proper error
|
||||
netgroup = api.Command['hostgroup_show'](keys[-1])
|
||||
@ -140,6 +141,7 @@ class hostgroup_add(LDAPCreate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# Always wait for the associated netgroup to be created so we can
|
||||
# be sure to ignore it in memberOf
|
||||
newentry = wait_for_value(ldap, dn, 'objectclass', 'mepOriginEntry')
|
||||
@ -166,6 +168,7 @@ class hostgroup_mod(LDAPUpdate):
|
||||
msg_summary = _('Modified hostgroup "%(value)s"')
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.suppress_netgroup_memberof(dn, entry_attrs)
|
||||
return dn
|
||||
|
||||
@ -195,6 +198,7 @@ class hostgroup_show(LDAPRetrieve):
|
||||
__doc__ = _('Display information about a hostgroup.')
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.suppress_netgroup_memberof( dn, entry_attrs)
|
||||
return dn
|
||||
|
||||
@ -205,6 +209,7 @@ class hostgroup_add_member(LDAPAddMember):
|
||||
__doc__ = _('Add members to a hostgroup.')
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.suppress_netgroup_memberof(dn, entry_attrs)
|
||||
return (completed, dn)
|
||||
|
||||
@ -215,6 +220,7 @@ class hostgroup_remove_member(LDAPRemoveMember):
|
||||
__doc__ = _('Remove members from a hostgroup.')
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.suppress_netgroup_memberof(dn, entry_attrs)
|
||||
return (completed, dn)
|
||||
|
||||
|
@ -71,7 +71,7 @@ class krbtpolicy(LDAPObject):
|
||||
"""
|
||||
Kerberos Ticket Policy object
|
||||
"""
|
||||
container_dn = 'cn=%s,cn=kerberos' % api.env.realm
|
||||
container_dn = DN(('cn', api.env.realm), ('cn', 'kerberos'))
|
||||
object_name = _('kerberos ticket policy settings')
|
||||
default_attributes = ['krbmaxticketlife', 'krbmaxrenewableage']
|
||||
limit_object_classes = ['krbticketpolicyaux']
|
||||
@ -112,6 +112,7 @@ class krbtpolicy_mod(LDAPUpdate):
|
||||
__doc__ = _('Modify Kerberos ticket policy.')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# disable all flag
|
||||
# ticket policies are attached to objects with unrelated attributes
|
||||
if options.get('all'):
|
||||
@ -125,6 +126,7 @@ class krbtpolicy_show(LDAPRetrieve):
|
||||
__doc__ = _('Display the current Kerberos ticket policy.')
|
||||
|
||||
def pre_callback(self, ldap, dn, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# disable all flag
|
||||
# ticket policies are attached to objects with unrelated attributes
|
||||
if options.get('all'):
|
||||
@ -132,6 +134,7 @@ class krbtpolicy_show(LDAPRetrieve):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if keys[-1] is not None:
|
||||
# if policy for a specific user isn't set, display global values
|
||||
if 'krbmaxticketlife' not in entry_attrs or \
|
||||
|
@ -21,10 +21,8 @@ import re
|
||||
import ldap as _ldap
|
||||
|
||||
from ipalib import api, errors, output
|
||||
from ipalib import Command, Password, Str, Flag, StrEnum
|
||||
from ipalib import Command, Password, Str, Flag, StrEnum, DNParam
|
||||
from ipalib.cli import to_cli
|
||||
from ipalib.util import validate_dn_param
|
||||
from ipalib.dn import *
|
||||
from ipalib.plugins.user import NO_UPG_MAGIC
|
||||
if api.env.in_server and api.env.context in ['lite', 'server']:
|
||||
try:
|
||||
@ -32,6 +30,7 @@ if api.env.in_server and api.env.context in ['lite', 'server']:
|
||||
except StandardError, e:
|
||||
raise e
|
||||
from ipalib import _
|
||||
from ipapython.dn import DN
|
||||
|
||||
__doc__ = _("""
|
||||
Migration to IPA
|
||||
@ -114,18 +113,10 @@ _dn_err_msg = _('Malformed DN')
|
||||
|
||||
_supported_schemas = (u'RFC2307bis', u'RFC2307')
|
||||
|
||||
_compat_dn = "cn=Schema Compatibility,cn=plugins,cn=config"
|
||||
|
||||
def is_DN_syntax(ldap, attr):
|
||||
"""
|
||||
Check the schema to see if the attribute uses DN syntax.
|
||||
|
||||
Returns True/False
|
||||
"""
|
||||
obj = ldap.schema.get_obj(_ldap.schema.AttributeType, attr)
|
||||
return obj is not None and obj.syntax == '1.3.6.1.4.1.1466.115.121.1.12'
|
||||
_compat_dn = DN(('cn', 'Schema Compatibility'), ('cn', 'plugins'), ('cn', 'config'))
|
||||
|
||||
def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs):
|
||||
assert isinstance(dn, DN)
|
||||
attr_blacklist = ['krbprincipalkey','memberofindirect','memberindirect']
|
||||
attr_blacklist.extend(kwargs.get('attr_blacklist', []))
|
||||
ds_ldap = ctx['ds_ldap']
|
||||
@ -198,17 +189,18 @@ def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs
|
||||
# tree
|
||||
|
||||
for attr in entry_attrs.keys():
|
||||
if is_DN_syntax(ldap, attr):
|
||||
if ldap.has_dn_syntax(attr):
|
||||
for ind, value in enumerate(entry_attrs[attr]):
|
||||
assert isinstance(value, DN)
|
||||
try:
|
||||
(remote_dn, remote_entry) = ds_ldap.get_entry(value, [api.Object.user.primary_key.name, api.Object.group.primary_key.name])
|
||||
except errors.NotFound:
|
||||
api.log.warn('%s: attribute %s refers to non-existent entry %s' % (pkey, attr, value))
|
||||
continue
|
||||
if value.lower().endswith(search_bases['user']):
|
||||
if value.endswith(search_bases['user']):
|
||||
primary_key = api.Object.user.primary_key.name
|
||||
container = api.env.container_user
|
||||
elif value.lower().endswith(search_bases['group']):
|
||||
elif value.endswith(search_bases['group']):
|
||||
primary_key = api.Object.group.primary_key.name
|
||||
container = api.env.container_group
|
||||
else:
|
||||
@ -221,15 +213,13 @@ def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs
|
||||
|
||||
api.log.debug('converting DN value %s for %s in %s' % (value, attr, dn))
|
||||
rdnval = remote_entry[primary_key][0].lower()
|
||||
entry_attrs[attr][ind] = \
|
||||
str(DN((primary_key, rdnval),
|
||||
container,
|
||||
api.env.basedn))
|
||||
entry_attrs[attr][ind] = DN((primary_key, rdnval), container, api.env.basedn)
|
||||
|
||||
return dn
|
||||
|
||||
|
||||
def _post_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx):
|
||||
assert isinstance(dn, DN)
|
||||
# add user to the default group
|
||||
try:
|
||||
ldap.add_entry_to_group(dn, ctx['def_group_dn'])
|
||||
@ -246,6 +236,7 @@ def _post_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx):
|
||||
# GROUP MIGRATION CALLBACKS AND VARS
|
||||
|
||||
def _pre_migrate_group(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs):
|
||||
|
||||
def convert_members_rfc2307bis(member_attr, search_bases, overwrite=False):
|
||||
"""
|
||||
Convert DNs in member attributes to work in IPA.
|
||||
@ -253,24 +244,19 @@ def _pre_migrate_group(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwarg
|
||||
new_members = []
|
||||
entry_attrs.setdefault(member_attr, [])
|
||||
for m in entry_attrs[member_attr]:
|
||||
assert isinstance(m, DN)
|
||||
try:
|
||||
# what str2dn returns looks like [[('cn', 'foo', 4)], [('dc', 'example', 1)], [('dc', 'com', 1)]]
|
||||
rdn = _ldap.dn.str2dn(m ,flags=_ldap.DN_FORMAT_LDAPV3)[0]
|
||||
rdnval = rdn[0][1]
|
||||
rdnval = m[0].value
|
||||
except IndexError:
|
||||
api.log.error('Malformed DN %s has no RDN?' % m)
|
||||
continue
|
||||
|
||||
if m.lower().endswith(search_bases['user']):
|
||||
if m.endswith(search_bases['user']):
|
||||
api.log.info('migrating user %s' % m)
|
||||
m = '%s=%s,%s' % (api.Object.user.primary_key.name,
|
||||
rdnval,
|
||||
api.env.container_user)
|
||||
elif m.lower().endswith(search_bases['group']):
|
||||
m = DN((api.Object.user.primary_key.name, rdnval), api.env.container_user)
|
||||
elif m.endswith(search_bases['group']):
|
||||
api.log.info('migrating group %s' % m)
|
||||
m = '%s=%s,%s' % (api.Object.group.primary_key.name,
|
||||
rdnval,
|
||||
api.env.container_group)
|
||||
m = DN((api.Object.group.primary_key.name, rdnval), api.env.container_group)
|
||||
else:
|
||||
api.log.error('entry %s does not belong into any known container' % m)
|
||||
continue
|
||||
@ -290,12 +276,11 @@ def _pre_migrate_group(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwarg
|
||||
new_members = []
|
||||
entry_attrs.setdefault(member_attr, [])
|
||||
for m in entry_attrs[member_attr]:
|
||||
memberdn = '%s=%s,%s' % (api.Object.user.primary_key.name,
|
||||
m,
|
||||
api.env.container_user)
|
||||
memberdn = DN((api.Object.user.primary_key.name, m), api.env.container_user)
|
||||
new_members.append(ldap.normalize_dn(memberdn))
|
||||
entry_attrs['member'] = new_members
|
||||
|
||||
assert isinstance(dn, DN)
|
||||
attr_blacklist = ['memberofindirect','memberindirect']
|
||||
attr_blacklist.extend(kwargs.get('attr_blacklist', []))
|
||||
|
||||
@ -330,6 +315,7 @@ def _pre_migrate_group(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwarg
|
||||
|
||||
|
||||
def _group_exc_callback(ldap, dn, entry_attrs, exc, options):
|
||||
assert isinstance(dn, DN)
|
||||
if isinstance(exc, errors.DuplicateEntry):
|
||||
if options.get('groupoverwritegid', False) and \
|
||||
entry_attrs.get('gidnumber') is not None:
|
||||
@ -424,24 +410,24 @@ class migrate_ds(Command):
|
||||
)
|
||||
|
||||
takes_options = (
|
||||
Str('binddn?', validate_dn_param,
|
||||
DNParam('binddn?',
|
||||
cli_name='bind_dn',
|
||||
label=_('Bind DN'),
|
||||
default=u'cn=directory manager',
|
||||
default=DN(('cn', 'directory manager')),
|
||||
autofill=True,
|
||||
),
|
||||
Str('usercontainer', validate_dn_param,
|
||||
DNParam('usercontainer',
|
||||
cli_name='user_container',
|
||||
label=_('User container'),
|
||||
doc=_('DN of container for users in DS relative to base DN'),
|
||||
default=u'ou=people',
|
||||
default=DN(('ou', 'people')),
|
||||
autofill=True,
|
||||
),
|
||||
Str('groupcontainer', validate_dn_param,
|
||||
DNParam('groupcontainer',
|
||||
cli_name='group_container',
|
||||
label=_('Group container'),
|
||||
doc=_('DN of container for groups in DS relative to base DN'),
|
||||
default=u'ou=groups',
|
||||
default=DN(('ou', 'groups')),
|
||||
autofill=True,
|
||||
),
|
||||
Str('userobjectclass+',
|
||||
@ -511,7 +497,7 @@ class migrate_ds(Command):
|
||||
doc=_('Continuous operation mode. Errors are reported but the process continues'),
|
||||
default=False,
|
||||
),
|
||||
Str('basedn?',
|
||||
DNParam('basedn?',
|
||||
cli_name='base_dn',
|
||||
label=_('Base DN'),
|
||||
doc=_('Base DN on remote LDAP server'),
|
||||
@ -594,11 +580,9 @@ can use their Kerberos accounts.''')
|
||||
|
||||
def _get_search_bases(self, options, ds_base_dn, migrate_order):
|
||||
search_bases = dict()
|
||||
ds_base_dn = DN(ds_base_dn)
|
||||
for ldap_obj_name in migrate_order:
|
||||
container = options.get('%scontainer' % to_cli(ldap_obj_name))
|
||||
if container:
|
||||
container = DN(container)
|
||||
# Don't append base dn if user already appended it in the container dn
|
||||
if container.endswith(ds_base_dn):
|
||||
search_base = container
|
||||
@ -606,13 +590,14 @@ can use their Kerberos accounts.''')
|
||||
search_base = DN(container, ds_base_dn)
|
||||
else:
|
||||
search_base = ds_base_dn
|
||||
search_bases[ldap_obj_name] = str(search_base)
|
||||
search_bases[ldap_obj_name] = search_base
|
||||
return search_bases
|
||||
|
||||
def migrate(self, ldap, config, ds_ldap, ds_base_dn, options):
|
||||
"""
|
||||
Migrate objects from DS to LDAP.
|
||||
"""
|
||||
assert isinstance(ds_base_dn, DN)
|
||||
migrated = {} # {'OBJ': ['PKEY1', 'PKEY2', ...], ...}
|
||||
failed = {} # {'OBJ': {'PKEY1': 'Failed 'cos blabla', ...}, ...}
|
||||
search_bases = self._get_search_bases(options, ds_base_dn, self.migrate_order)
|
||||
@ -703,6 +688,7 @@ can use their Kerberos accounts.''')
|
||||
continue
|
||||
|
||||
dn = ldap_obj.get_dn(pkey)
|
||||
assert isinstance(dn, DN)
|
||||
entry_attrs['objectclass'] = list(
|
||||
set(
|
||||
config.get(
|
||||
@ -722,6 +708,7 @@ can use their Kerberos accounts.''')
|
||||
valid_gids = valid_gids,
|
||||
**blacklists
|
||||
)
|
||||
assert isinstance(dn, DN)
|
||||
if not dn:
|
||||
continue
|
||||
except errors.NotFound, e:
|
||||
@ -760,6 +747,8 @@ can use their Kerberos accounts.''')
|
||||
config = ldap.get_ipa_config()[1]
|
||||
|
||||
ds_base_dn = options.get('basedn')
|
||||
if ds_base_dn is not None:
|
||||
assert isinstance(ds_base_dn, DN)
|
||||
|
||||
# check if migration mode is enabled
|
||||
if config.get('ipamigrationenabled', ('FALSE', ))[0] == 'FALSE':
|
||||
@ -773,6 +762,7 @@ can use their Kerberos accounts.''')
|
||||
if not options.get('compat'):
|
||||
try:
|
||||
(dn,check_compat) = ldap.get_entry(_compat_dn, normalize=False)
|
||||
assert isinstance(dn, DN)
|
||||
if check_compat is not None and \
|
||||
check_compat.get('nsslapd-pluginenabled', [''])[0].lower() == 'on':
|
||||
return dict(result={}, failed={}, enabled=True, compat=False)
|
||||
@ -782,14 +772,16 @@ can use their Kerberos accounts.''')
|
||||
if not ds_base_dn:
|
||||
# retrieve base DN from remote LDAP server
|
||||
(entries, truncated) = ds_ldap.find_entries(
|
||||
'', ['namingcontexts', 'defaultnamingcontext'], '',
|
||||
'', ['namingcontexts', 'defaultnamingcontext'], DN(''),
|
||||
_ldap.SCOPE_BASE, size_limit=-1, time_limit=0,
|
||||
)
|
||||
if 'defaultnamingcontext' in entries[0][1]:
|
||||
ds_base_dn = entries[0][1]['defaultnamingcontext'][0]
|
||||
ds_base_dn = DN(entries[0][1]['defaultnamingcontext'][0])
|
||||
assert isinstance(ds_base_dn, DN)
|
||||
else:
|
||||
try:
|
||||
ds_base_dn = entries[0][1]['namingcontexts'][0]
|
||||
ds_base_dn = DN(entries[0][1]['namingcontexts'][0])
|
||||
assert isinstance(ds_base_dn, DN)
|
||||
except (IndexError, KeyError), e:
|
||||
raise StandardError(str(e))
|
||||
|
||||
|
@ -162,6 +162,7 @@ class netgroup_add(LDAPCreate):
|
||||
u'Hostgroups and netgroups share a common namespace')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
entry_attrs.setdefault('nisdomainname', self.api.env.domain)
|
||||
|
||||
try:
|
||||
@ -203,6 +204,7 @@ class netgroup_mod(LDAPUpdate):
|
||||
msg_summary = _('Modified netgroup "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(dn, entry_attrs) = ldap.get_entry(dn, attrs_list)
|
||||
except errors.NotFound:
|
||||
@ -238,6 +240,7 @@ class netgroup_find(LDAPSearch):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *args, **options):
|
||||
assert isinstance(base_dn, DN)
|
||||
# Do not display private mepManagedEntry netgroups by default
|
||||
# If looking for managed groups, we need to omit the negation search filter
|
||||
|
||||
@ -267,8 +270,11 @@ class netgroup_add_member(LDAPAddMember):
|
||||
member_attributes = ['memberuser', 'memberhost', 'member']
|
||||
has_output_params = LDAPAddMember.has_output_params + output_params
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return add_external_pre_callback('host', ldap, dn, keys, options)
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return add_external_post_callback('memberhost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options)
|
||||
|
||||
api.register(netgroup_add_member)
|
||||
@ -280,6 +286,7 @@ class netgroup_remove_member(LDAPRemoveMember):
|
||||
member_attributes = ['memberuser', 'memberhost', 'member']
|
||||
has_output_params = LDAPRemoveMember.has_output_params + output_params
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return remove_external_post_callback('memberhost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options)
|
||||
|
||||
api.register(netgroup_remove_member)
|
||||
|
@ -24,6 +24,7 @@ from ipalib import _
|
||||
from ipalib import output
|
||||
from ipalib.plugins.user import split_principal, validate_principal, normalize_principal
|
||||
from ipalib.request import context
|
||||
from ipapython.dn import DN
|
||||
|
||||
__doc__ = _("""
|
||||
Set a user's password
|
||||
@ -104,7 +105,7 @@ class passwd(Command):
|
||||
|
||||
(dn, entry_attrs) = ldap.find_entry_by_attr(
|
||||
'krbprincipalname', principal, 'posixaccount', [''],
|
||||
",".join([api.env.container_user, api.env.basedn])
|
||||
DN(api.env.container_user, api.env.basedn)
|
||||
)
|
||||
|
||||
if principal == getattr(context, 'principal') and \
|
||||
|
@ -22,6 +22,7 @@ from ipalib import api, _, ngettext
|
||||
from ipalib import Flag, Str, StrEnum
|
||||
from ipalib.request import context
|
||||
from ipalib import errors
|
||||
from ipapython.dn import DN, EditableDN
|
||||
|
||||
__doc__ = _("""
|
||||
Permissions
|
||||
@ -202,6 +203,7 @@ class permission_add(LDAPCreate):
|
||||
has_output_params = LDAPCreate.has_output_params + output_params
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# Test the ACI before going any further
|
||||
opts = self.obj.filter_aci_attributes(options)
|
||||
opts['test'] = True
|
||||
@ -219,6 +221,7 @@ class permission_add(LDAPCreate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# Now actually add the aci.
|
||||
opts = self.obj.filter_aci_attributes(options)
|
||||
opts['test'] = False
|
||||
@ -275,6 +278,7 @@ class permission_add_noaci(LDAPCreate):
|
||||
yield option
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
permission_type = options.get('permissiontype')
|
||||
if permission_type:
|
||||
entry_attrs['ipapermissiontype'] = [ permission_type ]
|
||||
@ -297,6 +301,7 @@ class permission_del(LDAPDelete):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if not options.get('force') and not self.obj.check_system(ldap, dn, *keys):
|
||||
raise errors.ACIError(info='A SYSTEM permission may not be removed')
|
||||
# remove permission even when the underlying ACI is missing
|
||||
@ -316,6 +321,7 @@ class permission_mod(LDAPUpdate):
|
||||
has_output_params = LDAPUpdate.has_output_params + output_params
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if not self.obj.check_system(ldap, dn, *keys):
|
||||
raise errors.ACIError(info='A SYSTEM permission may not be modified')
|
||||
|
||||
@ -332,10 +338,13 @@ class permission_mod(LDAPUpdate):
|
||||
if 'rename' in options:
|
||||
if options['rename']:
|
||||
try:
|
||||
new_dn = dn.replace(keys[-1].lower(), options['rename'], 1)
|
||||
(new_dn, attrs) = ldap.get_entry(
|
||||
new_dn, attrs_list, normalize=self.obj.normalize_dn
|
||||
)
|
||||
try:
|
||||
new_dn = EditableDN(dn)
|
||||
new_dn[0]['cn'] # assure the first RDN has cn as it's type
|
||||
except (IndexError, KeyError), e:
|
||||
raise ValueError("expected dn starting with 'cn=' but got '%s'" % dn)
|
||||
new_dn[0].value = options['rename']
|
||||
(new_dn, attrs) = ldap.get_entry(new_dn, attrs_list, normalize=self.obj.normalize_dn)
|
||||
raise errors.DuplicateEntry()
|
||||
except errors.NotFound:
|
||||
pass # permission may be renamed, continue
|
||||
@ -371,6 +380,7 @@ class permission_mod(LDAPUpdate):
|
||||
raise exc
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# rename the underlying ACI after the change to permission
|
||||
cn = keys[-1]
|
||||
|
||||
@ -480,6 +490,7 @@ class permission_show(LDAPRetrieve):
|
||||
|
||||
has_output_params = LDAPRetrieve.has_output_params + output_params
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
common_options = filter_options(options, ['all', 'raw'])
|
||||
aci = self.api.Command.aci_show(keys[-1], aciprefix=ACI_PREFIX,
|
||||
|
@ -21,6 +21,7 @@ from ipalib import api, errors
|
||||
from ipalib import Int, Str
|
||||
from ipalib import Object, Command
|
||||
from ipalib import _
|
||||
from ipapython.dn import DN
|
||||
|
||||
__doc__ = _("""
|
||||
Kerberos pkinit options
|
||||
@ -67,9 +68,7 @@ class pkinit_anonymous(Command):
|
||||
__doc__ = _('Enable or Disable Anonymous PKINIT.')
|
||||
|
||||
princ_name = 'WELLKNOWN/ANONYMOUS@%s' % api.env.realm
|
||||
default_dn = 'krbprincipalname=%s,cn=%s,cn=kerberos,%s' % (
|
||||
princ_name, api.env.realm, api.env.basedn
|
||||
)
|
||||
default_dn = DN(('krbprincipalname', princ_name), ('cn', api.env.realm), ('cn', 'kerberos'), api.env.basedn)
|
||||
|
||||
takes_args = (
|
||||
Str('action', valid_arg),
|
||||
|
@ -19,11 +19,12 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from ipalib import api
|
||||
from ipalib import Int, Str
|
||||
from ipalib import Int, Str, DNParam
|
||||
from ipalib.plugins.baseldap import *
|
||||
from ipalib import _
|
||||
from ipalib.request import context
|
||||
from ipapython.ipautil import run
|
||||
from ipapython.dn import DN
|
||||
from distutils import version
|
||||
|
||||
__doc__ = _("""
|
||||
@ -75,13 +76,13 @@ class cosentry(LDAPObject):
|
||||
"""
|
||||
NO_CLI = True
|
||||
|
||||
container_dn = 'cn=costemplates,%s' % api.env.container_accounts
|
||||
container_dn = DN(('cn', 'costemplates'), api.env.container_accounts)
|
||||
object_class = ['top', 'costemplate', 'extensibleobject', 'krbcontainer']
|
||||
default_attributes = ['cn', 'cospriority', 'krbpwdpolicyreference']
|
||||
|
||||
takes_params = (
|
||||
Str('cn', primary_key=True),
|
||||
Str('krbpwdpolicyreference'),
|
||||
DNParam('krbpwdpolicyreference'),
|
||||
Int('cospriority', minvalue=0),
|
||||
)
|
||||
|
||||
@ -102,8 +103,7 @@ class cosentry(LDAPObject):
|
||||
)['result']
|
||||
if len(entries) > 0:
|
||||
group_name = self.api.Object.group.get_primary_key_from_dn(
|
||||
entries[0]['cn'][0]
|
||||
)
|
||||
DN(entries[0]['cn'][0]))
|
||||
raise errors.ValidationError(
|
||||
name='priority',
|
||||
error=self.priority_not_unique_msg % {
|
||||
@ -119,6 +119,7 @@ class cosentry_add(LDAPCreate):
|
||||
NO_CLI = True
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# check for existence of the group
|
||||
result = self.api.Command.group_show(keys[-1], all=True)['result']
|
||||
oc = map(lambda x:x.lower(),result['objectclass'])
|
||||
@ -141,6 +142,7 @@ class cosentry_mod(LDAPUpdate):
|
||||
NO_CLI = True
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
new_cospriority = options.get('cospriority')
|
||||
if new_cospriority is not None:
|
||||
cos_entry = self.api.Command.cosentry_show(keys[-1])['result']
|
||||
@ -167,13 +169,13 @@ api.register(cosentry_find)
|
||||
|
||||
|
||||
global_policy_name = 'global_policy'
|
||||
global_policy_dn = 'cn=%s,cn=%s,cn=kerberos,%s' % (global_policy_name, api.env.realm, api.env.basedn)
|
||||
global_policy_dn = DN(('cn', global_policy_name), ('cn', api.env.realm), ('cn', 'kerberos'), api.env.basedn)
|
||||
|
||||
class pwpolicy(LDAPObject):
|
||||
"""
|
||||
Password Policy object
|
||||
"""
|
||||
container_dn = 'cn=%s,cn=kerberos' % api.env.realm
|
||||
container_dn = DN(('cn', api.env.realm), ('cn', 'kerberos'))
|
||||
object_name = _('password policy')
|
||||
object_name_plural = _('password policies')
|
||||
object_class = ['top', 'nscontainer', 'krbpwdpolicy']
|
||||
@ -339,6 +341,7 @@ class pwpolicy_add(LDAPCreate):
|
||||
yield self.obj.primary_key.clone(attribute=True, required=True)
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.convert_time_on_input(entry_attrs)
|
||||
self.obj.validate_lifetime(entry_attrs, True)
|
||||
self.api.Command.cosentry_add(
|
||||
@ -348,6 +351,7 @@ class pwpolicy_add(LDAPCreate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.log.info('%r' % entry_attrs)
|
||||
# attribute rights are not allowed for pwpolicy_add
|
||||
self.obj.add_cospriority(entry_attrs, keys[-1], rights=False)
|
||||
@ -366,7 +370,8 @@ class pwpolicy_del(LDAPDelete):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
if dn.lower() == global_policy_dn.lower():
|
||||
assert isinstance(dn, DN)
|
||||
if dn == global_policy_dn:
|
||||
raise errors.ValidationError(
|
||||
name='group',
|
||||
error=_('cannot delete global password policy')
|
||||
@ -374,6 +379,7 @@ class pwpolicy_del(LDAPDelete):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
self.api.Command.cosentry_del(keys[-1])
|
||||
except errors.NotFound:
|
||||
@ -387,6 +393,7 @@ class pwpolicy_mod(LDAPUpdate):
|
||||
__doc__ = _('Modify a group password policy.')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.convert_time_on_input(entry_attrs)
|
||||
self.obj.validate_lifetime(entry_attrs, False, *keys)
|
||||
setattr(context, 'cosupdate', False)
|
||||
@ -408,6 +415,7 @@ class pwpolicy_mod(LDAPUpdate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
rights = options.get('all', False) and options.get('rights', False)
|
||||
self.obj.add_cospriority(entry_attrs, keys[-1], rights)
|
||||
self.obj.convert_time_for_output(entry_attrs, **options)
|
||||
@ -436,6 +444,7 @@ class pwpolicy_show(LDAPRetrieve):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if options.get('user') is not None:
|
||||
user_entry = self.api.Command.user_show(
|
||||
options['user'], all=True
|
||||
@ -445,6 +454,7 @@ class pwpolicy_show(LDAPRetrieve):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
rights = options.get('all', False) and options.get('rights', False)
|
||||
self.obj.add_cospriority(entry_attrs, keys[-1], rights)
|
||||
self.obj.convert_time_for_output(entry_attrs, **options)
|
||||
|
@ -96,6 +96,7 @@ class range_add(LDAPCreate):
|
||||
msg_summary = _('Added ID range "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if ('ipanttrusteddomainsid' not in options and
|
||||
'ipasecondarybaserid' not in options):
|
||||
raise errors.ValidationError(name=_('Range setup'),
|
||||
@ -110,6 +111,7 @@ class range_add(LDAPCreate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.handle_iparangetype(entry_attrs, options, keep_objectclass=True)
|
||||
return dn
|
||||
|
||||
@ -128,6 +130,7 @@ class range_find(LDAPSearch):
|
||||
# Since all range types are stored within separate containers under
|
||||
# 'cn=ranges,cn=etc' search can be done on a one-level scope
|
||||
def pre_callback(self, ldap, filters, attrs_list, base_dn, scope, *args, **options):
|
||||
assert isinstance(base_dn, DN)
|
||||
attrs_list.append('objectclass')
|
||||
return (filters, base_dn, ldap.SCOPE_ONELEVEL)
|
||||
|
||||
@ -140,10 +143,12 @@ class range_show(LDAPRetrieve):
|
||||
__doc__ = _('Display information about a range.')
|
||||
|
||||
def pre_callback(self, ldap, dn, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
attrs_list.append('objectclass')
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.handle_iparangetype(entry_attrs, options)
|
||||
return dn
|
||||
|
||||
@ -153,10 +158,12 @@ class range_mod(LDAPUpdate):
|
||||
msg_summary = _('Modified ID range "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
attrs_list.append('objectclass')
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.handle_iparangetype(entry_attrs, options)
|
||||
return dn
|
||||
|
||||
@ -166,4 +173,3 @@ api.register(range_mod)
|
||||
api.register(range_del)
|
||||
api.register(range_find)
|
||||
api.register(range_show)
|
||||
|
||||
|
@ -234,6 +234,7 @@ class selinuxusermap_add(LDAPCreate):
|
||||
msg_summary = _('Added SELinux User Map "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# rules are enabled by default
|
||||
entry_attrs['ipaenabledflag'] = 'TRUE'
|
||||
validate_selinuxuser_inlist(ldap, entry_attrs['ipaselinuxuser'])
|
||||
@ -243,6 +244,7 @@ class selinuxusermap_add(LDAPCreate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj._convert_seealso(ldap, entry_attrs, **options)
|
||||
|
||||
return dn
|
||||
@ -264,6 +266,7 @@ class selinuxusermap_mod(LDAPUpdate):
|
||||
msg_summary = _('Modified SELinux User Map "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(_dn, _entry_attrs) = ldap.get_entry(dn, attrs_list)
|
||||
except errors.NotFound:
|
||||
@ -288,6 +291,7 @@ class selinuxusermap_mod(LDAPUpdate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj._convert_seealso(ldap, entry_attrs, **options)
|
||||
return dn
|
||||
|
||||
@ -331,6 +335,7 @@ class selinuxusermap_show(LDAPRetrieve):
|
||||
__doc__ = _('Display the properties of a SELinux User Map rule.')
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj._convert_seealso(ldap, entry_attrs, **options)
|
||||
return dn
|
||||
|
||||
@ -398,6 +403,7 @@ class selinuxusermap_add_user(LDAPAddMember):
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(dn, entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
|
||||
except errors.NotFound:
|
||||
@ -428,6 +434,7 @@ class selinuxusermap_add_host(LDAPAddMember):
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(dn, entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
|
||||
except errors.NotFound:
|
||||
|
@ -278,6 +278,7 @@ class service_add(LDAPCreate):
|
||||
),
|
||||
)
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
(service, hostname, realm) = split_principal(keys[-1])
|
||||
if service.lower() == 'host' and not options['force']:
|
||||
raise errors.HostService()
|
||||
@ -322,6 +323,7 @@ class service_del(LDAPDelete):
|
||||
msg_summary = _('Deleted service "%(value)s"')
|
||||
member_attributes = ['managedby']
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# In the case of services we don't want IPA master services to be
|
||||
# deleted. This is a limited few though. If the user has their own
|
||||
# custom services allow them to manage them.
|
||||
@ -367,6 +369,7 @@ class service_mod(LDAPUpdate):
|
||||
member_attributes = ['managedby']
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if 'usercertificate' in options:
|
||||
(service, hostname, realm) = split_principal(keys[-1])
|
||||
cert = options.get('usercertificate')
|
||||
@ -386,7 +389,9 @@ class service_mod(LDAPUpdate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
set_certificate_attrs(entry_attrs)
|
||||
return dn
|
||||
|
||||
api.register(service_mod)
|
||||
|
||||
@ -402,6 +407,7 @@ class service_find(LDAPSearch):
|
||||
has_output_params = LDAPSearch.has_output_params + output_params
|
||||
|
||||
def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *args, **options):
|
||||
assert isinstance(base_dn, DN)
|
||||
# lisp style!
|
||||
custom_filter = '(&(objectclass=ipaService)' \
|
||||
'(!(objectClass=posixAccount))' \
|
||||
@ -439,6 +445,7 @@ class service_show(LDAPRetrieve):
|
||||
has_output_params = LDAPRetrieve.has_output_params + output_params
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.get_password_attributes(ldap, dn, entry_attrs)
|
||||
|
||||
set_certificate_attrs(entry_attrs)
|
||||
|
@ -246,6 +246,7 @@ class sudorule_add(LDAPCreate):
|
||||
__doc__ = _('Create new Sudo Rule.')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
self.obj.check_order_uniqueness(*keys, **options)
|
||||
# Sudo Rules are enabled by default
|
||||
entry_attrs['ipaenabledflag'] = 'TRUE'
|
||||
@ -269,6 +270,7 @@ class sudorule_mod(LDAPUpdate):
|
||||
|
||||
msg_summary = _('Modified Sudo Rule "%(value)s"')
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if 'sudoorder' in options:
|
||||
new_order = options.get('sudoorder')
|
||||
old_entry = self.api.Command.sudorule_show(keys[-1])['result']
|
||||
@ -371,6 +373,7 @@ class sudorule_add_allow_command(LDAPAddMember):
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(_dn, _entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
|
||||
except errors.NotFound:
|
||||
@ -399,6 +402,7 @@ class sudorule_add_deny_command(LDAPAddMember):
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(_dn, _entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
|
||||
except errors.NotFound:
|
||||
@ -426,6 +430,7 @@ class sudorule_add_user(LDAPAddMember):
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(_dn, _entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
|
||||
except errors.NotFound:
|
||||
@ -435,6 +440,7 @@ class sudorule_add_user(LDAPAddMember):
|
||||
return add_external_pre_callback('user', ldap, dn, keys, options)
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return add_external_post_callback('memberuser', 'user', 'externaluser', ldap, completed, failed, dn, entry_attrs, keys, options)
|
||||
|
||||
api.register(sudorule_add_user)
|
||||
@ -447,6 +453,7 @@ class sudorule_remove_user(LDAPRemoveMember):
|
||||
member_count_out = ('%i object removed.', '%i objects removed.')
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return remove_external_post_callback('memberuser', 'user', 'externaluser', ldap, completed, failed, dn, entry_attrs, keys, options)
|
||||
|
||||
api.register(sudorule_remove_user)
|
||||
@ -459,6 +466,7 @@ class sudorule_add_host(LDAPAddMember):
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
(_dn, _entry_attrs) = ldap.get_entry(dn, self.obj.default_attributes)
|
||||
except errors.NotFound:
|
||||
@ -468,6 +476,7 @@ class sudorule_add_host(LDAPAddMember):
|
||||
return add_external_pre_callback('host', ldap, dn, keys, options)
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return add_external_post_callback('memberhost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options)
|
||||
|
||||
api.register(sudorule_add_host)
|
||||
@ -480,6 +489,7 @@ class sudorule_remove_host(LDAPRemoveMember):
|
||||
member_count_out = ('%i object removed.', '%i objects removed.')
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return remove_external_post_callback('memberhost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options)
|
||||
|
||||
api.register(sudorule_remove_host)
|
||||
@ -491,6 +501,7 @@ class sudorule_add_runasuser(LDAPAddMember):
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
def check_validity(runas):
|
||||
v = unicode(runas)
|
||||
if v.upper() == u'ALL':
|
||||
@ -521,6 +532,7 @@ class sudorule_add_runasuser(LDAPAddMember):
|
||||
return add_external_pre_callback('user', ldap, dn, keys, options)
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return add_external_post_callback('ipasudorunas', 'user', 'ipasudorunasextuser', ldap, completed, failed, dn, entry_attrs, keys, options)
|
||||
|
||||
api.register(sudorule_add_runasuser)
|
||||
@ -533,6 +545,7 @@ class sudorule_remove_runasuser(LDAPRemoveMember):
|
||||
member_count_out = ('%i object removed.', '%i objects removed.')
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return remove_external_post_callback('ipasudorunas', 'user', 'ipasudorunasextuser', ldap, completed, failed, dn, entry_attrs, keys, options)
|
||||
|
||||
api.register(sudorule_remove_runasuser)
|
||||
@ -545,6 +558,7 @@ class sudorule_add_runasgroup(LDAPAddMember):
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
def check_validity(runas):
|
||||
v = unicode(runas)
|
||||
if v.upper() == u'ALL':
|
||||
@ -569,6 +583,7 @@ class sudorule_add_runasgroup(LDAPAddMember):
|
||||
return add_external_pre_callback('group', ldap, dn, keys, options)
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return add_external_post_callback('ipasudorunasgroup', 'group', 'ipasudorunasextgroup', ldap, completed, failed, dn, entry_attrs, keys, options)
|
||||
|
||||
api.register(sudorule_add_runasgroup)
|
||||
@ -581,6 +596,7 @@ class sudorule_remove_runasgroup(LDAPRemoveMember):
|
||||
member_count_out = ('%i object removed.', '%i objects removed.')
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return remove_external_post_callback('ipasudorunasgroup', 'group', 'ipasudorunasextgroup', ldap, completed, failed, dn, entry_attrs, keys, options)
|
||||
|
||||
api.register(sudorule_remove_runasgroup)
|
||||
|
@ -107,9 +107,10 @@ class trust(LDAPObject):
|
||||
)
|
||||
|
||||
def make_trust_dn(env, trust_type, dn):
|
||||
assert isinstance(dn, DN)
|
||||
if trust_type in trust.trust_types:
|
||||
container_dn = DN(('cn', trust_type), env.container_trusts, env.basedn)
|
||||
return unicode(DN(DN(dn)[0], container_dn))
|
||||
return DN(dn[0], container_dn)
|
||||
return dn
|
||||
|
||||
class trust_add(LDAPCreate):
|
||||
@ -214,6 +215,7 @@ class trust_del(LDAPDelete):
|
||||
msg_summary = _('Deleted trust "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
result = self.api.Command.trust_show(keys[-1])
|
||||
except errors.NotFound, e:
|
||||
@ -226,6 +228,7 @@ class trust_mod(LDAPUpdate):
|
||||
msg_summary = _('Modified trust "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
result = None
|
||||
try:
|
||||
result = self.api.Command.trust_show(keys[-1])
|
||||
@ -245,6 +248,7 @@ class trust_find(LDAPSearch):
|
||||
# Since all trusts types are stored within separate containers under 'cn=trusts',
|
||||
# search needs to be done on a sub-tree scope
|
||||
def pre_callback(self, ldap, filters, attrs_list, base_dn, scope, *args, **options):
|
||||
assert isinstance(base_dn, DN)
|
||||
return (filters, base_dn, ldap.SCOPE_SUBTREE)
|
||||
|
||||
class trust_show(LDAPRetrieve):
|
||||
@ -271,6 +275,7 @@ class trust_show(LDAPRetrieve):
|
||||
return result
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if 'trust_show_type' in options:
|
||||
return make_trust_dn(self.env, options['trust_show_type'], dn)
|
||||
return dn
|
||||
@ -281,4 +286,3 @@ api.register(trust_mod)
|
||||
api.register(trust_del)
|
||||
api.register(trust_find)
|
||||
api.register(trust_show)
|
||||
|
||||
|
@ -375,11 +375,12 @@ class user(LDAPObject):
|
||||
if not manager:
|
||||
return None
|
||||
|
||||
if isinstance(manager, basestring):
|
||||
if not isinstance(manager, list):
|
||||
manager = [manager]
|
||||
try:
|
||||
container_dn = DN(self.container_dn, api.env.basedn)
|
||||
for m in xrange(len(manager)):
|
||||
if manager[m].endswith('%s,%s' % (self.container_dn, api.env.basedn)):
|
||||
if isinstance(manager[m], DN) and manager[m].endswith(container_dn):
|
||||
continue
|
||||
(dn, entry_attrs) = self.backend.find_entry_by_attr(
|
||||
self.primary_key.name, manager[m], self.object_class, [''],
|
||||
@ -420,6 +421,7 @@ class user_add(LDAPCreate):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if not options.get('noprivate', False):
|
||||
try:
|
||||
# The Managed Entries plugin will allow a user to be created
|
||||
@ -459,7 +461,9 @@ class user_add(LDAPCreate):
|
||||
homes_root = config.get('ipahomesrootdir', ['/home'])[0]
|
||||
# build user's home directory based on his uid
|
||||
entry_attrs['homedirectory'] = posixpath.join(homes_root, keys[-1])
|
||||
entry_attrs.setdefault('krbpwdpolicyreference', 'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn))
|
||||
entry_attrs.setdefault('krbpwdpolicyreference',
|
||||
DN(('cn', 'global_policy'), ('cn', api.env.realm), ('cn', 'kerberos'),
|
||||
api.env.basedn))
|
||||
entry_attrs.setdefault('krbprincipalname', '%s@%s' % (entry_attrs['uid'], api.env.realm))
|
||||
|
||||
if entry_attrs.get('gidnumber', DNA_MAGIC) == DNA_MAGIC:
|
||||
@ -496,6 +500,7 @@ class user_add(LDAPCreate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
config = ldap.get_ipa_config()[1]
|
||||
# add the user we just created into the default primary group
|
||||
def_primary_group = config.get('ipadefaultprimarygroup')
|
||||
@ -544,6 +549,7 @@ class user_del(LDAPDelete):
|
||||
msg_summary = _('Deleted user "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
protected_group_name = u'admins'
|
||||
result = api.Command.group_show(protected_group_name)
|
||||
if result['result'].get('member_user', []) == [keys[-1]]:
|
||||
@ -562,6 +568,7 @@ class user_mod(LDAPUpdate):
|
||||
has_output_params = LDAPUpdate.has_output_params + user_output_params
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if options.get('rename') is not None:
|
||||
config = ldap.get_ipa_config()[1]
|
||||
if 'ipamaxusernamelength' in config:
|
||||
@ -592,6 +599,7 @@ class user_mod(LDAPUpdate):
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
if options.get('random', False):
|
||||
try:
|
||||
entry_attrs['randompassword'] = unicode(getattr(context, 'randompassword'))
|
||||
@ -621,6 +629,7 @@ class user_find(LDAPSearch):
|
||||
)
|
||||
|
||||
def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *keys, **options):
|
||||
assert isinstance(base_dn, DN)
|
||||
if options.get('whoami'):
|
||||
return ("(&(objectclass=posixaccount)(krbprincipalname=%s))"%\
|
||||
getattr(context, 'principal'), base_dn, scope)
|
||||
@ -651,6 +660,7 @@ class user_show(LDAPRetrieve):
|
||||
has_output_params = LDAPRetrieve.has_output_params + user_output_params
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
convert_nsaccountlock(entry_attrs)
|
||||
self.obj._convert_manager(entry_attrs, **options)
|
||||
self.obj.get_password_attributes(ldap, dn, entry_attrs)
|
||||
@ -763,7 +773,7 @@ class user_status(LDAPQuery):
|
||||
# Get list of masters
|
||||
try:
|
||||
(masters, truncated) = ldap.find_entries(
|
||||
None, ['*'], 'cn=masters,cn=ipa,cn=etc,%s' % api.env.basedn,
|
||||
None, ['*'], DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn),
|
||||
ldap.SCOPE_ONELEVEL
|
||||
)
|
||||
except errors.NotFound:
|
||||
|
@ -23,6 +23,7 @@ Base classes for non-LDAP backend plugins.
|
||||
from ipalib import api
|
||||
from ipalib import Command
|
||||
from ipalib import errors
|
||||
from ipapython.dn import DN
|
||||
|
||||
class VirtualCommand(Command):
|
||||
"""
|
||||
@ -55,7 +56,7 @@ class VirtualCommand(Command):
|
||||
ldap = self.api.Backend.ldap2
|
||||
self.log.debug("IPA: virtual verify %s" % operation)
|
||||
|
||||
operationdn = "cn=%s,%s,%s" % (operation, self.api.env.container_virtual, self.api.env.basedn)
|
||||
operationdn = DN(('cn', operation), self.api.env.container_virtual, self.api.env.basedn)
|
||||
|
||||
try:
|
||||
if not ldap.can_write(operationdn, "objectclass"):
|
||||
|
@ -57,6 +57,7 @@ from nss.error import NSPRError
|
||||
from urllib2 import urlparse
|
||||
from ipalib.krb_utils import KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, KRB5KRB_AP_ERR_TKT_EXPIRED, \
|
||||
KRB5_FCC_PERM, KRB5_FCC_NOFILE, KRB5_CC_FORMAT, KRB5_REALM_CANT_RESOLVE
|
||||
from ipapython.dn import DN
|
||||
|
||||
COOKIE_NAME = 'ipa_session_cookie:%s'
|
||||
|
||||
@ -83,7 +84,7 @@ def xml_wrap(value):
|
||||
"""
|
||||
if type(value) in (list, tuple):
|
||||
return tuple(xml_wrap(v) for v in value)
|
||||
if type(value) is dict:
|
||||
if isinstance(value, dict):
|
||||
return dict(
|
||||
(k, xml_wrap(v)) for (k, v) in value.iteritems()
|
||||
)
|
||||
@ -92,6 +93,8 @@ def xml_wrap(value):
|
||||
if type(value) is Decimal:
|
||||
# transfer Decimal as a string
|
||||
return unicode(value)
|
||||
if isinstance(value, DN):
|
||||
return str(value)
|
||||
assert type(value) in (unicode, int, float, bool, NoneType)
|
||||
return value
|
||||
|
||||
|
@ -628,7 +628,7 @@ mod_auth_kerb. Everything else remains the same.
|
||||
|
||||
default_max_session_duration = 60*60 # number of seconds
|
||||
|
||||
ISO8601_DATETIME_FMT = '%Y-%m-%dT%H:%M:%S' # FIXME jrd, this should be defined elsewhere
|
||||
ISO8601_DATETIME_FMT = '%Y-%m-%dT%H:%M:%S' # FIXME, this should be defined elsewhere
|
||||
def fmt_time(timestamp):
|
||||
return time.strftime(ISO8601_DATETIME_FMT, time.localtime(timestamp))
|
||||
|
||||
|
@ -33,8 +33,8 @@ from dns.exception import DNSException
|
||||
|
||||
from ipalib import errors
|
||||
from ipalib.text import _
|
||||
from ipalib.dn import DN, RDN
|
||||
from ipapython.ipautil import decode_ssh_pubkey
|
||||
from ipapython.dn import DN, RDN
|
||||
|
||||
|
||||
def json_serialize(obj):
|
||||
@ -472,10 +472,3 @@ def validate_rdn_param(ugettext, value):
|
||||
except Exception, e:
|
||||
return str(e)
|
||||
return None
|
||||
|
||||
def validate_dn_param(ugettext, value):
|
||||
try:
|
||||
rdn = DN(value)
|
||||
except Exception, e:
|
||||
return str(e)
|
||||
return None
|
||||
|
@ -42,7 +42,7 @@ from ipalib import api
|
||||
from ipalib import _
|
||||
from ipalib import util
|
||||
from ipalib import errors
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
|
||||
PEM = 0
|
||||
DER = 1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,7 @@
|
||||
import copy
|
||||
|
||||
from ipapython import ipautil
|
||||
from ipapython.dn import DN
|
||||
|
||||
def copy_CIDict(x):
|
||||
"""Do a deep copy of a CIDict"""
|
||||
@ -45,19 +46,25 @@ class Entity:
|
||||
if isinstance(entrydata,tuple):
|
||||
self.dn = entrydata[0]
|
||||
self.data = ipautil.CIDict(entrydata[1])
|
||||
elif isinstance(entrydata,str) or isinstance(entrydata,unicode):
|
||||
elif isinstance(entrydata, DN):
|
||||
self.dn = entrydata
|
||||
self.data = ipautil.CIDict()
|
||||
elif isinstance(entrydata, basestring):
|
||||
self.dn = DN(entrydata)
|
||||
self.data = ipautil.CIDict()
|
||||
elif isinstance(entrydata,dict):
|
||||
self.dn = entrydata['dn']
|
||||
del entrydata['dn']
|
||||
self.data = ipautil.CIDict(entrydata)
|
||||
else:
|
||||
self.dn = ''
|
||||
self.dn = DN()
|
||||
self.data = ipautil.CIDict()
|
||||
|
||||
assert isinstance(self.dn, DN)
|
||||
self.orig_data = ipautil.CIDict(copy_CIDict(self.data))
|
||||
|
||||
dn = ipautil.dn_attribute_property('_dn')
|
||||
|
||||
def __nonzero__(self):
|
||||
"""This allows us to do tests like if entry: returns false if there is no data,
|
||||
true otherwise"""
|
||||
@ -67,23 +74,8 @@ class Entity:
|
||||
"""Return True if this entry has an attribute named name, False otherwise"""
|
||||
return self.data and self.data.has_key(name)
|
||||
|
||||
def __setattr__(self,name,value):
|
||||
"""One should use setValue() or setValues() to set values except for
|
||||
dn and data which are special."""
|
||||
if name != 'dn' and name != 'data' and name != 'orig_data':
|
||||
raise KeyError, 'use setValue() or setValues()'
|
||||
else:
|
||||
self.__dict__[name] = value
|
||||
|
||||
def __getattr__(self,name):
|
||||
"""If name is the name of an LDAP attribute, return the first value for that
|
||||
attribute - equivalent to getValue - this allows the use of
|
||||
entry.cn
|
||||
instead of
|
||||
entry.getValue('cn')
|
||||
This also allows us to return None if an attribute is not found rather than
|
||||
throwing an exception"""
|
||||
return self.getValue(name)
|
||||
def __str__(self):
|
||||
return "dn: %s data: %s" % (self.dn, self.data)
|
||||
|
||||
def getValues(self,name):
|
||||
"""Get the list (array) of values for the attribute named name"""
|
||||
@ -150,6 +142,7 @@ class Entity:
|
||||
def toDict(self):
|
||||
"""Convert the attrs and values to a dict. The dict is keyed on the
|
||||
attribute name. The value is either single value or a list of values."""
|
||||
assert isinstance(self.dn, DN)
|
||||
result = ipautil.CIDict(self.data)
|
||||
result['dn'] = self.dn
|
||||
return result
|
||||
@ -160,6 +153,7 @@ class Entity:
|
||||
|
||||
def origDataDict(self):
|
||||
"""Returns a dict of the original values of the user. Used for updates."""
|
||||
assert isinstance(self.dn, DN)
|
||||
result = ipautil.CIDict(self.orig_data)
|
||||
result['dn'] = self.dn
|
||||
return result
|
||||
|
@ -101,10 +101,10 @@ class IPALogManager(LogManager):
|
||||
in the Env config must begin with "log_logger_level\_" and then be
|
||||
followed by a symbolic or numeric log level, for example::
|
||||
|
||||
log_logger_level_debug = ipalib\.dn\..*
|
||||
log_logger_level_debug = ipapython\.dn\..*
|
||||
log_logger_level_35 = ipalib\.plugins\.dogtag
|
||||
|
||||
The first line says any logger belonging to the ipalib.dn module
|
||||
The first line says any logger belonging to the ipapython.dn module
|
||||
will have it's level configured to debug.
|
||||
|
||||
The second line say the ipa.plugins.dogtag logger will be
|
||||
|
@ -49,6 +49,7 @@ from dns.exception import DNSException
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython import ipavalidate
|
||||
from ipapython import config
|
||||
from ipapython.dn import DN
|
||||
|
||||
try:
|
||||
from subprocess import CalledProcessError
|
||||
@ -200,10 +201,16 @@ def format_netloc(host, port=None):
|
||||
return '%s:%s' % (host, str(port))
|
||||
|
||||
def realm_to_suffix(realm_name):
|
||||
"""Convert a kerberos realm into the IPA suffix."""
|
||||
'Convert a kerberos realm to a IPA suffix.'
|
||||
s = realm_name.split(".")
|
||||
terms = ["dc=" + x.lower() for x in s]
|
||||
return ",".join(terms)
|
||||
suffix_dn = DN(*[('dc', x.lower()) for x in s])
|
||||
return suffix_dn
|
||||
|
||||
def suffix_to_realm(suffix_dn):
|
||||
'Convert a IPA suffix to a kerberos realm.'
|
||||
assert isinstance(suffix_dn, DN)
|
||||
realm = '.'.join([x.value for x in suffix_dn])
|
||||
return realm
|
||||
|
||||
def template_str(txt, vars):
|
||||
val = string.Template(txt).substitute(vars)
|
||||
@ -1111,3 +1118,33 @@ def kinit_hostprincipal(keytab, ccachedir, principal):
|
||||
return ccache_file
|
||||
except krbV.Krb5Error, e:
|
||||
raise StandardError('Error initializing principal %s in %s: %s' % (principal, keytab, str(e)))
|
||||
|
||||
def dn_attribute_property(private_name):
|
||||
'''
|
||||
Create a property for a dn attribute which assures the attribute
|
||||
is a DN or None. If the value is not None the setter converts it to
|
||||
a DN. The getter assures it's either None or a DN instance.
|
||||
|
||||
The private_name parameter is the class internal attribute the property
|
||||
shadows.
|
||||
|
||||
For example if a class has an attribute called base_dn, then:
|
||||
|
||||
base_dn = dn_attribute_property('_base_dn')
|
||||
|
||||
Thus the class with have an attriubte called base_dn which can only
|
||||
ever be None or a DN instance. The actual value is stored in _base_dn.
|
||||
'''
|
||||
|
||||
def setter(self, value):
|
||||
if value is not None:
|
||||
value = DN(value)
|
||||
setattr(self, private_name, value)
|
||||
|
||||
def getter(self):
|
||||
value = getattr(self, private_name)
|
||||
if value is not None:
|
||||
assert isinstance(value, DN)
|
||||
return value
|
||||
|
||||
return property(getter, setter)
|
||||
|
@ -1,69 +0,0 @@
|
||||
# Authors: Rob Crittenden <rcritten@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 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, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import krbV
|
||||
import ldap
|
||||
import ldap.dn
|
||||
import ipaldap
|
||||
|
||||
class IPAConn:
|
||||
def __init__(self, host, port, krbccache, debug=None):
|
||||
self._conn = None
|
||||
|
||||
# Save the arguments
|
||||
self._host = host
|
||||
self._port = port
|
||||
self._krbccache = krbccache
|
||||
self._debug = debug
|
||||
|
||||
self._ctx = krbV.default_context()
|
||||
|
||||
ccache = krbV.CCache(name=krbccache, context=self._ctx)
|
||||
cprinc = ccache.principal()
|
||||
|
||||
self._conn = ipaldap.IPAdmin(host,port,None,None,None,debug)
|
||||
|
||||
# This will bind the connection
|
||||
try:
|
||||
self._conn.set_krbccache(krbccache, cprinc.name)
|
||||
except ldap.UNWILLING_TO_PERFORM, e:
|
||||
raise e
|
||||
except Exception, e:
|
||||
raise e
|
||||
|
||||
def __del__(self):
|
||||
# take no chances on unreleased connections
|
||||
self.releaseConn()
|
||||
|
||||
def getConn(self):
|
||||
return self._conn
|
||||
|
||||
def releaseConn(self):
|
||||
if self._conn is None:
|
||||
return
|
||||
|
||||
self._conn.unbind_s()
|
||||
self._conn = None
|
||||
|
||||
return
|
||||
|
||||
if __name__ == "__main__":
|
||||
ipaconn = IPAConn("localhost", 389, "FILE:/tmp/krb5cc_500")
|
||||
x = ipaconn.getConn().getEntry("dc=example,dc=com", ldap.SCOPE_SUBTREE, "uid=admin", ["cn"])
|
||||
print "%s" % x
|
@ -101,7 +101,7 @@ class DomainValidator(object):
|
||||
def is_configured(self):
|
||||
cn_trust_local = DN(('cn', self.api.env.domain), self.api.env.container_cifsdomains, self.api.env.basedn)
|
||||
try:
|
||||
(dn, entry_attrs) = self.ldap.get_entry(unicode(cn_trust_local), [self.ATTR_FLATNAME, self.ATTR_SID])
|
||||
(dn, entry_attrs) = self.ldap.get_entry(cn_trust_local, [self.ATTR_FLATNAME, self.ATTR_SID])
|
||||
self.flatname = entry_attrs[self.ATTR_FLATNAME][0]
|
||||
self.sid = entry_attrs[self.ATTR_SID][0]
|
||||
self.dn = dn
|
||||
@ -115,7 +115,7 @@ class DomainValidator(object):
|
||||
try:
|
||||
search_kw = {'objectClass': 'ipaNTTrustedDomain'}
|
||||
filter = self.ldap.make_filter(search_kw, rules=self.ldap.MATCH_ALL)
|
||||
(entries, truncated) = self.ldap.find_entries(filter=filter, base_dn=unicode(cn_trust),
|
||||
(entries, truncated) = self.ldap.find_entries(filter=filter, base_dn=cn_trust,
|
||||
attrs_list=[self.ATTR_TRUSTED_SID, 'dn'])
|
||||
|
||||
return entries
|
||||
@ -447,5 +447,3 @@ class TrustDomainJoins(object):
|
||||
self.__populate_remote_domain(realm, realm_server, realm_passwd=None)
|
||||
self.local_domain.establish_trust(self.remote_domain, trustdom_passwd)
|
||||
return dict(local=self.local_domain, remote=self.remote_domain)
|
||||
|
||||
|
||||
|
@ -29,11 +29,12 @@ from ipaserver.install.dsinstance import realm_to_serverid
|
||||
from ipaserver.install.bindinstance import get_rr, add_rr, del_rr, \
|
||||
dns_zone_exists
|
||||
from ipalib import errors, api
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
from ipapython import sysrestore
|
||||
from ipapython import ipautil
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython import services as ipaservices
|
||||
from ipapython.dn import DN
|
||||
|
||||
import string
|
||||
import struct
|
||||
@ -103,7 +104,7 @@ class ADTRUSTInstance(service.Service):
|
||||
self.netbios_name = None
|
||||
self.no_msdcs = None
|
||||
self.smbd_user = None
|
||||
self.suffix = None
|
||||
self.suffix = DN()
|
||||
self.ldapi_socket = None
|
||||
self.smb_conf = None
|
||||
self.smb_dn = None
|
||||
@ -129,11 +130,10 @@ class ADTRUSTInstance(service.Service):
|
||||
return "S-1-5-21-%d-%d-%d" % (sub_ids[0], sub_ids[1], sub_ids[2])
|
||||
|
||||
def __add_admin_sids(self):
|
||||
admin_dn = str(DN(('uid', 'admin'), api.env.container_user,
|
||||
self.suffix))
|
||||
admin_group_dn = str(DN(('cn', 'admins'), api.env.container_group,
|
||||
self.suffix))
|
||||
|
||||
admin_dn = DN(('uid', 'admin'), api.env.container_user,
|
||||
self.suffix)
|
||||
admin_group_dn = DN(('cn', 'admins'), api.env.container_group,
|
||||
self.suffix)
|
||||
try:
|
||||
dom_entry = self.admin_conn.getEntry(self.smb_dom_dn, \
|
||||
ldap.SCOPE_BASE)
|
||||
@ -186,10 +186,9 @@ class ADTRUSTInstance(service.Service):
|
||||
"""
|
||||
|
||||
try:
|
||||
res = self.admin_conn.search_s(str(DN(api.env.container_ranges,
|
||||
self.suffix)),
|
||||
ldap.SCOPE_ONELEVEL,
|
||||
"(objectclass=ipaDomainIDRange)")
|
||||
res = self.admin_conn.getList(DN(api.env.container_ranges, self.suffix),
|
||||
ldap.SCOPE_ONELEVEL,
|
||||
"(objectclass=ipaDomainIDRange)")
|
||||
if len(res) != 1:
|
||||
root_logger.critical("Found more than one ID range for the " \
|
||||
"local domain.")
|
||||
@ -230,17 +229,18 @@ class ADTRUSTInstance(service.Service):
|
||||
pass
|
||||
|
||||
for new_dn in (self.trust_dn, \
|
||||
str(DN(('cn', 'ad'), self.trust_dn)), \
|
||||
str(DN(api.env.container_cifsdomains, self.suffix))):
|
||||
DN(('cn', 'ad'), self.trust_dn), \
|
||||
DN(api.env.container_cifsdomains, self.suffix)):
|
||||
try:
|
||||
self.admin_conn.getEntry(new_dn, ldap.SCOPE_BASE)
|
||||
except errors.NotFound:
|
||||
entry = ipaldap.Entry(new_dn)
|
||||
entry.setValues("objectclass", ["nsContainer"])
|
||||
name = new_dn.split('=')[1].split(',')[0]
|
||||
if not name:
|
||||
print "Cannot extract RDN attribute value from [%s]" % \
|
||||
new_dn
|
||||
try:
|
||||
name = new_dn[1].attr
|
||||
except Exception, e:
|
||||
print 'Cannot extract RDN attribute value from "%s": %s' % \
|
||||
(new_dn, e)
|
||||
return
|
||||
entry.setValues("cn", name)
|
||||
self.admin_conn.addEntry(entry)
|
||||
@ -474,16 +474,16 @@ class ADTRUSTInstance(service.Service):
|
||||
|
||||
self.smb_conf = "/etc/samba/smb.conf"
|
||||
|
||||
self.smb_dn = str(DN(('cn', 'adtrust agents'), ('cn', 'sysaccounts'),
|
||||
('cn', 'etc'), self.suffix))
|
||||
self.smb_dn = DN(('cn', 'adtrust agents'), ('cn', 'sysaccounts'),
|
||||
('cn', 'etc'), self.suffix)
|
||||
|
||||
self.trust_dn = str(DN(api.env.container_trusts, self.suffix))
|
||||
self.smb_dom_dn = str(DN(('cn', self.domain_name),
|
||||
api.env.container_cifsdomains, self.suffix))
|
||||
self.trust_dn = DN(api.env.container_trusts, self.suffix)
|
||||
self.smb_dom_dn = DN(('cn', self.domain_name),
|
||||
api.env.container_cifsdomains, self.suffix)
|
||||
self.cifs_principal = "cifs/" + self.fqdn + "@" + self.realm
|
||||
self.cifs_agent = str(DN(('krbprincipalname', self.cifs_principal.lower()),
|
||||
api.env.container_service,
|
||||
self.suffix))
|
||||
self.cifs_agent = DN(('krbprincipalname', self.cifs_principal.lower()),
|
||||
api.env.container_service,
|
||||
self.suffix)
|
||||
self.selinux_booleans = ["samba_portmapper"]
|
||||
|
||||
self.__setup_sub_dict()
|
||||
@ -491,16 +491,13 @@ class ADTRUSTInstance(service.Service):
|
||||
def find_local_id_range(self):
|
||||
self.ldap_connect()
|
||||
|
||||
if self.admin_conn.search_s(str(DN(api.env.container_ranges,
|
||||
self.suffix)),
|
||||
if self.admin_conn.search_s(DN(api.env.container_ranges, self.suffix),
|
||||
ldap.SCOPE_ONELEVEL,
|
||||
"objectclass=ipaDomainIDRange"):
|
||||
return
|
||||
|
||||
try:
|
||||
entry = self.admin_conn.getEntry(str(DN(('cn', 'admins'),
|
||||
api.env.container_group,
|
||||
self.suffix)),
|
||||
entry = self.admin_conn.getEntry(DN(('cn', 'admins'), api.env.container_group, self.suffix),
|
||||
ldap.SCOPE_BASE)
|
||||
except errors.NotFound:
|
||||
raise ValueError("No local ID range and no admins group found.\n" \
|
||||
@ -523,9 +520,9 @@ class ADTRUSTInstance(service.Service):
|
||||
"range.\nAdd local ID range manually and try " \
|
||||
"again!")
|
||||
|
||||
entry = ipaldap.Entry(str(DN(('cn', ('%s_id_range' % self.realm)),
|
||||
api.env.container_ranges,
|
||||
self.suffix)))
|
||||
entry = ipaldap.Entry(DN(('cn', ('%s_id_range' % self.realm)),
|
||||
api.env.container_ranges,
|
||||
self.suffix))
|
||||
entry.setValue('objectclass', 'ipaDomainIDRange')
|
||||
entry.setValue('cn', ('%s_id_range' % self.realm))
|
||||
entry.setValue('ipaBaseID', str(base_id))
|
||||
|
@ -38,6 +38,7 @@ from ipapython.ipa_log_manager import *
|
||||
|
||||
import ipalib
|
||||
from ipalib import api, util, errors
|
||||
from ipapython.dn import DN
|
||||
|
||||
NAMED_CONF = '/etc/named.conf'
|
||||
RESOLV_CONF = '/etc/resolv.conf'
|
||||
@ -166,10 +167,11 @@ def dns_container_exists(fqdn, suffix, dm_password=None, ldapi=False, realm=None
|
||||
Test whether the dns container exists.
|
||||
"""
|
||||
|
||||
def object_exists(dn):
|
||||
def object_exists(dn): # FIXME, this should be a IPAdmin/ldap2 method so it can be shared
|
||||
"""
|
||||
Test whether the given object exists in LDAP.
|
||||
"""
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
conn.search_ext_s(dn, ldap.SCOPE_BASE)
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
@ -177,6 +179,7 @@ def dns_container_exists(fqdn, suffix, dm_password=None, ldapi=False, realm=None
|
||||
else:
|
||||
return True
|
||||
|
||||
assert isinstance(suffix, DN)
|
||||
try:
|
||||
# At install time we may need to use LDAPI to avoid chicken/egg
|
||||
# issues with SSL certs and truting CAs
|
||||
@ -192,7 +195,7 @@ def dns_container_exists(fqdn, suffix, dm_password=None, ldapi=False, realm=None
|
||||
except ldap.SERVER_DOWN:
|
||||
raise RuntimeError('LDAP server on %s is not responding. Is IPA installed?' % fqdn)
|
||||
|
||||
ret = object_exists("cn=dns,%s" % suffix)
|
||||
ret = object_exists(DN(('cn', 'dns'), suffix))
|
||||
conn.unbind_s()
|
||||
|
||||
return ret
|
||||
@ -288,11 +291,14 @@ def add_zone(name, zonemgr=None, dns_backup=None, ns_hostname=None, ns_ip_addres
|
||||
ns_main = ns_hostname
|
||||
ns_replicas = []
|
||||
|
||||
if ns_ip_address is not None:
|
||||
ns_ip_address = unicode(ns_ip_address)
|
||||
|
||||
try:
|
||||
api.Command.dnszone_add(unicode(name),
|
||||
idnssoamname=unicode(ns_main+'.'),
|
||||
idnssoarname=unicode(zonemgr),
|
||||
ip_address=unicode(ns_ip_address),
|
||||
ip_address=ns_ip_address,
|
||||
idnsallowdynupdate=True,
|
||||
idnsupdatepolicy=unicode(update_policy),
|
||||
idnsallowquery=u'any',
|
||||
@ -329,11 +335,14 @@ def add_reverse_zone(zone, ns_hostname=None, ns_ip_address=None,
|
||||
ns_main = ns_hostname
|
||||
ns_replicas = []
|
||||
|
||||
if ns_ip_address is not None:
|
||||
ns_ip_address = unicode(ns_ip_address)
|
||||
|
||||
try:
|
||||
api.Command.dnszone_add(unicode(zone),
|
||||
idnssoamname=unicode(ns_main+'.'),
|
||||
idnsallowdynupdate=True,
|
||||
ip_address=unicode(ns_ip_address),
|
||||
ip_address=ns_ip_address,
|
||||
idnsupdatepolicy=unicode(update_policy),
|
||||
idnsallowquery=u'any',
|
||||
idnsallowtransfer=u'none',)
|
||||
@ -465,6 +474,8 @@ class BindInstance(service.Service):
|
||||
else:
|
||||
self.fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
|
||||
|
||||
suffix = ipautil.dn_attribute_property('_suffix')
|
||||
|
||||
def setup(self, fqdn, ip_address, realm_name, domain_name, forwarders, ntp,
|
||||
reverse_zone, named_user="named", zonemgr=None,
|
||||
zone_refresh=0, persistent_search=True, serial_autoincrement=True):
|
||||
@ -574,7 +585,7 @@ class BindInstance(service.Service):
|
||||
|
||||
if self.ntp:
|
||||
optional_ntp = "\n;ntp server\n"
|
||||
optional_ntp += "_ntp._udp\t\tIN SRV 0 100 123\t%s""" % self.host_in_rr
|
||||
optional_ntp += "_ntp._udp\t\tIN SRV 0 100 123\t%s" % self.host_in_rr
|
||||
else:
|
||||
optional_ntp = ""
|
||||
|
||||
@ -654,7 +665,8 @@ class BindInstance(service.Service):
|
||||
p = self.move_service(dns_principal)
|
||||
if p is None:
|
||||
# the service has already been moved, perhaps we're doing a DNS reinstall
|
||||
dns_principal = "krbprincipalname=%s,cn=services,cn=accounts,%s" % (dns_principal, self.suffix)
|
||||
dns_principal = DN(('krbprincipalname', dns_principal),
|
||||
('cn', 'services'), ('cn', 'accounts'), self.suffix)
|
||||
else:
|
||||
dns_principal = p
|
||||
|
||||
@ -667,9 +679,7 @@ class BindInstance(service.Service):
|
||||
# it can host the memberof attribute, then also add it to the
|
||||
# dnsserver role group, this way the DNS is allowed to perform
|
||||
# DNS Updates
|
||||
dns_group = "cn=DNS Servers,cn=privileges,cn=pbac,%s" % self.suffix
|
||||
if isinstance(dns_principal, unicode):
|
||||
dns_principal = dns_principal.encode('utf-8')
|
||||
dns_group = DN(('cn', 'DNS Servers'), ('cn', 'privileges'), ('cn', 'pbac'), self.suffix)
|
||||
mod = [(ldap.MOD_ADD, 'member', dns_principal)]
|
||||
|
||||
try:
|
||||
|
@ -39,7 +39,7 @@ from ipapython import dogtag
|
||||
from ipapython.certdb import get_ca_nickname
|
||||
from ipapython import certmonger
|
||||
from ipalib import pkcs10, x509
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
import subprocess
|
||||
|
||||
from nss.error import NSPRError
|
||||
@ -243,7 +243,9 @@ class CADSInstance(service.Service):
|
||||
self.suffix = ipautil.realm_to_suffix(self.realm_name)
|
||||
self.__setup_sub_dict()
|
||||
else:
|
||||
self.suffix = None
|
||||
self.suffix = DN()
|
||||
|
||||
subject_base = ipautil.dn_attribute_property('_subject_base')
|
||||
|
||||
def create_instance(self, realm_name, host_name, domain_name,
|
||||
dm_password, pkcs12_info=None, ds_port=DEFAULT_DSPORT,
|
||||
@ -268,7 +270,7 @@ class CADSInstance(service.Service):
|
||||
def __setup_sub_dict(self):
|
||||
server_root = dsinstance.find_server_root()
|
||||
self.sub_dict = dict(FQDN=self.fqdn, SERVERID=self.serverid,
|
||||
PASSWORD=self.dm_password, SUFFIX=self.suffix.lower(),
|
||||
PASSWORD=self.dm_password, SUFFIX=self.suffix,
|
||||
REALM=self.realm_name, USER=PKI_DS_USER,
|
||||
SERVER_ROOT=server_root, DOMAIN=self.domain,
|
||||
TIME=int(time.time()), DSPORT=self.ds_port,
|
||||
@ -342,7 +344,7 @@ class CADSInstance(service.Service):
|
||||
|
||||
def enable_ssl(self):
|
||||
conn = ipaldap.IPAdmin("127.0.0.1", port=DEFAULT_DSPORT)
|
||||
conn.simple_bind_s("cn=directory manager", self.dm_password)
|
||||
conn.simple_bind_s(DN(('cn', 'directory manager')), self.dm_password)
|
||||
|
||||
mod = [(ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"),
|
||||
(ldap.MOD_REPLACE, "nsSSL3Ciphers",
|
||||
@ -350,13 +352,13 @@ class CADSInstance(service.Service):
|
||||
+rsa_des_sha,+rsa_fips_des_sha,+rsa_3des_sha,+rsa_fips_3des_sha,+fortezza,\
|
||||
+fortezza_rc4_128_sha,+fortezza_null,+tls_rsa_export1024_with_rc4_56_sha,\
|
||||
+tls_rsa_export1024_with_des_cbc_sha")]
|
||||
conn.modify_s("cn=encryption,cn=config", mod)
|
||||
conn.modify_s(DN(('cn', 'encryption'), ('cn', 'config')), mod)
|
||||
|
||||
mod = [(ldap.MOD_ADD, "nsslapd-security", "on"),
|
||||
(ldap.MOD_ADD, "nsslapd-secureport", str(DEFAULT_DSPORT+1))]
|
||||
conn.modify_s("cn=config", mod)
|
||||
conn.modify_s(DN(('cn', 'config')), mod)
|
||||
|
||||
entry = ipaldap.Entry("cn=RSA,cn=encryption,cn=config")
|
||||
entry = ipaldap.Entry(DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')))
|
||||
|
||||
entry.setValues("objectclass", "top", "nsEncryptionModule")
|
||||
entry.setValues("cn", "RSA")
|
||||
@ -460,7 +462,7 @@ class CAInstance(service.Service):
|
||||
# will already have been initialized by Apache by the time
|
||||
# mod_python wants to do things.
|
||||
self.canickname = get_ca_nickname(realm)
|
||||
self.basedn = "o=ipaca"
|
||||
self.basedn = DN(('o', 'ipaca'))
|
||||
self.ca_agent_db = tempfile.mkdtemp(prefix = "tmp-")
|
||||
self.ra_agent_db = ra_db
|
||||
self.ra_agent_pwd = self.ra_agent_db + "/pwdfile.txt"
|
||||
@ -506,7 +508,7 @@ class CAInstance(service.Service):
|
||||
self.clone = True
|
||||
self.master_host = master_host
|
||||
if subject_base is None:
|
||||
self.subject_base = "O=%s" % self.realm
|
||||
self.subject_base = DN(('O', self.realm))
|
||||
else:
|
||||
self.subject_base = subject_base
|
||||
|
||||
@ -615,12 +617,12 @@ class CAInstance(service.Service):
|
||||
"-agent_name", "ipa-ca-agent",
|
||||
"-agent_key_size", "2048",
|
||||
"-agent_key_type", "rsa",
|
||||
"-agent_cert_subject", "CN=ipa-ca-agent,%s" % self.subject_base,
|
||||
"-agent_cert_subject", str(DN(('CN', 'ipa-ca-agent'), self.subject_base)),
|
||||
"-ldap_host", self.fqdn,
|
||||
"-ldap_port", str(self.ds_port),
|
||||
"-bind_dn", "cn=Directory Manager",
|
||||
"-bind_password", self.dm_password,
|
||||
"-base_dn", self.basedn,
|
||||
"-base_dn", str(self.basedn),
|
||||
"-db_name", "ipaca",
|
||||
"-key_size", "2048",
|
||||
"-key_type", "rsa",
|
||||
@ -629,11 +631,12 @@ class CAInstance(service.Service):
|
||||
"-backup_pwd", self.admin_password,
|
||||
"-subsystem_name", self.service_name,
|
||||
"-token_name", "internal",
|
||||
"-ca_subsystem_cert_subject_name", "CN=CA Subsystem,%s" % self.subject_base,
|
||||
"-ca_ocsp_cert_subject_name", "CN=OCSP Subsystem,%s" % self.subject_base,
|
||||
"-ca_server_cert_subject_name", "CN=%s,%s" % (self.fqdn, self.subject_base),
|
||||
"-ca_audit_signing_cert_subject_name", "CN=CA Audit,%s" % self.subject_base,
|
||||
"-ca_sign_cert_subject_name", "CN=Certificate Authority,%s" % self.subject_base ]
|
||||
"-ca_subsystem_cert_subject_name", str(DN(('CN', 'CA Subsystem'), self.subject_base)),
|
||||
"-ca_subsystem_cert_subject_name", str(DN(('CN', 'CA Subsystem'), self.subject_base)),
|
||||
"-ca_ocsp_cert_subject_name", str(DN(('CN', 'OCSP Subsystem'), self.subject_base)),
|
||||
"-ca_server_cert_subject_name", str(DN(('CN', self.fqdn), self.subject_base)),
|
||||
"-ca_audit_signing_cert_subject_name", str(DN(('CN', 'CA Audit'), self.subject_base)),
|
||||
"-ca_sign_cert_subject_name", str(DN(('CN', 'Certificate Authority'), self.subject_base)) ]
|
||||
if self.external == 1:
|
||||
args.append("-external")
|
||||
args.append("true")
|
||||
@ -836,13 +839,12 @@ class CAInstance(service.Service):
|
||||
# Create an RA user in the CA LDAP server and add that user to
|
||||
# the appropriate groups so it can issue certificates without
|
||||
# manual intervention.
|
||||
ld = ldap.initialize("ldap://%s" % ipautil.format_netloc(self.fqdn, self.ds_port))
|
||||
ld.protocol_version=ldap.VERSION3
|
||||
ld.simple_bind_s("cn=Directory Manager", self.dm_password)
|
||||
conn = ipaldap.IPAdmin(self.fqdn, self.ds_port)
|
||||
conn.simple_bind_s(DN(('cn', 'Directory Manager')), self.dm_password)
|
||||
|
||||
decoded = base64.b64decode(self.ra_cert)
|
||||
|
||||
entry_dn = "uid=%s,ou=People,%s" % ("ipara", self.basedn)
|
||||
entry_dn = DN(('uid', "ipara"), ('ou', 'People'), self.basedn)
|
||||
entry = [
|
||||
('objectClass', ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'cmsuser']),
|
||||
('uid', "ipara"),
|
||||
@ -851,19 +853,23 @@ class CAInstance(service.Service):
|
||||
('usertype', "agentType"),
|
||||
('userstate', "1"),
|
||||
('userCertificate', decoded),
|
||||
('description', '2;%s;CN=Certificate Authority,%s;CN=IPA RA,%s' % (str(self.requestId), self.subject_base, self.subject_base)),]
|
||||
('description', '2;%s;%s;%s' % \
|
||||
(str(self.requestId),
|
||||
DN(('CN', 'Certificate Authority'), self.subject_base),
|
||||
DN(('CN', 'IPA RA'), self.subject_base))),
|
||||
]
|
||||
|
||||
ld.add_s(entry_dn, entry)
|
||||
conn.add_s(entry_dn, entry)
|
||||
|
||||
dn = "cn=Certificate Manager Agents,ou=groups,%s" % self.basedn
|
||||
dn = DN(('cn', 'Certificate Manager Agents'), ('ou', 'groups'), self.basedn)
|
||||
modlist = [(0, 'uniqueMember', '%s' % entry_dn)]
|
||||
ld.modify_s(dn, modlist)
|
||||
conn.modify_s(dn, modlist)
|
||||
|
||||
dn = "cn=Registration Manager Agents,ou=groups,%s" % self.basedn
|
||||
dn = DN(('cn', 'Registration Manager Agents'), ('ou', 'groups'), self.basedn)
|
||||
modlist = [(0, 'uniqueMember', '%s' % entry_dn)]
|
||||
ld.modify_s(dn, modlist)
|
||||
conn.modify_s(dn, modlist)
|
||||
|
||||
ld.unbind_s()
|
||||
conn.unbind_s()
|
||||
|
||||
def __run_certutil(self, args, database=None, pwd_file=None,stdin=None):
|
||||
if not database:
|
||||
@ -969,7 +975,7 @@ class CAInstance(service.Service):
|
||||
|
||||
# Generate our CSR. The result gets put into stdout
|
||||
try:
|
||||
(stdout, stderr, returncode) = self.__run_certutil(["-R", "-k", "rsa", "-g", "2048", "-s", "CN=IPA RA,%s" % self.subject_base, "-z", noise_name, "-a"])
|
||||
(stdout, stderr, returncode) = self.__run_certutil(["-R", "-k", "rsa", "-g", "2048", "-s", str(DN(('CN', 'IPA RA'), self.subject_base)), "-z", noise_name, "-a"])
|
||||
finally:
|
||||
os.remove(noise_name)
|
||||
|
||||
@ -1071,7 +1077,7 @@ class CAInstance(service.Service):
|
||||
def __set_subject_in_config(self):
|
||||
# dogtag ships with an IPA-specific profile that forces a subject
|
||||
# format. We need to update that template with our base subject
|
||||
if installutils.update_file(IPA_SERVICE_PROFILE, 'OU=pki-ipa, O=IPA', self.subject_base):
|
||||
if installutils.update_file(IPA_SERVICE_PROFILE, 'OU=pki-ipa, O=IPA', str(self.subject_base)):
|
||||
print "Updating subject_base in CA template failed"
|
||||
|
||||
def uninstall(self):
|
||||
|
@ -39,7 +39,7 @@ from ipalib import pkcs10
|
||||
from ConfigParser import RawConfigParser, MissingSectionHeaderError
|
||||
from ipapython import services as ipaservices
|
||||
from ipalib import x509
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
from ipalib.errors import CertificateOperationError
|
||||
|
||||
from nss.error import NSPRError
|
||||
@ -224,8 +224,7 @@ class CertDB(object):
|
||||
self.self_signed_ca = ipa_self_signed()
|
||||
|
||||
if not subject_base:
|
||||
self.subject_base = "O=IPA"
|
||||
self.subject_format = "CN=%%s,%s" % self.subject_base
|
||||
self.subject_base = DN(('O', 'IPA'))
|
||||
|
||||
self.cacert_name = get_ca_nickname(self.realm)
|
||||
self.valid_months = "120"
|
||||
@ -245,6 +244,8 @@ class CertDB(object):
|
||||
else:
|
||||
self.fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
|
||||
|
||||
subject_base = ipautil.dn_attribute_property('_subject_base')
|
||||
|
||||
def __del__(self):
|
||||
if self.reqdir is not None:
|
||||
shutil.rmtree(self.reqdir, ignore_errors=True)
|
||||
@ -381,11 +382,11 @@ class CertDB(object):
|
||||
|
||||
def create_ca_cert(self):
|
||||
os.chdir(self.secdir)
|
||||
subject = "cn=%s Certificate Authority" % self.realm
|
||||
subject = DN(('cn', '%s Certificate Authority' % self.realm))
|
||||
p = subprocess.Popen(["/usr/bin/certutil",
|
||||
"-d", self.secdir,
|
||||
"-S", "-n", self.cacert_name,
|
||||
"-s", subject,
|
||||
"-s", str(subject),
|
||||
"-x",
|
||||
"-t", "CT,,C",
|
||||
"-1",
|
||||
@ -565,7 +566,7 @@ class CertDB(object):
|
||||
if not cdb:
|
||||
cdb = self
|
||||
if subject is None:
|
||||
subject=self.subject_format % hostname
|
||||
subject=DN(('CN', hostname), self.subject_base)
|
||||
self.request_cert(subject)
|
||||
cdb.issue_server_cert(self.certreq_fname, self.certder_fname)
|
||||
self.add_cert(self.certder_fname, nickname)
|
||||
@ -583,7 +584,7 @@ class CertDB(object):
|
||||
if not cdb:
|
||||
cdb = self
|
||||
if subject is None:
|
||||
subject=self.subject_format % hostname
|
||||
subject=DN(('CN', hostname), self.subject_base)
|
||||
self.request_cert(subject)
|
||||
cdb.issue_signing_cert(self.certreq_fname, self.certder_fname)
|
||||
self.add_cert(self.certder_fname, nickname)
|
||||
@ -591,9 +592,10 @@ class CertDB(object):
|
||||
os.unlink(self.certder_fname)
|
||||
|
||||
def request_cert(self, subject, certtype="rsa", keysize="2048"):
|
||||
assert isinstance(subject, DN)
|
||||
self.create_noise_file()
|
||||
self.setup_cert_request()
|
||||
args = ["-R", "-s", subject,
|
||||
args = ["-R", "-s", str(subject),
|
||||
"-o", self.certreq_fname,
|
||||
"-k", certtype,
|
||||
"-g", keysize,
|
||||
@ -1046,19 +1048,19 @@ class CertDB(object):
|
||||
# Prepare a simple cert request
|
||||
req_dict = dict(PASSWORD=self.gen_password(),
|
||||
SUBJBASE=self.subject_base,
|
||||
CERTNAME="CN="+nickname)
|
||||
CERTNAME=DN(('CN', nickname)))
|
||||
req_template = ipautil.SHARE_DIR + reqcfg + ".template"
|
||||
conf = ipautil.template_file(req_template, req_dict)
|
||||
fd = open(reqcfg, "w+")
|
||||
fd.write(conf)
|
||||
fd.close()
|
||||
|
||||
base = self.subject_base.replace(",", "/")
|
||||
esc_subject = "CN=%s/%s" % (nickname, base)
|
||||
base = str(self.subject_base).replace(",", "/")
|
||||
esc_subject = DN(('CN', '%s/%s' % (nickname, base)))
|
||||
|
||||
ipautil.run(["/usr/bin/openssl", "req", "-new",
|
||||
"-config", reqcfg,
|
||||
"-subj", esc_subject,
|
||||
"-subj", str(esc_subject),
|
||||
"-key", key_fname,
|
||||
"-out", "kdc.req"])
|
||||
|
||||
|
@ -36,12 +36,12 @@ import service
|
||||
import installutils
|
||||
import certs
|
||||
import ldap
|
||||
from ldap.dn import escape_dn_chars
|
||||
from ipaserver import ipaldap
|
||||
from ipaserver.install import ldapupdate
|
||||
from ipaserver.install import httpinstance
|
||||
from ipaserver.install import replication
|
||||
from ipalib import util, errors
|
||||
from ipapython.dn import DN
|
||||
from ipaserver.plugins.ldap2 import ldap2
|
||||
|
||||
SERVER_ROOT_64 = "/usr/lib64/dirsrv"
|
||||
@ -177,7 +177,7 @@ class DsInstance(service.Service):
|
||||
self.suffix = ipautil.realm_to_suffix(self.realm_name)
|
||||
self.__setup_sub_dict()
|
||||
else:
|
||||
self.suffix = None
|
||||
self.suffix = DN()
|
||||
|
||||
if fstore:
|
||||
self.fstore = fstore
|
||||
@ -185,6 +185,8 @@ class DsInstance(service.Service):
|
||||
self.fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
|
||||
|
||||
|
||||
subject_base = ipautil.dn_attribute_property('_subject_base')
|
||||
|
||||
def __common_setup(self):
|
||||
|
||||
self.step("creating directory server user", self.__create_ds_user)
|
||||
@ -299,7 +301,7 @@ class DsInstance(service.Service):
|
||||
self.fqdn,
|
||||
self.dm_password)
|
||||
repl.setup_replication(self.master_fqdn,
|
||||
r_binddn="cn=Directory Manager",
|
||||
r_binddn=DN(('cn', 'Directory Manager')),
|
||||
r_bindpw=self.dm_password)
|
||||
self.run_init_memberof = repl.needs_memberof_fixup()
|
||||
|
||||
@ -314,12 +316,12 @@ class DsInstance(service.Service):
|
||||
self.sub_dict = dict(FQDN=self.fqdn, SERVERID=self.serverid,
|
||||
PASSWORD=self.dm_password,
|
||||
RANDOM_PASSWORD=self.generate_random(),
|
||||
SUFFIX=self.suffix.lower(),
|
||||
SUFFIX=self.suffix,
|
||||
REALM=self.realm_name, USER=DS_USER,
|
||||
SERVER_ROOT=server_root, DOMAIN=self.domain,
|
||||
TIME=int(time.time()), IDSTART=self.idstart,
|
||||
IDMAX=self.idmax, HOST=self.fqdn,
|
||||
ESCAPED_SUFFIX= escape_dn_chars(self.suffix.lower()),
|
||||
ESCAPED_SUFFIX=str(self.suffix),
|
||||
GROUP=DS_GROUP,
|
||||
IDRANGE_SIZE=self.idmax-self.idstart+1
|
||||
)
|
||||
@ -445,11 +447,12 @@ class DsInstance(service.Service):
|
||||
|
||||
self._ldap_mod("memberof-task.ldif", self.sub_dict)
|
||||
# Note, keep dn in sync with dn in install/share/memberof-task.ldif
|
||||
dn = "cn=IPA install %s,cn=memberof task,cn=tasks,cn=config" % self.sub_dict["TIME"]
|
||||
dn = DN(('cn', 'IPA install %s' % self.sub_dict["TIME"]), ('cn', 'memberof task'),
|
||||
('cn', 'tasks'), ('cn', 'config'))
|
||||
root_logger.debug("Waiting for memberof task to complete.")
|
||||
conn = ipaldap.IPAdmin("127.0.0.1")
|
||||
if self.dm_password:
|
||||
conn.simple_bind_s("cn=directory manager", self.dm_password)
|
||||
conn.simple_bind_s(DN(('cn', 'directory manager')), self.dm_password)
|
||||
else:
|
||||
conn.do_sasl_gssapi_bind()
|
||||
conn.checkTask(dn, dowait=True)
|
||||
@ -543,7 +546,7 @@ class DsInstance(service.Service):
|
||||
dsdb.create_pin_file()
|
||||
|
||||
conn = ipaldap.IPAdmin("127.0.0.1")
|
||||
conn.simple_bind_s("cn=directory manager", self.dm_password)
|
||||
conn.simple_bind_s(DN(('cn', 'directory manager')), self.dm_password)
|
||||
|
||||
mod = [(ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"),
|
||||
(ldap.MOD_REPLACE, "nsSSL3Ciphers",
|
||||
@ -551,12 +554,12 @@ class DsInstance(service.Service):
|
||||
+rsa_des_sha,+rsa_fips_des_sha,+rsa_3des_sha,+rsa_fips_3des_sha,+fortezza,\
|
||||
+fortezza_rc4_128_sha,+fortezza_null,+tls_rsa_export1024_with_rc4_56_sha,\
|
||||
+tls_rsa_export1024_with_des_cbc_sha")]
|
||||
conn.modify_s("cn=encryption,cn=config", mod)
|
||||
conn.modify_s(DN(('cn', 'encryption'), ('cn', 'config')), mod)
|
||||
|
||||
mod = [(ldap.MOD_ADD, "nsslapd-security", "on")]
|
||||
conn.modify_s("cn=config", mod)
|
||||
conn.modify_s(DN(('cn', 'config')), mod)
|
||||
|
||||
entry = ipaldap.Entry("cn=RSA,cn=encryption,cn=config")
|
||||
entry = ipaldap.Entry(DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')))
|
||||
|
||||
entry.setValues("objectclass", "top", "nsEncryptionModule")
|
||||
entry.setValues("cn", "RSA")
|
||||
@ -612,9 +615,9 @@ class DsInstance(service.Service):
|
||||
os.close(admpwdfd)
|
||||
|
||||
args = ["/usr/bin/ldappasswd", "-h", self.fqdn,
|
||||
"-ZZ", "-x", "-D", "cn=Directory Manager",
|
||||
"-ZZ", "-x", "-D", str(DN(('cn', 'Directory Manager'))),
|
||||
"-y", dmpwdfile, "-T", admpwdfile,
|
||||
"uid=admin,cn=users,cn=accounts,"+self.suffix]
|
||||
str(DN(('uid', 'admin'), ('cn', 'users'), ('cn', 'accounts'), self.suffix))]
|
||||
try:
|
||||
env = { 'LDAPTLS_CACERTDIR':os.path.dirname(CACERT),
|
||||
'LDAPTLS_CACERT':CACERT }
|
||||
@ -801,22 +804,19 @@ class DsInstance(service.Service):
|
||||
def replica_populate(self):
|
||||
self.ldap_connect()
|
||||
|
||||
dn = "cn=default,ou=profile,%s" % self.suffix
|
||||
dn = DN(('cn', 'default'), ('ou', 'profile'), self.suffix)
|
||||
try:
|
||||
ret = self.admin_conn.search_s(dn, ldap.SCOPE_BASE,
|
||||
'(objectclass=*)')[0]
|
||||
srvlist = ret.data.get('defaultServerList')
|
||||
if len(srvlist) > 0:
|
||||
srvlist = srvlist[0].split()
|
||||
entry = self.admin_conn.getEntry(dn, ldap.SCOPE_BASE, '(objectclass=*)')
|
||||
srvlist = entry.getValue('defaultServerList', '')
|
||||
srvlist = srvlist.split()
|
||||
if not self.fqdn in srvlist:
|
||||
srvlist.append(self.fqdn)
|
||||
attr = ' '.join(srvlist)
|
||||
mod = [(ldap.MOD_REPLACE, 'defaultServerList', attr)]
|
||||
self.admin_conn.modify_s(dn, mod)
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
except errors.NotFound:
|
||||
pass
|
||||
except ldap.TYPE_OR_VALUE_EXISTS:
|
||||
pass
|
||||
|
||||
self.ldap_disconnect()
|
||||
|
||||
|
@ -57,6 +57,8 @@ class HTTPInstance(service.Service):
|
||||
else:
|
||||
self.fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
|
||||
|
||||
subject_base = ipautil.dn_attribute_property('_subject_base')
|
||||
|
||||
def create_instance(self, realm, fqdn, domain_name, dm_password=None, autoconfig=True, pkcs12_info=None, self_signed_ca=False, subject_base=None, auto_redirect=True):
|
||||
self.fqdn = fqdn
|
||||
self.realm = realm
|
||||
|
@ -44,6 +44,7 @@ from ipapython.ipa_log_manager import *
|
||||
from ipalib.util import validate_hostname
|
||||
from ipapython import config
|
||||
from ipalib import errors
|
||||
from ipapython.dn import DN
|
||||
|
||||
# Used to determine install status
|
||||
IPA_MODULES = ['httpd', 'kadmin', 'dirsrv', 'pki-cad', 'pkids', 'install', 'krb5kdc', 'ntpd', 'named', 'ipa_memcached']
|
||||
@ -71,9 +72,11 @@ class ReplicaConfig:
|
||||
self.dirman_password = ""
|
||||
self.host_name = ""
|
||||
self.dir = ""
|
||||
self.subject_base = ""
|
||||
self.subject_base = None
|
||||
self.setup_ca = False
|
||||
|
||||
subject_base = ipautil.dn_attribute_property('_subject_base')
|
||||
|
||||
def get_fqdn():
|
||||
fqdn = ""
|
||||
try:
|
||||
|
@ -150,6 +150,8 @@ class LDAPUpdater_Upgrade(LDAPUpdater):
|
||||
|
||||
|
||||
class LDAPUpdater_NonUpgrade(LDAPUpdater):
|
||||
log_file_name = '/var/log/ipaupgrade.log'
|
||||
|
||||
def validate_options(self):
|
||||
super(LDAPUpdater_NonUpgrade, self).validate_options()
|
||||
options = self.options
|
||||
|
@ -33,6 +33,7 @@ from ipapython import services as ipaservices
|
||||
from ipalib import util
|
||||
from ipalib import errors
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
|
||||
from ipaserver import ipaldap
|
||||
from ipaserver.install import replication
|
||||
@ -84,6 +85,7 @@ class KrbInstance(service.Service):
|
||||
self.admin_password = None
|
||||
self.master_password = None
|
||||
self.suffix = None
|
||||
self.subject_base = None
|
||||
self.kdc_password = None
|
||||
self.sub_dict = None
|
||||
self.pkcs12_info = None
|
||||
@ -94,8 +96,11 @@ class KrbInstance(service.Service):
|
||||
else:
|
||||
self.fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
|
||||
|
||||
suffix = ipautil.dn_attribute_property('_suffix')
|
||||
subject_base = ipautil.dn_attribute_property('_subject_base')
|
||||
|
||||
def get_realm_suffix(self):
|
||||
return "cn=%s,cn=kerberos,%s" % (self.realm, self.suffix)
|
||||
return DN(('cn', self.realm), ('cn', 'kerberos'), self.suffix)
|
||||
|
||||
def move_service_to_host(self, principal):
|
||||
"""
|
||||
@ -103,12 +108,12 @@ class KrbInstance(service.Service):
|
||||
cn=kerberos to reside under the host entry.
|
||||
"""
|
||||
|
||||
service_dn = "krbprincipalname=%s,%s" % (principal, self.get_realm_suffix())
|
||||
service_dn = DN(('krbprincipalname', principal), self.get_realm_suffix())
|
||||
service_entry = self.admin_conn.getEntry(service_dn, ldap.SCOPE_BASE)
|
||||
self.admin_conn.deleteEntry(service_dn)
|
||||
|
||||
# Create a host entry for this master
|
||||
host_dn = "fqdn=%s,cn=computers,cn=accounts,%s" % (self.fqdn, self.suffix)
|
||||
host_dn = DN(('fqdn', self.fqdn), ('cn', 'computers'), ('cn', 'accounts'), self.suffix)
|
||||
host_entry = ipaldap.Entry(host_dn)
|
||||
host_entry.setValues('objectclass', ['top', 'ipaobject', 'nshost', 'ipahost', 'ipaservice', 'pkiuser', 'krbprincipalaux', 'krbprincipal', 'krbticketpolicyaux', 'ipasshhost'])
|
||||
host_entry.setValues('krbextradata', service_entry.getValues('krbextradata'))
|
||||
@ -251,7 +256,7 @@ class KrbInstance(service.Service):
|
||||
# they may conflict.
|
||||
|
||||
try:
|
||||
res = self.admin_conn.search_s("cn=mapping,cn=sasl,cn=config",
|
||||
res = self.admin_conn.search_s(DN(('cn', 'mapping'), ('cn', 'sasl'), ('cn', 'config')),
|
||||
ldap.SCOPE_ONELEVEL,
|
||||
"(objectclass=nsSaslMapping)")
|
||||
for r in res:
|
||||
@ -264,7 +269,7 @@ class KrbInstance(service.Service):
|
||||
root_logger.critical("Error while enumerating SASL mappings %s" % str(e))
|
||||
raise e
|
||||
|
||||
entry = ipaldap.Entry("cn=Full Principal,cn=mapping,cn=sasl,cn=config")
|
||||
entry = ipaldap.Entry(DN(('cn', 'Full Principal'), ('cn', 'mapping'), ('cn', 'sasl'), ('cn', 'config')))
|
||||
entry.setValues("objectclass", "top", "nsSaslMapping")
|
||||
entry.setValues("cn", "Full Principal")
|
||||
entry.setValues("nsSaslMapRegexString", '\(.*\)@\(.*\)')
|
||||
@ -277,7 +282,7 @@ class KrbInstance(service.Service):
|
||||
root_logger.critical("failed to add Full Principal Sasl mapping")
|
||||
raise e
|
||||
|
||||
entry = ipaldap.Entry("cn=Name Only,cn=mapping,cn=sasl,cn=config")
|
||||
entry = ipaldap.Entry(DN(('cn', 'Name Only'), ('cn', 'mapping'), ('cn', 'sasl'), ('cn', 'config')))
|
||||
entry.setValues("objectclass", "top", "nsSaslMapping")
|
||||
entry.setValues("cn", "Name Only")
|
||||
entry.setValues("nsSaslMapRegexString", '^[^:@]+$')
|
||||
@ -358,7 +363,7 @@ class KrbInstance(service.Service):
|
||||
root_logger.critical("Could not find master key in DS")
|
||||
raise e
|
||||
|
||||
krbMKey = pyasn1.codec.ber.decoder.decode(entry.krbmkey)
|
||||
krbMKey = pyasn1.codec.ber.decoder.decode(entry.getValue('krbmkey'))
|
||||
keytype = int(krbMKey[0][1][0])
|
||||
keydata = str(krbMKey[0][1][1])
|
||||
|
||||
@ -431,7 +436,7 @@ class KrbInstance(service.Service):
|
||||
|
||||
# Create the special anonymous principal
|
||||
installutils.kadmin_addprinc(princ_realm)
|
||||
dn = "krbprincipalname=%s,%s" % (princ_realm, self.get_realm_suffix())
|
||||
dn = DN(('krbprincipalname', princ_realm), self.get_realm_suffix())
|
||||
self.admin_conn.inactivateEntry(dn, False)
|
||||
|
||||
def __convert_to_gssapi_replication(self):
|
||||
@ -439,7 +444,7 @@ class KrbInstance(service.Service):
|
||||
self.fqdn,
|
||||
self.dm_password)
|
||||
repl.convert_to_gssapi_replication(self.master_fqdn,
|
||||
r_binddn="cn=Directory Manager",
|
||||
r_binddn=DN(('cn', 'Directory Manager')),
|
||||
r_bindpw=self.dm_password)
|
||||
|
||||
def uninstall(self):
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,7 @@
|
||||
from ipaserver.install.plugins import MIDDLE
|
||||
from ipaserver.install.plugins.baseupdate import PostUpdate
|
||||
from ipalib import api, errors
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
from ipapython.ipa_log_manager import *
|
||||
|
||||
DEFAULT_ID_RANGE_SIZE = 200000
|
||||
@ -34,7 +34,7 @@ class update_default_range(PostUpdate):
|
||||
def execute(self, **options):
|
||||
ldap = self.obj.backend
|
||||
|
||||
dn = str(DN(api.env.container_ranges, api.env.basedn))
|
||||
dn = DN(api.env.container_ranges, api.env.basedn)
|
||||
search_filter = "objectclass=ipaDomainIDRange"
|
||||
try:
|
||||
(entries, truncated) = ldap.find_entries(search_filter, [], dn)
|
||||
@ -44,7 +44,7 @@ class update_default_range(PostUpdate):
|
||||
root_logger.debug("default_range: ipaDomainIDRange entry found, skip plugin")
|
||||
return (False, False, [])
|
||||
|
||||
dn = str(DN(('cn', 'admins'), api.env.container_group, api.env.basedn))
|
||||
dn = DN(('cn', 'admins'), api.env.container_group, api.env.basedn)
|
||||
try:
|
||||
(dn, admins_entry) = ldap.get_entry(dn, ['gidnumber'])
|
||||
except errors.NotFound:
|
||||
@ -65,12 +65,10 @@ class update_default_range(PostUpdate):
|
||||
]
|
||||
|
||||
updates = {}
|
||||
dn = str(DN(('cn', '%s_id_range' % api.env.realm),
|
||||
api.env.container_ranges, api.env.basedn))
|
||||
dn = DN(('cn', '%s_id_range' % api.env.realm),
|
||||
api.env.container_ranges, api.env.basedn)
|
||||
|
||||
# make sure everything is str or otherwise python-ldap would complain
|
||||
range_entry = map(str, range_entry)
|
||||
updates[dn] = {'dn' : dn, 'default' : range_entry}
|
||||
updates[dn] = {'dn': dn, 'default': range_entry}
|
||||
|
||||
# Default range entry has a hard-coded range size to 200000 which is
|
||||
# a default range size in ipa-server-install. This could cause issues
|
||||
@ -78,7 +76,7 @@ class update_default_range(PostUpdate):
|
||||
# bigger range (option --idmax).
|
||||
# We should make our best to check if this is the case and provide
|
||||
# user with an information how to fix it.
|
||||
dn = str(DN(api.env.container_dna_posix_ids, api.env.basedn))
|
||||
dn = DN(api.env.container_dna_posix_ids, api.env.basedn)
|
||||
search_filter = "objectclass=dnaSharedConfig"
|
||||
attrs = ['dnaHostname', 'dnaRemainingValues']
|
||||
try:
|
||||
|
@ -21,7 +21,7 @@ from ipaserver.install.plugins import MIDDLE
|
||||
from ipaserver.install.plugins.baseupdate import PostUpdate
|
||||
from ipaserver.install.plugins import baseupdate
|
||||
from ipalib import api, errors, util
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
from ipalib.plugins.dns import dns_container_exists
|
||||
from ipapython.ipa_log_manager import *
|
||||
|
||||
@ -89,31 +89,29 @@ class update_dns_permissions(PostUpdate):
|
||||
entries otherwise.
|
||||
"""
|
||||
|
||||
_write_dns_perm_dn = DN('cn=Write DNS Configuration',
|
||||
api.env.container_permission,
|
||||
api.env.basedn)
|
||||
_write_dns_perm_dn = DN(('cn', 'Write DNS Configuration'),
|
||||
api.env.container_permission, api.env.basedn)
|
||||
_write_dns_perm_entry = ['objectClass:groupofnames',
|
||||
'objectClass:top',
|
||||
'cn:Write DNS Configuration',
|
||||
'description:Write DNS Configuration',
|
||||
'member:cn=DNS Administrators,cn=privileges,cn=pbac,%s' \
|
||||
% api.env.basedn,
|
||||
'member:cn=DNS Servers,cn=privileges,cn=pbac,%s' \
|
||||
% api.env.basedn]
|
||||
'member:%s' % DN(('cn', 'DNS Administrators'), ('cn', 'privileges'), ('cn', 'pbac'),
|
||||
api.env.basedn),
|
||||
'member:%s' % DN(('cn', 'DNS Servers'), ('cn', 'privileges'), ('cn', 'pbac'),
|
||||
api.env.basedn)]
|
||||
|
||||
_read_dns_perm_dn = DN('cn=Read DNS Entries',
|
||||
api.env.container_permission,
|
||||
api.env.basedn)
|
||||
_read_dns_perm_dn = DN(('cn', 'Read DNS Entries'),
|
||||
api.env.container_permission, api.env.basedn)
|
||||
_read_dns_perm_entry = ['objectClass:top',
|
||||
'objectClass:groupofnames',
|
||||
'objectClass:ipapermission',
|
||||
'cn:Read DNS Entries',
|
||||
'description:Read DNS entries',
|
||||
'ipapermissiontype:SYSTEM',
|
||||
'member:cn=DNS Administrators,cn=privileges,cn=pbac,%s' \
|
||||
% api.env.basedn,
|
||||
'member:cn=DNS Servers,cn=privileges,cn=pbac,%s' \
|
||||
% api.env.basedn,]
|
||||
'member:%s' % DN(('cn', 'DNS Administrators'), ('cn', 'privileges'), ('cn', 'pbac'),
|
||||
api.env.basedn),
|
||||
'member:%s' % DN(('cn', 'DNS Servers'), ('cn', 'privileges'), ('cn', 'pbac'),
|
||||
api.env.basedn),]
|
||||
|
||||
_write_dns_aci_dn = DN(api.env.basedn)
|
||||
_write_dns_aci_entry = ['add:aci:\'(targetattr = "idnsforwardpolicy || idnsforwarders || idnsallowsyncptr || idnszonerefresh || idnspersistentsearch")(target = "ldap:///cn=dns,%(realm)s")(version 3.0;acl "permission:Write DNS Configuration";allow (write) groupdn = "ldap:///cn=Write DNS Configuration,cn=permissions,cn=pbac,%(realm)s";)\'' % dict(realm=api.env.basedn)]
|
||||
@ -135,10 +133,7 @@ class update_dns_permissions(PostUpdate):
|
||||
(self._write_dns_aci_dn, 'updates', self._write_dns_aci_entry),
|
||||
(self._read_dns_aci_dn, 'updates', self._read_dns_aci_entry)):
|
||||
|
||||
dn = str(dn)
|
||||
# make sure everything is str or otherwise python-ldap would complain
|
||||
entry = map(str, entry)
|
||||
dnsupdates[dn] = {'dn' : dn, container : entry}
|
||||
dnsupdates[dn] = {'dn': dn, container: entry}
|
||||
|
||||
return (False, True, [dnsupdates])
|
||||
|
||||
@ -161,9 +156,9 @@ class update_dns_limits(PostUpdate):
|
||||
return (False, False, [])
|
||||
|
||||
dns_principal = 'DNS/%s@%s' % (self.env.host, self.env.realm)
|
||||
dns_service_dn = str(DN(('krbprincipalname', dns_principal),
|
||||
self.env.container_service,
|
||||
self.env.basedn))
|
||||
dns_service_dn = DN(('krbprincipalname', dns_principal),
|
||||
self.env.container_service,
|
||||
self.env.basedn)
|
||||
|
||||
try:
|
||||
(dn, entry) = ldap.get_entry(dns_service_dn, self.limit_attributes)
|
||||
|
@ -44,7 +44,7 @@ class update_replica_exclude_attribute_list(PreUpdate):
|
||||
entries = repl.find_replication_agreements()
|
||||
self.log.debug("Found %d agreement(s)", len(entries))
|
||||
for replica in entries:
|
||||
self.log.debug(replica.description)
|
||||
self.log.debug(replica.getValue('description'))
|
||||
attrlist = replica.getValue('nsDS5ReplicatedAttributeList')
|
||||
if attrlist is None:
|
||||
self.log.debug("Adding nsDS5ReplicatedAttributeList and nsDS5ReplicatedAttributeListTotal")
|
||||
@ -68,7 +68,7 @@ class update_replica_exclude_attribute_list(PreUpdate):
|
||||
self.log.debug("Attribute list needs updating")
|
||||
current = replica.toDict()
|
||||
replica.setValue('nsDS5ReplicatedAttributeList',
|
||||
replica.nsDS5ReplicatedAttributeList + ' %s' % ' '.join(missing))
|
||||
replica.getValue('nsDS5ReplicatedAttributeList') + ' %s' % ' '.join(missing))
|
||||
try:
|
||||
repl.conn.updateEntry(replica.dn, current, replica.toDict())
|
||||
self.log.debug("Updated")
|
||||
|
@ -24,6 +24,7 @@ from ipalib.frontend import Updater
|
||||
from ipaserver.install.plugins import baseupdate
|
||||
from ipalib import api, errors
|
||||
from ipapython import ipautil
|
||||
from ipapython.dn import DN, EditableDN
|
||||
import ldap as _ldap
|
||||
|
||||
def entry_to_update(entry):
|
||||
@ -44,67 +45,99 @@ def entry_to_update(entry):
|
||||
|
||||
return update
|
||||
|
||||
def generate_update(ldap, deletes=False):
|
||||
"""
|
||||
We need to separate the deletes that need to happen from the
|
||||
new entries that need to be added.
|
||||
"""
|
||||
suffix = ipautil.realm_to_suffix(api.env.realm)
|
||||
searchfilter = '(objectclass=*)'
|
||||
definitions_managed_entries = []
|
||||
old_template_container = 'cn=etc,%s' % suffix
|
||||
old_definition_container = 'cn=managed entries,cn=plugins,cn=config'
|
||||
new = 'cn=Managed Entries,cn=etc,%s' % suffix
|
||||
sub = ['cn=Definitions,', 'cn=Templates,']
|
||||
new_managed_entries = []
|
||||
old_templates = []
|
||||
template = None
|
||||
restart = False
|
||||
class GenerateUpdateMixin(object):
|
||||
def generate_update(self, deletes=False):
|
||||
"""
|
||||
We need to separate the deletes that need to happen from the
|
||||
new entries that need to be added.
|
||||
"""
|
||||
ldap = self.obj.backend
|
||||
|
||||
# If the old entries don't exist the server has already been updated.
|
||||
try:
|
||||
(definitions_managed_entries, truncated) = ldap.find_entries(
|
||||
searchfilter, ['*'], old_definition_container, _ldap.SCOPE_ONELEVEL, normalize=False
|
||||
)
|
||||
except errors.NotFound, e:
|
||||
return (False, new_managed_entries)
|
||||
suffix = ipautil.realm_to_suffix(api.env.realm)
|
||||
searchfilter = '(objectclass=*)'
|
||||
definitions_managed_entries = []
|
||||
|
||||
for entry in definitions_managed_entries:
|
||||
new_definition = {}
|
||||
definition_managed_entry_updates = {}
|
||||
if deletes:
|
||||
old_definition = {'dn': str(entry[0]), 'deleteentry': ['dn: %s' % str(entry[0])]}
|
||||
old_template = str(entry[1]['managedtemplate'][0])
|
||||
definition_managed_entry_updates[old_definition['dn']] = old_definition
|
||||
old_templates.append(old_template)
|
||||
else:
|
||||
entry[1]['managedtemplate'] = str(entry[1]['managedtemplate'][0].replace(old_template_container, sub[1] + new))
|
||||
new_definition['dn'] = str(entry[0].replace(old_definition_container, sub[0] + new))
|
||||
new_definition['default'] = entry_to_update(entry[1])
|
||||
definition_managed_entry_updates[new_definition['dn']] = new_definition
|
||||
new_managed_entries.append(definition_managed_entry_updates)
|
||||
for old_template in old_templates: # Only happens when deletes is True
|
||||
old_template_container = DN(('cn', 'etc'), suffix)
|
||||
new_template_container = DN(('cn', 'Templates'), ('cn', 'Managed Entries'), ('cn', 'etc'), suffix)
|
||||
|
||||
old_definition_container = DN(('cn', 'managed entries'), ('cn', 'plugins'), ('cn', 'config'), suffix)
|
||||
new_definition_container = DN(('cn', 'Definitions'), ('cn', 'Managed Entries'), ('cn', 'etc'), suffix)
|
||||
|
||||
definitions_dn = DN(('cn', 'Definitions'))
|
||||
update_list = []
|
||||
restart = False
|
||||
|
||||
# If the old entries don't exist the server has already been updated.
|
||||
try:
|
||||
(dn, template) = ldap.get_entry(old_template, ['*'], normalize=False)
|
||||
dn = str(dn)
|
||||
new_template = {}
|
||||
template_managed_entry_updates = {}
|
||||
old_template = {'dn': dn, 'deleteentry': ['dn: %s' % dn]}
|
||||
new_template['dn'] = str(dn.replace(old_template_container, sub[1] + new))
|
||||
new_template['default'] = entry_to_update(template)
|
||||
template_managed_entry_updates[new_template['dn']] = new_template
|
||||
template_managed_entry_updates[old_template['dn']] = old_template
|
||||
new_managed_entries.append(template_managed_entry_updates)
|
||||
(definitions_managed_entries, truncated) = ldap.find_entries(
|
||||
searchfilter, ['*'], old_definition_container, _ldap.SCOPE_ONELEVEL, normalize=False
|
||||
)
|
||||
except errors.NotFound, e:
|
||||
pass
|
||||
return (False, update_list)
|
||||
|
||||
if len(new_managed_entries) > 0:
|
||||
restart = True
|
||||
new_managed_entries.sort(reverse=True)
|
||||
for entry in definitions_managed_entries:
|
||||
assert isinstance(entry.dn, DN)
|
||||
if deletes:
|
||||
old_dn = entry.data['managedtemplate'][0]
|
||||
assert isinstance(old_dn, DN)
|
||||
try:
|
||||
(old_dn, entry) = ldap.get_entry(old_dn, ['*'], normalize=False)
|
||||
except errors.NotFound, e:
|
||||
pass
|
||||
else:
|
||||
# Compute the new dn by replacing the old container with the new container
|
||||
new_dn = EditableDN(old_dn)
|
||||
if new_dn.replace(old_template_container, new_template_container) != 1:
|
||||
self.error("unable to replace '%s' with '%s' in '%s'",
|
||||
old_template_container, new_template_container, old_dn)
|
||||
continue
|
||||
|
||||
return (restart, new_managed_entries)
|
||||
new_dn = DN(new_dn)
|
||||
|
||||
class update_managed_post_first(PreUpdate):
|
||||
# The old attributes become defaults for the new entry
|
||||
new_update = {'dn': new_dn,
|
||||
'default': entry_to_update(entry)}
|
||||
|
||||
# Delete the old entry
|
||||
old_update = {'dn': old_dn, 'deleteentry': None}
|
||||
|
||||
# Add the delete and replacement updates to the list of all updates
|
||||
update_list.append({old_dn: old_update, new_dn: new_update})
|
||||
|
||||
else:
|
||||
# Update the template dn by replacing the old containter with the new container
|
||||
old_dn = entry.data['managedtemplate'][0]
|
||||
new_dn = EditableDN(old_dn)
|
||||
if new_dn.replace(old_template_container, new_template_container) != 1:
|
||||
self.error("unable to replace '%s' with '%s' in '%s'",
|
||||
old_template_container, new_template_container, old_dn)
|
||||
continue
|
||||
new_dn = DN(new_dn)
|
||||
entry.data['managedtemplate'] = new_dn
|
||||
|
||||
# Edit the dn, then convert it back to an immutable DN
|
||||
old_dn = entry.dn
|
||||
new_dn = EditableDN(old_dn)
|
||||
if new_dn.replace(old_definition_container, new_definition_container) != 1:
|
||||
self.error("unable to replace '%s' with '%s' in '%s'",
|
||||
old_definition_container, new_definition_container, old_dn)
|
||||
continue
|
||||
new_dn = DN(new_dn)
|
||||
|
||||
# The old attributes become defaults for the new entry
|
||||
new_update = {'dn': new_dn,
|
||||
'default': entry_to_update(entry.data)}
|
||||
|
||||
# Add the replacement update to the collection of all updates
|
||||
update_list.append({new_dn: new_update})
|
||||
|
||||
if len(update_list) > 0:
|
||||
restart = True
|
||||
update_list.sort(reverse=True)
|
||||
|
||||
return (restart, update_list)
|
||||
|
||||
class update_managed_post_first(PreUpdate, GenerateUpdateMixin):
|
||||
"""
|
||||
Update managed entries
|
||||
"""
|
||||
@ -112,21 +145,21 @@ class update_managed_post_first(PreUpdate):
|
||||
|
||||
def execute(self, **options):
|
||||
# Never need to restart with the pre-update changes
|
||||
(ignore, new_managed_entries) = generate_update(self.obj.backend, False)
|
||||
(ignore, update_list) = self.generate_update(False)
|
||||
|
||||
return (False, True, new_managed_entries)
|
||||
return (False, True, update_list)
|
||||
|
||||
api.register(update_managed_post_first)
|
||||
|
||||
class update_managed_post(PostUpdate):
|
||||
class update_managed_post(PostUpdate, GenerateUpdateMixin):
|
||||
"""
|
||||
Update managed entries
|
||||
"""
|
||||
order=LAST
|
||||
|
||||
def execute(self, **options):
|
||||
(restart, new_managed_entries) = generate_update(self.obj.backend, True)
|
||||
(restart, update_list) = self.generate_update(True)
|
||||
|
||||
return (restart, True, new_managed_entries)
|
||||
return (restart, True, update_list)
|
||||
|
||||
api.register(update_managed_post)
|
||||
|
@ -25,6 +25,7 @@ from ipaserver.install.ldapupdate import LDAPUpdate
|
||||
from ipapython.ipautil import wait_for_open_socket
|
||||
from ipalib import api
|
||||
from ipalib import backend
|
||||
from ipapython.dn import DN
|
||||
import ldap as _ldap
|
||||
|
||||
class updateclient(backend.Executioner):
|
||||
@ -44,7 +45,7 @@ class updateclient(backend.Executioner):
|
||||
|
||||
updates is a dictionary keyed on dn. The value of an update is a
|
||||
dictionary with the following possible values:
|
||||
- dn: str, duplicate of the key
|
||||
- dn: DN, equal to the dn attribute
|
||||
- updates: list of updates against the dn
|
||||
- default: list of the default entry to be added if it doesn't
|
||||
exist
|
||||
@ -103,7 +104,7 @@ class updateclient(backend.Executioner):
|
||||
autobind = False
|
||||
else:
|
||||
autobind = True
|
||||
self.Backend.ldap2.connect(bind_dn='cn=Directory Manager', bind_pw=dm_password, autobind=autobind)
|
||||
self.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=dm_password, autobind=autobind)
|
||||
|
||||
def order(self, updatetype):
|
||||
"""Return plugins of the given updatetype in sorted order.
|
||||
@ -125,22 +126,12 @@ class updateclient(backend.Executioner):
|
||||
(restart, apply_now, res) = self.run(update.name, **kw)
|
||||
if restart:
|
||||
self.restart(dm_password, live_run)
|
||||
dn_list = {}
|
||||
for upd in res:
|
||||
for dn in upd:
|
||||
dn_explode = _ldap.explode_dn(dn.lower())
|
||||
l = len(dn_explode)
|
||||
if dn_list.get(l):
|
||||
if dn not in dn_list[l]:
|
||||
dn_list[l].append(dn)
|
||||
else:
|
||||
dn_list[l] = [dn]
|
||||
updates = {}
|
||||
for entry in res:
|
||||
updates.update(entry)
|
||||
|
||||
if apply_now:
|
||||
ld.update_from_dict(dn_list, updates)
|
||||
updates = {}
|
||||
for entry in res:
|
||||
updates.update(entry)
|
||||
ld.update_from_dict(updates)
|
||||
elif res:
|
||||
result.extend(res)
|
||||
|
||||
|
@ -28,17 +28,16 @@ from ipapython import services as ipaservices
|
||||
from ldap import modlist
|
||||
from ipalib import api, util, errors
|
||||
from ipapython import ipautil
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
|
||||
DIRMAN_CN = "cn=directory manager"
|
||||
CACERT = "/etc/ipa/ca.crt"
|
||||
# the default container used by AD for user entries
|
||||
WIN_USER_CONTAINER = "cn=Users"
|
||||
WIN_USER_CONTAINER = DN(('cn', 'Users'))
|
||||
# the default container used by IPA for user entries
|
||||
IPA_USER_CONTAINER = "cn=users,cn=accounts"
|
||||
IPA_USER_CONTAINER = DN(('cn', 'users'), ('cn', 'accounts'))
|
||||
PORT = 636
|
||||
TIMEOUT = 120
|
||||
REPL_MAN_DN = "cn=replication manager,cn=config"
|
||||
REPL_MAN_DN = DN(('cn', 'replication manager'), ('cn', 'config'))
|
||||
|
||||
IPA_REPLICA = 1
|
||||
WINSYNC = 2
|
||||
@ -94,9 +93,10 @@ def enable_replication_version_checking(hostname, realm, dirman_passwd):
|
||||
conn.do_simple_bind(bindpw=dirman_passwd)
|
||||
else:
|
||||
conn.do_sasl_gssapi_bind()
|
||||
entry = conn.search_s('cn=IPA Version Replication,cn=plugins,cn=config', ldap.SCOPE_BASE, 'objectclass=*')
|
||||
if entry[0].getValue('nsslapd-pluginenabled') == 'off':
|
||||
conn.modify_s(entry[0].dn, [(ldap.MOD_REPLACE, 'nsslapd-pluginenabled', 'on')])
|
||||
entry = conn.getEntry(DN(('cn', 'IPA Version Replication'), ('cn', 'plugins'), ('cn', 'config')),
|
||||
ldap.SCOPE_BASE, 'objectclass=*')
|
||||
if entry.getValue('nsslapd-pluginenabled') == 'off':
|
||||
conn.modify_s(entry.dn, [(ldap.MOD_REPLACE, 'nsslapd-pluginenabled', 'on')])
|
||||
conn.unbind()
|
||||
serverid = "-".join(realm.split("."))
|
||||
ipaservices.knownservices.dirsrv.restart(instance_name=serverid)
|
||||
@ -112,8 +112,7 @@ class ReplicationManager(object):
|
||||
self.dirman_passwd = dirman_passwd
|
||||
self.realm = realm
|
||||
self.starttls = starttls
|
||||
tmp = ipautil.realm_to_suffix(realm)
|
||||
self.suffix = str(DN(tmp)).lower()
|
||||
self.suffix = ipautil.realm_to_suffix(realm)
|
||||
self.need_memberof_fixup = False
|
||||
|
||||
# The caller is allowed to pass in an existing IPAdmin connection.
|
||||
@ -150,25 +149,28 @@ class ReplicationManager(object):
|
||||
"""
|
||||
# First see if there is already one set
|
||||
dn = self.replica_dn()
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
replica = conn.search_s(dn, ldap.SCOPE_BASE, "objectclass=*")[0]
|
||||
replica = conn.getEntry(dn, ldap.SCOPE_BASE, "objectclass=*")
|
||||
except errors.NotFound:
|
||||
pass
|
||||
else:
|
||||
if replica.getValue('nsDS5ReplicaId'):
|
||||
return int(replica.getValue('nsDS5ReplicaId'))
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
pass
|
||||
|
||||
# Ok, either the entry doesn't exist or the attribute isn't set
|
||||
# so get it from the other master
|
||||
retval = -1
|
||||
dn = str(DN(('cn','replication'),('cn','etc'), self.suffix))
|
||||
dn = DN(('cn','replication'),('cn','etc'), self.suffix)
|
||||
try:
|
||||
replica = master_conn.search_s(dn, ldap.SCOPE_BASE, "objectclass=*")[0]
|
||||
if not replica.getValue('nsDS5ReplicaId'):
|
||||
root_logger.debug("Unable to retrieve nsDS5ReplicaId from remote server")
|
||||
raise RuntimeError("Unable to retrieve nsDS5ReplicaId from remote server")
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
replica = master_conn.getEntry(dn, ldap.SCOPE_BASE, "objectclass=*")
|
||||
except errors.NotFound:
|
||||
root_logger.debug("Unable to retrieve nsDS5ReplicaId from remote server")
|
||||
raise
|
||||
else:
|
||||
if replica.getValue('nsDS5ReplicaId') is None:
|
||||
root_logger.debug("Unable to retrieve nsDS5ReplicaId from remote server")
|
||||
raise RuntimeError("Unable to retrieve nsDS5ReplicaId from remote server")
|
||||
|
||||
# Now update the value on the master
|
||||
retval = int(replica.getValue('nsDS5ReplicaId'))
|
||||
@ -195,8 +197,9 @@ class ReplicationManager(object):
|
||||
"""
|
||||
filt = "(|(objectclass=nsDSWindowsReplicationAgreement)(objectclass=nsds5ReplicationAgreement))"
|
||||
try:
|
||||
ents = self.conn.search_s("cn=mapping tree,cn=config", ldap.SCOPE_SUBTREE, filt)
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
ents = self.conn.getList(DN(('cn', 'mapping tree'), ('cn', 'config')),
|
||||
ldap.SCOPE_SUBTREE, filt)
|
||||
except errors.NotFound:
|
||||
ents = []
|
||||
return ents
|
||||
|
||||
@ -212,13 +215,13 @@ class ReplicationManager(object):
|
||||
|
||||
filt = "(objectclass=nsds5ReplicationAgreement)"
|
||||
try:
|
||||
ents = self.conn.search_s("cn=mapping tree,cn=config",
|
||||
ldap.SCOPE_SUBTREE, filt)
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
ents = self.conn.getList(DN(('cn', 'mapping tree'), ('cn', 'config')),
|
||||
ldap.SCOPE_SUBTREE, filt)
|
||||
except errors.NotFound:
|
||||
return res
|
||||
|
||||
for ent in ents:
|
||||
res.append(ent.nsds5replicahost)
|
||||
res.append(ent.getValue('nsds5replicahost'))
|
||||
|
||||
return res
|
||||
|
||||
@ -234,24 +237,23 @@ class ReplicationManager(object):
|
||||
|
||||
filt = "(&(|(objectclass=nsds5ReplicationAgreement)(objectclass=nsDSWindowsReplicationAgreement))(nsDS5ReplicaHost=%s))" % hostname
|
||||
try:
|
||||
entry = self.conn.search_s("cn=mapping tree,cn=config",
|
||||
ldap.SCOPE_SUBTREE, filt)
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
entries = self.conn.getList(DN(('cn', 'mapping tree'), ('cn', 'config')),
|
||||
ldap.SCOPE_SUBTREE, filt)
|
||||
except errors.NotFound:
|
||||
return None
|
||||
|
||||
if len(entry) == 0:
|
||||
if len(entries) == 0:
|
||||
return None
|
||||
else:
|
||||
return entry[0] # There can be only one
|
||||
return entries[0] # There can be only one
|
||||
|
||||
def add_replication_manager(self, conn, dn, pw):
|
||||
"""
|
||||
Create a pseudo user to use for replication.
|
||||
"""
|
||||
|
||||
edn = ldap.dn.str2dn(dn)
|
||||
rdn_attr = edn[0][0][0]
|
||||
rdn_val = edn[0][0][1]
|
||||
assert isinstance(dn, DN)
|
||||
rdn_attr = dn[0].attr
|
||||
rdn_val = dn[0].value
|
||||
|
||||
ent = ipaldap.Entry(dn)
|
||||
ent.setValues("objectclass", "top", "person")
|
||||
@ -266,6 +268,7 @@ class ReplicationManager(object):
|
||||
pass
|
||||
|
||||
def delete_replication_manager(self, conn, dn=REPL_MAN_DN):
|
||||
assert isinstance(dn, DN)
|
||||
try:
|
||||
conn.delete_s(dn)
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
@ -278,16 +281,18 @@ class ReplicationManager(object):
|
||||
return "2"
|
||||
|
||||
def replica_dn(self):
|
||||
return str(DN(('cn','replica'),('cn',self.suffix),('cn','mapping tree'),('cn','config')))
|
||||
return DN(('cn','replica'),('cn',self.suffix),('cn','mapping tree'),('cn','config'))
|
||||
|
||||
def replica_config(self, conn, replica_id, replica_binddn):
|
||||
assert isinstance(replica_binddn, DN)
|
||||
dn = self.replica_dn()
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
try:
|
||||
entry = conn.getEntry(dn, ldap.SCOPE_BASE)
|
||||
managers = entry.getValues('nsDS5ReplicaBindDN')
|
||||
for m in managers:
|
||||
if DN(replica_binddn) == DN(m):
|
||||
if replica_binddn == DN(m):
|
||||
return
|
||||
# Add the new replication manager
|
||||
mod = [(ldap.MOD_ADD, 'nsDS5ReplicaBindDN', replica_binddn)]
|
||||
@ -303,7 +308,7 @@ class ReplicationManager(object):
|
||||
entry = ipaldap.Entry(dn)
|
||||
entry.setValues('objectclass', "top", "nsds5replica", "extensibleobject")
|
||||
entry.setValues('cn', "replica")
|
||||
entry.setValues('nsds5replicaroot', self.suffix)
|
||||
entry.setValues('nsds5replicaroot', str(self.suffix))
|
||||
entry.setValues('nsds5replicaid', str(replica_id))
|
||||
entry.setValues('nsds5replicatype', replica_type)
|
||||
entry.setValues('nsds5flags', "1")
|
||||
@ -313,7 +318,7 @@ class ReplicationManager(object):
|
||||
conn.addEntry(entry)
|
||||
|
||||
def setup_changelog(self, conn):
|
||||
dn = "cn=changelog5, cn=config"
|
||||
dn = DN(('cn', 'changelog5'), ('cn', 'config'))
|
||||
dirpath = conn.dbdir + "/cldb"
|
||||
entry = ipaldap.Entry(dn)
|
||||
entry.setValues('objectclass', "top", "extensibleobject")
|
||||
@ -325,7 +330,7 @@ class ReplicationManager(object):
|
||||
return
|
||||
|
||||
def setup_chaining_backend(self, conn):
|
||||
chaindn = "cn=chaining database, cn=plugins, cn=config"
|
||||
chaindn = DN(('cn', 'chaining database'), ('cn', 'plugins'), ('cn', 'config'))
|
||||
benamebase = "chaindb"
|
||||
urls = [self.to_ldap_url(conn)]
|
||||
cn = ""
|
||||
@ -334,11 +339,11 @@ class ReplicationManager(object):
|
||||
while not done:
|
||||
try:
|
||||
cn = benamebase + str(benum) # e.g. localdb1
|
||||
dn = "cn=" + cn + ", " + chaindn
|
||||
dn = DN(('cn', cn), chaindn)
|
||||
entry = ipaldap.Entry(dn)
|
||||
entry.setValues('objectclass', 'top', 'extensibleObject', 'nsBackendInstance')
|
||||
entry.setValues('cn', cn)
|
||||
entry.setValues('nsslapd-suffix', self.suffix)
|
||||
entry.setValues('nsslapd-suffix', str(self.suffix))
|
||||
entry.setValues('nsfarmserverurl', urls)
|
||||
entry.setValues('nsmultiplexorbinddn', self.repl_man_dn)
|
||||
entry.setValues('nsmultiplexorcredentials', self.repl_man_passwd)
|
||||
@ -365,7 +370,7 @@ class ReplicationManager(object):
|
||||
|
||||
def get_mapping_tree_entry(self):
|
||||
try:
|
||||
entry = self.conn.getEntry("cn=mapping tree,cn=config", ldap.SCOPE_ONELEVEL,
|
||||
entry = self.conn.getEntry(DN(('cn', 'mapping tree'), ('cn', 'config')), ldap.SCOPE_ONELEVEL,
|
||||
"(cn=\"%s\")" % (self.suffix))
|
||||
except errors.NotFound, e:
|
||||
root_logger.debug("failed to find mappting tree entry for %s" % self.suffix)
|
||||
@ -378,7 +383,7 @@ class ReplicationManager(object):
|
||||
mtent = self.get_mapping_tree_entry()
|
||||
dn = mtent.dn
|
||||
|
||||
plgent = self.conn.getEntry("cn=Multimaster Replication Plugin,cn=plugins,cn=config",
|
||||
plgent = self.conn.getEntry(DN(('cn', 'Multimaster Replication Plugin'), ('cn', 'plugins'), ('cn', 'config')),
|
||||
ldap.SCOPE_BASE, "(objectclass=*)", ['nsslapd-pluginPath'])
|
||||
path = plgent.getValue('nsslapd-pluginPath')
|
||||
|
||||
@ -397,7 +402,7 @@ class ReplicationManager(object):
|
||||
self.enable_chain_on_update(chainbe)
|
||||
|
||||
def add_passsync_user(self, conn, password):
|
||||
pass_dn = "uid=passsync,cn=sysaccounts,cn=etc,%s" % self.suffix
|
||||
pass_dn = DN(('uid', 'passsync'), ('cn', 'sysaccounts'), ('cn', 'etc'), self.suffix)
|
||||
print "The user for the Windows PassSync service is %s" % pass_dn
|
||||
try:
|
||||
conn.getEntry(pass_dn, ldap.SCOPE_BASE)
|
||||
@ -414,7 +419,7 @@ class ReplicationManager(object):
|
||||
conn.addEntry(entry)
|
||||
|
||||
# Add it to the list of users allowed to bypass password policy
|
||||
extop_dn = "cn=ipa_pwd_extop,cn=plugins,cn=config"
|
||||
extop_dn = DN(('cn', 'ipa_pwd_extop'), ('cn', 'plugins'), ('cn', 'config'))
|
||||
entry = conn.getEntry(extop_dn, ldap.SCOPE_BASE)
|
||||
pass_mgrs = entry.getValues('passSyncManagersDNs')
|
||||
if not pass_mgrs:
|
||||
@ -435,9 +440,9 @@ class ReplicationManager(object):
|
||||
|
||||
def setup_winsync_agmt(self, entry, win_subtree=None):
|
||||
if win_subtree is None:
|
||||
win_subtree = WIN_USER_CONTAINER + "," + self.ad_suffix
|
||||
ds_subtree = IPA_USER_CONTAINER + "," + self.suffix
|
||||
windomain = '.'.join(ldap.explode_dn(self.suffix, 1))
|
||||
win_subtree = DN(WIN_USER_CONTAINER, self.ad_suffix)
|
||||
ds_subtree = DN(IPA_USER_CONTAINER, self.suffix)
|
||||
windomain = ipautil.suffix_to_realm(self.suffix)
|
||||
|
||||
entry.setValues("objectclass", "nsDSWindowsReplicationAgreement")
|
||||
entry.setValues("nsds7WindowsReplicaSubtree", win_subtree)
|
||||
@ -454,7 +459,7 @@ class ReplicationManager(object):
|
||||
tell which side we want.
|
||||
"""
|
||||
cn = "meTo%s" % (hostname)
|
||||
dn = "cn=%s, %s" % (cn, self.replica_dn())
|
||||
dn = DN(('cn', cn), self.replica_dn())
|
||||
|
||||
return (cn, dn)
|
||||
|
||||
@ -469,6 +474,9 @@ class ReplicationManager(object):
|
||||
isn't a dogtag replication agreement.
|
||||
"""
|
||||
|
||||
if repl_man_dn is not None:
|
||||
assert isinstance(repl_man_dn, DN)
|
||||
|
||||
cn, dn = self.agreement_dn(b_hostname, master=master)
|
||||
try:
|
||||
a_conn.getEntry(dn, ldap.SCOPE_BASE)
|
||||
@ -482,7 +490,7 @@ class ReplicationManager(object):
|
||||
entry.setValues('nsds5replicahost', b_hostname)
|
||||
entry.setValues('nsds5replicaport', str(port))
|
||||
entry.setValues('nsds5replicatimeout', str(TIMEOUT))
|
||||
entry.setValues('nsds5replicaroot', self.suffix)
|
||||
entry.setValues('nsds5replicaroot', str(self.suffix))
|
||||
if master is None:
|
||||
entry.setValues('nsDS5ReplicatedAttributeList',
|
||||
'(objectclass=*) $ EXCLUDE %s' % " ".join(EXCLUDES))
|
||||
@ -538,10 +546,15 @@ class ReplicationManager(object):
|
||||
|
||||
while (retries > 0 ):
|
||||
root_logger.info('Getting ldap service principals for conversion: %s and %s' % (filter_a, filter_b))
|
||||
a_entry = b.search_s(self.suffix, ldap.SCOPE_SUBTREE,
|
||||
filterstr=filter_a)
|
||||
b_entry = a.search_s(self.suffix, ldap.SCOPE_SUBTREE,
|
||||
filterstr=filter_b)
|
||||
try:
|
||||
a_entry = b.search_s(self.suffix, ldap.SCOPE_SUBTREE, filterstr=filter_a)
|
||||
except errors.NotFound:
|
||||
pass
|
||||
|
||||
try:
|
||||
b_entry = a.search_s(self.suffix, ldap.SCOPE_SUBTREE, filterstr=filter_b)
|
||||
except errors.NotFound:
|
||||
pass
|
||||
|
||||
if a_entry and b_entry:
|
||||
root_logger.debug('Found both principals.')
|
||||
@ -578,7 +591,10 @@ class ReplicationManager(object):
|
||||
"""
|
||||
|
||||
rep_dn = self.replica_dn()
|
||||
assert isinstance(rep_dn, DN)
|
||||
(a_dn, b_dn) = self.get_replica_principal_dns(a, b, retries=10)
|
||||
assert isinstance(a_dn, DN)
|
||||
assert isinstance(b_dn, DN)
|
||||
|
||||
# Add kerberos principal DNs as valid bindDNs for replication
|
||||
try:
|
||||
@ -623,12 +639,10 @@ class ReplicationManager(object):
|
||||
return self.conn.deleteEntry(dn)
|
||||
|
||||
def delete_referral(self, hostname):
|
||||
esc1_suffix = self.suffix.replace('=', '\\3D').replace(',', '\\2C')
|
||||
esc2_suffix = self.suffix.replace('=', '%3D').replace(',', '%2C')
|
||||
dn = 'cn=%s,cn=mapping tree,cn=config' % esc1_suffix
|
||||
dn = DN(('cn', self.suffix), ('cn', 'mapping tree'), ('cn', 'config'))
|
||||
# TODO: should we detect proto/port somehow ?
|
||||
mod = [(ldap.MOD_DELETE, 'nsslapd-referral',
|
||||
'ldap://%s/%s' % (ipautil.format_netloc(hostname, 389), esc2_suffix))]
|
||||
'ldap://%s/%s' % (ipautil.format_netloc(hostname, 389), self.suffix))]
|
||||
|
||||
try:
|
||||
self.conn.modify_s(dn, mod)
|
||||
@ -648,9 +662,9 @@ class ReplicationManager(object):
|
||||
print "Error reading status from agreement", agmtdn
|
||||
hasError = 1
|
||||
else:
|
||||
refresh = entry.nsds5BeginReplicaRefresh
|
||||
inprogress = entry.nsds5replicaUpdateInProgress
|
||||
status = entry.nsds5ReplicaLastInitStatus
|
||||
refresh = entry.getValue('nsds5BeginReplicaRefresh')
|
||||
inprogress = entry.getValue('nsds5replicaUpdateInProgress')
|
||||
status = entry.getValue('nsds5ReplicaLastInitStatus')
|
||||
if not refresh: # done - check status
|
||||
if not status:
|
||||
print "No status yet"
|
||||
@ -683,10 +697,10 @@ class ReplicationManager(object):
|
||||
print "Error reading status from agreement", agmtdn
|
||||
hasError = 1
|
||||
else:
|
||||
inprogress = entry.nsds5replicaUpdateInProgress
|
||||
status = entry.nsds5ReplicaLastUpdateStatus
|
||||
start = entry.nsds5ReplicaLastUpdateStart
|
||||
end = entry.nsds5ReplicaLastUpdateEnd
|
||||
inprogress = entry.getValue('nsds5replicaUpdateInProgress')
|
||||
status = entry.getValue('nsds5ReplicaLastUpdateStatus')
|
||||
start = entry.getValue('nsds5ReplicaLastUpdateStart')
|
||||
end = entry.getValue('nsds5ReplicaLastUpdateEnd')
|
||||
# incremental update is done if inprogress is false and end >= start
|
||||
done = inprogress and inprogress.lower() == 'false' and start and end and (start <= end)
|
||||
root_logger.info("Replication Update in progress: %s: status: %s: start: %s: end: %s" %
|
||||
@ -733,6 +747,7 @@ class ReplicationManager(object):
|
||||
return self.wait_for_repl_init(conn, dn)
|
||||
|
||||
def basic_replication_setup(self, conn, replica_id, repldn, replpw):
|
||||
assert isinstance(repldn, DN)
|
||||
if replpw is not None:
|
||||
self.add_replication_manager(conn, repldn, replpw)
|
||||
self.replica_config(conn, replica_id, repldn)
|
||||
@ -741,6 +756,7 @@ class ReplicationManager(object):
|
||||
def setup_replication(self, r_hostname, r_port=389, r_sslport=636,
|
||||
r_binddn=None, r_bindpw=None, starttls=False,
|
||||
is_cs_replica=False):
|
||||
assert isinstance(r_binddn, DN)
|
||||
# note - there appears to be a bug in python-ldap - it does not
|
||||
# allow connections using two different CA certs
|
||||
if starttls:
|
||||
@ -836,7 +852,7 @@ class ReplicationManager(object):
|
||||
root_logger.info("Agreement is ready, starting replication . . .")
|
||||
|
||||
# Add winsync replica to the public DIT
|
||||
dn = str(DN(('cn',ad_dc_name),('cn','replicas'),('cn','ipa'),('cn','etc'), self.suffix))
|
||||
dn = DN(('cn',ad_dc_name),('cn','replicas'),('cn','ipa'),('cn','etc'), self.suffix)
|
||||
entry = ipaldap.Entry(dn)
|
||||
entry.setValues("objectclass", ["nsContainer", "ipaConfigObject"])
|
||||
entry.setValues("cn", ad_dc_name)
|
||||
@ -910,17 +926,17 @@ class ReplicationManager(object):
|
||||
filter = '(&(nsDS5ReplicaHost=%s)' \
|
||||
'(|(objectclass=nsDSWindowsReplicationAgreement)' \
|
||||
'(objectclass=nsds5ReplicationAgreement)))' % hostname
|
||||
entry = conn.search_s("cn=config", ldap.SCOPE_SUBTREE, filter)
|
||||
if len(entry) == 0:
|
||||
entries = conn.getList(DN(('cn', 'config')), ldap.SCOPE_SUBTREE, filter)
|
||||
if len(entries) == 0:
|
||||
root_logger.error("Unable to find replication agreement for %s" %
|
||||
(hostname))
|
||||
raise RuntimeError("Unable to proceed")
|
||||
if len(entry) > 1:
|
||||
if len(entries) > 1:
|
||||
root_logger.error("Found multiple agreements for %s" % hostname)
|
||||
root_logger.error("Using the first one only (%s)" % entry[0].dn)
|
||||
root_logger.error("Using the first one only (%s)" % entries[0].dn)
|
||||
|
||||
dn = entry[0].dn
|
||||
schedule = entry[0].nsds5replicaupdateschedule
|
||||
dn = entries[0].dn
|
||||
schedule = entries[0].getValue('nsds5replicaupdateschedule')
|
||||
|
||||
# On the remote chance of a match. We force a synch to happen right
|
||||
# now by setting the schedule to something and quickly removing it.
|
||||
@ -965,16 +981,14 @@ class ReplicationManager(object):
|
||||
# delete master kerberos key and all its svc principals
|
||||
try:
|
||||
filter='(krbprincipalname=*/%s@%s)' % (replica, realm)
|
||||
entries = self.conn.search_s(self.suffix, ldap.SCOPE_SUBTREE,
|
||||
filterstr=filter)
|
||||
entries = self.conn.getList(self.suffix, ldap.SCOPE_SUBTREE,
|
||||
filterstr=filter)
|
||||
if len(entries) != 0:
|
||||
dnset = self.conn.get_dns_sorted_by_length(entries,
|
||||
reverse=True)
|
||||
for dns in dnset:
|
||||
for dn in dns:
|
||||
self.conn.deleteEntry(dn)
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
pass
|
||||
except errors.NotFound:
|
||||
pass
|
||||
except Exception, e:
|
||||
@ -984,18 +998,18 @@ class ReplicationManager(object):
|
||||
err = e
|
||||
|
||||
# remove replica memberPrincipal from s4u2proxy configuration
|
||||
dn1 = DN(u'cn=ipa-http-delegation', api.env.container_s4u2proxy, self.suffix)
|
||||
dn1 = DN(('cn', 'ipa-http-delegation'), api.env.container_s4u2proxy, self.suffix)
|
||||
member_principal1 = "HTTP/%(fqdn)s@%(realm)s" % dict(fqdn=replica, realm=realm)
|
||||
|
||||
dn2 = DN(u'cn=ipa-ldap-delegation-targets', api.env.container_s4u2proxy, self.suffix)
|
||||
dn2 = DN(('cn', 'ipa-ldap-delegation-targets'), api.env.container_s4u2proxy, self.suffix)
|
||||
member_principal2 = "ldap/%(fqdn)s@%(realm)s" % dict(fqdn=replica, realm=realm)
|
||||
|
||||
dn3 = DN(u'cn=ipa-cifs-delegation-targets', api.env.container_s4u2proxy, self.suffix)
|
||||
dn3 = DN(('cn', 'ipa-cifs-delegation-targets'), api.env.container_s4u2proxy, self.suffix)
|
||||
member_principal3 = "cifs/%(fqdn)s@%(realm)s" % dict(fqdn=replica, realm=realm)
|
||||
|
||||
for (dn, member_principal) in ((str(dn1), member_principal1),
|
||||
(str(dn2), member_principal2),
|
||||
(str(dn3), member_principal3)):
|
||||
for (dn, member_principal) in ((dn1, member_principal1),
|
||||
(dn2, member_principal2),
|
||||
(dn3, member_principal3)):
|
||||
try:
|
||||
mod = [(ldap.MOD_DELETE, 'memberPrincipal', member_principal)]
|
||||
self.conn.modify_s(dn, mod)
|
||||
@ -1010,16 +1024,14 @@ class ReplicationManager(object):
|
||||
|
||||
# delete master entry with all active services
|
||||
try:
|
||||
dn = 'cn=%s,cn=masters,cn=ipa,cn=etc,%s' % (replica, self.suffix)
|
||||
entries = self.conn.search_s(dn, ldap.SCOPE_SUBTREE)
|
||||
dn = DN(('cn', replica), ('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), self.suffix)
|
||||
entries = self.conn.getList(dn, ldap.SCOPE_SUBTREE)
|
||||
if len(entries) != 0:
|
||||
dnset = self.conn.get_dns_sorted_by_length(entries,
|
||||
reverse=True)
|
||||
for dns in dnset:
|
||||
for dn in dns:
|
||||
self.conn.deleteEntry(dn)
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
pass
|
||||
except errors.NotFound:
|
||||
pass
|
||||
except Exception, e:
|
||||
@ -1029,15 +1041,13 @@ class ReplicationManager(object):
|
||||
err = e
|
||||
|
||||
try:
|
||||
basedn = 'cn=etc,%s' % self.suffix
|
||||
basedn = DN(('cn', 'etc'), self.suffix)
|
||||
filter = '(dnaHostname=%s)' % replica
|
||||
entries = self.conn.search_s(basedn, ldap.SCOPE_SUBTREE,
|
||||
filterstr=filter)
|
||||
entries = self.conn.getList(basedn, ldap.SCOPE_SUBTREE,
|
||||
filterstr=filter)
|
||||
if len(entries) != 0:
|
||||
for e in entries:
|
||||
self.conn.deleteEntry(e.dn)
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
pass
|
||||
except errors.NotFound:
|
||||
pass
|
||||
except Exception, e:
|
||||
@ -1047,18 +1057,16 @@ class ReplicationManager(object):
|
||||
err = e
|
||||
|
||||
try:
|
||||
dn = 'cn=default,ou=profile,%s' % self.suffix
|
||||
ret = self.conn.search_s(dn, ldap.SCOPE_BASE,
|
||||
'(objectclass=*)')[0]
|
||||
srvlist = ret.data.get('defaultServerList')
|
||||
if len(srvlist) > 0:
|
||||
srvlist = srvlist[0].split()
|
||||
dn = DN(('cn', 'default'), ('ou', 'profile'), self.suffix)
|
||||
ret = self.conn.getEntry(dn, ldap.SCOPE_BASE, '(objectclass=*)')
|
||||
srvlist = ret.getValue('defaultServerList', '')
|
||||
srvlist = srvlist[0].split()
|
||||
if replica in srvlist:
|
||||
srvlist.remove(replica)
|
||||
attr = ' '.join(srvlist)
|
||||
mod = [(ldap.MOD_REPLACE, 'defaultServerList', attr)]
|
||||
self.conn.modify_s(dn, mod)
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
except errors.NotFound:
|
||||
pass
|
||||
except ldap.NO_SUCH_ATTRIBUTE:
|
||||
pass
|
||||
|
@ -25,6 +25,7 @@ from ipapython import sysrestore
|
||||
from ipapython import ipautil
|
||||
from ipapython import services as ipaservices
|
||||
from ipalib import errors
|
||||
from ipapython.dn import DN
|
||||
import ldap
|
||||
from ipaserver import ipaldap
|
||||
import base64
|
||||
@ -78,7 +79,7 @@ class Service(object):
|
||||
self.sstore = sysrestore.StateFile('/var/lib/ipa/sysrestore')
|
||||
|
||||
self.realm = None
|
||||
self.suffix = None
|
||||
self.suffix = DN()
|
||||
self.principal = None
|
||||
self.dercert = None
|
||||
|
||||
@ -150,7 +151,7 @@ class Service(object):
|
||||
# use URI of admin connection
|
||||
if not self.admin_conn:
|
||||
self.ldap_connect()
|
||||
args += ["-H", self.admin_conn._uri]
|
||||
args += ["-H", self.admin_conn.uri]
|
||||
|
||||
auth_parms = []
|
||||
if self.dm_password:
|
||||
@ -183,15 +184,15 @@ class Service(object):
|
||||
cn=kerberos to cn=services
|
||||
"""
|
||||
|
||||
dn = "krbprincipalname=%s,cn=%s,cn=kerberos,%s" % (principal, self.realm, self.suffix)
|
||||
dn = DN(('krbprincipalname', principal), ('cn', self.realm), ('cn', 'kerberos'), self.suffix)
|
||||
try:
|
||||
entry = self.admin_conn.getEntry(dn, ldap.SCOPE_BASE)
|
||||
except errors.NotFound:
|
||||
# There is no service in the wrong location, nothing to do.
|
||||
# This can happen when installing a replica
|
||||
return
|
||||
newdn = "krbprincipalname=%s,cn=services,cn=accounts,%s" % (principal, self.suffix)
|
||||
hostdn = "fqdn=%s,cn=computers,cn=accounts,%s" % (self.fqdn, self.suffix)
|
||||
return None
|
||||
newdn = DN(('krbprincipalname', principal), ('cn', 'services'), ('cn', 'accounts'), self.suffix)
|
||||
hostdn = DN(('fqdn', self.fqdn), ('cn', 'computers'), ('cn', 'accounts'), self.suffix)
|
||||
self.admin_conn.deleteEntry(dn)
|
||||
entry.dn = newdn
|
||||
classes = entry.getValues("objectclass")
|
||||
@ -211,8 +212,8 @@ class Service(object):
|
||||
if not self.admin_conn:
|
||||
self.ldap_connect()
|
||||
|
||||
dn = "krbprincipalname=%s,cn=services,cn=accounts,%s" % (principal, self.suffix)
|
||||
hostdn = "fqdn=%s,cn=computers,cn=accounts,%s" % (self.fqdn, self.suffix)
|
||||
dn = DN(('krbprincipalname', principal), ('cn', 'services'), ('cn', 'accounts'), self.suffix)
|
||||
hostdn = DN(('fqdn', self.fqdn), ('cn', 'computers'), ('cn', 'accounts'), self.suffix)
|
||||
entry = ipaldap.Entry(dn)
|
||||
entry.setValues("objectclass", ["krbprincipal", "krbprincipalaux", "krbticketpolicyaux", "ipaobject", "ipaservice", "pkiuser"])
|
||||
entry.setValue("krbprincipalname", principal)
|
||||
@ -242,7 +243,7 @@ class Service(object):
|
||||
self.ldap_disconnect()
|
||||
self.ldap_connect()
|
||||
|
||||
dn = "krbprincipalname=%s,cn=services,cn=accounts,%s" % (self.principal, self.suffix)
|
||||
dn = DN(('krbprincipalname', self.principal), ('cn', 'services'), ('cn', 'accounts'), self.suffix)
|
||||
mod = [(ldap.MOD_ADD, 'userCertificate', self.dercert)]
|
||||
try:
|
||||
self.admin_conn.modify_s(dn, mod)
|
||||
@ -327,13 +328,12 @@ class Service(object):
|
||||
self.steps = []
|
||||
|
||||
def ldap_enable(self, name, fqdn, dm_password, ldap_suffix):
|
||||
assert isinstance(ldap_suffix, DN)
|
||||
self.disable()
|
||||
if not self.admin_conn:
|
||||
self.ldap_connect()
|
||||
|
||||
entry_name = "cn=%s,cn=%s,%s,%s" % (name, fqdn,
|
||||
"cn=masters,cn=ipa,cn=etc",
|
||||
ldap_suffix)
|
||||
entry_name = DN(('cn', name), ('cn', fqdn), ('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), ldap_suffix)
|
||||
order = SERVICE_LIST[name][1]
|
||||
entry = ipaldap.Entry(entry_name)
|
||||
entry.setValues("objectclass",
|
||||
@ -362,6 +362,8 @@ class SimpleServiceInstance(Service):
|
||||
self.step("configuring %s to start on boot" % self.service_name, self.__enable)
|
||||
self.start_creation("Configuring %s" % self.service_name)
|
||||
|
||||
suffix = ipautil.dn_attribute_property('_ldap_suffix')
|
||||
|
||||
def __start(self):
|
||||
self.backup_state("running", self.is_running())
|
||||
self.restart()
|
||||
|
@ -34,9 +34,11 @@ import ldap.sasl
|
||||
import ldapurl
|
||||
from ldap.controls import LDAPControl
|
||||
from ldap.ldapobject import SimpleLDAPObject
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython import ipautil
|
||||
from ipalib import errors
|
||||
from ipapython.ipautil import format_netloc, wait_for_open_socket, wait_for_open_ports
|
||||
from ipapython.dn import DN
|
||||
from ipapython.entity import Entity
|
||||
from ipaserver.plugins.ldap2 import IPASimpleLDAPObject
|
||||
|
||||
@ -92,7 +94,7 @@ class Entry:
|
||||
a list of values. In python-ldap, entries are returned as a list of
|
||||
2-tuples. Instance variables:
|
||||
|
||||
* dn - string - the string DN of the entry
|
||||
* dn - DN object - the DN of the entry
|
||||
* data - CIDict - case insensitive dict of the attributes and values
|
||||
"""
|
||||
def __init__(self,entrydata):
|
||||
@ -103,13 +105,22 @@ class Entry:
|
||||
if isinstance(entrydata,tuple):
|
||||
self.dn = entrydata[0]
|
||||
self.data = ipautil.CIDict(entrydata[1])
|
||||
elif isinstance(entrydata,str) or isinstance(entrydata,unicode):
|
||||
elif isinstance(entrydata,DN):
|
||||
self.dn = entrydata
|
||||
self.data = ipautil.CIDict()
|
||||
elif isinstance(entrydata, basestring):
|
||||
self.dn = DN(entrydata)
|
||||
self.data = ipautil.CIDict()
|
||||
else:
|
||||
raise TypeError("entrydata must be 2-tuple, DN, or basestring, got %s" % type(entrydata))
|
||||
else:
|
||||
self.dn = ''
|
||||
self.dn = DN()
|
||||
self.data = ipautil.CIDict()
|
||||
|
||||
assert isinstance(self.dn, DN)
|
||||
|
||||
dn = ipautil.dn_attribute_property('_dn')
|
||||
|
||||
def __nonzero__(self):
|
||||
"""This allows us to do tests like if entry: returns false if there is no data,
|
||||
true otherwise"""
|
||||
@ -119,23 +130,16 @@ class Entry:
|
||||
"""Return True if this entry has an attribute named name, False otherwise"""
|
||||
return self.data and self.data.has_key(name)
|
||||
|
||||
def __getattr__(self,name):
|
||||
"""If name is the name of an LDAP attribute, return the first value for that
|
||||
attribute - equivalent to getValue - this allows the use of
|
||||
entry.cn
|
||||
instead of
|
||||
entry.getValue('cn')
|
||||
This also allows us to return None if an attribute is not found rather than
|
||||
throwing an exception"""
|
||||
return self.getValue(name)
|
||||
|
||||
def getValues(self,name):
|
||||
"""Get the list (array) of values for the attribute named name"""
|
||||
return self.data.get(name)
|
||||
|
||||
def getValue(self,name):
|
||||
def getValue(self,name, default=None):
|
||||
"""Get the first value for the attribute named name"""
|
||||
return self.data.get(name,[None])[0]
|
||||
value = self.data.get(name, default)
|
||||
if isinstance(value, (list, tuple)):
|
||||
return value[0]
|
||||
return value
|
||||
|
||||
def setValue(self, name, *value):
|
||||
"""
|
||||
@ -179,6 +183,7 @@ class Entry:
|
||||
def toDict(self):
|
||||
"""Convert the attrs and values to a dict. The dict is keyed on the
|
||||
attribute name. The value is either single value or a list of values."""
|
||||
assert isinstance(self.dn, DN)
|
||||
result = ipautil.CIDict(self.data)
|
||||
for i in result.keys():
|
||||
result[i] = ipautil.utf8_encode_values(result[i])
|
||||
@ -206,7 +211,7 @@ class Entry:
|
||||
# (1000)
|
||||
newdata = {}
|
||||
newdata.update(self.data)
|
||||
ldif.LDIFWriter(sio,Entry.base64_attrs,1000).unparse(self.dn,newdata)
|
||||
ldif.LDIFWriter(sio,Entry.base64_attrs,1000).unparse(str(self.dn),newdata)
|
||||
return sio.getvalue()
|
||||
|
||||
class IPAdmin(IPAEntryLDAPObject):
|
||||
@ -233,6 +238,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
that we can call it from places other than instance creation
|
||||
e.g. when we just need to reconnect
|
||||
"""
|
||||
log_mgr.get_logger(self, True)
|
||||
if debug and debug.lower() == "on":
|
||||
ldap.set_option(ldap.OPT_DEBUG_LEVEL,255)
|
||||
if cacert is not None:
|
||||
@ -251,7 +257,6 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
self.ldapi = ldapi
|
||||
self.realm = realm
|
||||
self.suffixes = {}
|
||||
self.schema = None
|
||||
self.__localinit()
|
||||
|
||||
def __lateinit(self):
|
||||
@ -260,7 +265,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
values.
|
||||
"""
|
||||
try:
|
||||
ent = self.getEntry('cn=config,cn=ldbm database,cn=plugins,cn=config',
|
||||
ent = self.getEntry(DN(('cn', 'config'), ('cn', 'ldbm database'), ('cn', 'plugins'), ('cn', 'config')),
|
||||
ldap.SCOPE_BASE, '(objectclass=*)',
|
||||
[ 'nsslapd-directory' ])
|
||||
|
||||
@ -299,6 +304,9 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
if not isinstance(e,ldap.TIMEOUT):
|
||||
desc = e.args[0]['desc'].strip()
|
||||
info = e.args[0].get('info','').strip()
|
||||
arg_desc = kw.get('arg_desc')
|
||||
if arg_desc is not None:
|
||||
info += " arguments: %s" % arg_desc
|
||||
else:
|
||||
desc = ''
|
||||
info = ''
|
||||
@ -334,7 +342,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
raise errors.DatabaseError(desc=desc,info=info)
|
||||
|
||||
def __wait_for_connection(self, timeout):
|
||||
lurl = ldapurl.LDAPUrl(self._uri)
|
||||
lurl = ldapurl.LDAPUrl(self.uri)
|
||||
if lurl.urlscheme == 'ldapi':
|
||||
wait_for_open_socket(lurl.hostport, timeout)
|
||||
else:
|
||||
@ -365,25 +373,25 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
try:
|
||||
if krbccache is not None:
|
||||
os.environ["KRB5CCNAME"] = krbccache
|
||||
self.sasl_interactive_bind_s("", SASL_AUTH)
|
||||
self.sasl_interactive_bind_s(None, SASL_AUTH)
|
||||
self.principal = principal
|
||||
self.proxydn = None
|
||||
except ldap.LDAPError, e:
|
||||
self.__handle_errors(e)
|
||||
|
||||
def do_simple_bind(self, binddn="cn=directory manager", bindpw="", timeout=DEFAULT_TIMEOUT):
|
||||
self.binddn = binddn
|
||||
def do_simple_bind(self, binddn=DN(('cn', 'directory manager')), bindpw="", timeout=DEFAULT_TIMEOUT):
|
||||
self.binddn = binddn # FIXME, self.binddn & self.bindpwd never referenced.
|
||||
self.bindpwd = bindpw
|
||||
self.__bind_with_wait(self.simple_bind_s, timeout, binddn, bindpw)
|
||||
self.__lateinit()
|
||||
|
||||
def do_sasl_gssapi_bind(self, timeout=DEFAULT_TIMEOUT):
|
||||
self.__bind_with_wait(self.sasl_interactive_bind_s, timeout, '', SASL_AUTH)
|
||||
self.__bind_with_wait(self.sasl_interactive_bind_s, timeout, None, SASL_AUTH)
|
||||
self.__lateinit()
|
||||
|
||||
def do_external_bind(self, user_name=None, timeout=DEFAULT_TIMEOUT):
|
||||
auth_tokens = ldap.sasl.external(user_name)
|
||||
self.__bind_with_wait(self.sasl_interactive_bind_s, timeout, '', auth_tokens)
|
||||
self.__bind_with_wait(self.sasl_interactive_bind_s, timeout, None, auth_tokens)
|
||||
self.__lateinit()
|
||||
|
||||
def getEntry(self, base, scope, filterstr='(objectClass=*)', attrlist=None, attrsonly=0):
|
||||
@ -491,13 +499,15 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
self.set_option(ldap.OPT_SERVER_CONTROLS, sctrl)
|
||||
self.add_s(entry.dn, entry.toTupleList())
|
||||
except ldap.LDAPError, e:
|
||||
arg_desc = 'entry=%s' % (entry.toTupleList())
|
||||
arg_desc = 'entry=%s: %s' % (entry.dn, entry.toTupleList())
|
||||
self.__handle_errors(e, arg_desc=arg_desc)
|
||||
return True
|
||||
|
||||
def updateRDN(self, dn, newrdn):
|
||||
"""Wrap the modrdn function."""
|
||||
|
||||
assert isinstance(dn, DN)
|
||||
assert isinstance(newrdn, DN)
|
||||
sctrl = self.__get_server_controls()
|
||||
|
||||
if dn == newrdn:
|
||||
@ -516,6 +526,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
"""This wraps the mod function. It assumes that the entry is already
|
||||
populated with all of the desired objectclasses and attributes"""
|
||||
|
||||
assert isinstance(dn, DN)
|
||||
sctrl = self.__get_server_controls()
|
||||
|
||||
modlist = self.generateModList(oldentry, newentry)
|
||||
@ -575,7 +586,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
|
||||
# You can't remove schema online. An add will automatically
|
||||
# replace any existing schema.
|
||||
if old_entry.get('dn') == 'cn=schema':
|
||||
if old_entry.get('dn', DN()) == DN(('cn', 'schema')):
|
||||
if len(adds) > 0:
|
||||
modlist.append((ldap.MOD_ADD, key, adds))
|
||||
else:
|
||||
@ -590,11 +601,12 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
|
||||
return modlist
|
||||
|
||||
def inactivateEntry(self,dn,has_key):
|
||||
def inactivateEntry(self,dn, has_key):
|
||||
"""Rather than deleting entries we mark them as inactive.
|
||||
has_key defines whether the entry already has nsAccountlock
|
||||
set so we can determine which type of mod operation to run."""
|
||||
|
||||
assert isinstance(dn, DN)
|
||||
sctrl = self.__get_server_controls()
|
||||
modlist=[]
|
||||
|
||||
@ -616,6 +628,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
def deleteEntry(self, dn):
|
||||
"""This wraps the delete function. Use with caution."""
|
||||
|
||||
assert isinstance(dn, DN)
|
||||
sctrl = self.__get_server_controls()
|
||||
|
||||
try:
|
||||
@ -627,7 +640,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
self.__handle_errors(e, arg_desc=arg_desc)
|
||||
return True
|
||||
|
||||
def modifyPassword(self,dn,oldpass,newpass):
|
||||
def modifyPassword(self, dn, oldpass, newpass):
|
||||
"""Set the user password using RFC 3062, LDAP Password Modify Extended
|
||||
Operation. This ends up calling the IPA password slapi plugin
|
||||
handler so the Kerberos password gets set properly.
|
||||
@ -635,6 +648,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
oldpass is not mandatory
|
||||
"""
|
||||
|
||||
assert isinstance(dn, DN)
|
||||
sctrl = self.__get_server_controls()
|
||||
|
||||
try:
|
||||
@ -656,6 +670,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
|
||||
if isinstance(dn,Entry):
|
||||
dn = dn.dn
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
# wait for entry and/or attr to show up
|
||||
if not quiet:
|
||||
@ -691,6 +706,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
running, true if done - if true, second is the exit code - if dowait
|
||||
is True, this function will block until the task is complete
|
||||
"""
|
||||
assert isinstance(dn, DN)
|
||||
attrlist = ['nsTaskLog', 'nsTaskStatus', 'nsTaskExitCode', 'nsTaskCurrentItem', 'nsTaskTotalItems']
|
||||
done = False
|
||||
exitCode = 0
|
||||
@ -701,26 +717,13 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
break
|
||||
if verbose:
|
||||
print entry
|
||||
if entry.nsTaskExitCode:
|
||||
exitCode = int(entry.nsTaskExitCode)
|
||||
if entry.getValue('nsTaskExitCode'):
|
||||
exitCode = int(entry.getValue('nsTaskExitCode'))
|
||||
done = True
|
||||
if dowait: time.sleep(1)
|
||||
else: break
|
||||
return (done, exitCode)
|
||||
|
||||
def get_schema(self):
|
||||
"""
|
||||
Retrieve cn=schema and convert it into a python-ldap schema
|
||||
object.
|
||||
"""
|
||||
if self.schema:
|
||||
return self.schema
|
||||
schema = self.getEntry('cn=schema', ldap.SCOPE_BASE,
|
||||
'(objectclass=*)', ['attributetypes', 'objectclasses'])
|
||||
schema = schema.toDict()
|
||||
self.schema = ldap.schema.SubSchema(schema)
|
||||
return self.schema
|
||||
|
||||
def get_single_value(self, attr):
|
||||
"""
|
||||
Check the schema to see if the attribute is single-valued.
|
||||
@ -730,8 +733,6 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
If there is a problem loading the schema or the attribute is
|
||||
not in the schema return None
|
||||
"""
|
||||
if not self.schema:
|
||||
self.get_schema()
|
||||
obj = self.schema.get_obj(ldap.schema.AttributeType, attr)
|
||||
return obj and obj.single_value
|
||||
|
||||
@ -744,19 +745,27 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
starting from the leafs and go up to delete nodes only when all its
|
||||
leafs are removed.
|
||||
|
||||
Returns a "sorted" dict keyed by dn lengths and corresponding list
|
||||
of DNs.
|
||||
{'1': [dn1, dn2, dn3], '2': [dn4, dn5], ..}
|
||||
Returns a list of list of dn's. Every dn in the dn list has
|
||||
the same number of RDN's. The outer list is sorted according
|
||||
to the number of RDN's in each inner list.
|
||||
|
||||
Example:
|
||||
|
||||
[['cn=bob', cn=tom], ['cn=bob,ou=people', cn=tom,ou=people]]
|
||||
|
||||
dn's in list[0] have 1 RDN
|
||||
dn's in list[1] have 2 RDN's
|
||||
"""
|
||||
|
||||
res = dict()
|
||||
|
||||
for e in entries:
|
||||
sdn = ldap.dn.str2dn(e.dn)
|
||||
l = len(sdn)
|
||||
if not l in res:
|
||||
res[l] = []
|
||||
res[l].append(e.dn)
|
||||
dn = e.dn
|
||||
assert isinstance(dn, DN)
|
||||
rdn_count = len(dn)
|
||||
rdn_count_list = res.setdefault(rdn_count, [])
|
||||
if dn not in rdn_count_list:
|
||||
rdn_count_list.append(dn)
|
||||
|
||||
keys = res.keys()
|
||||
keys.sort(reverse=reverse)
|
||||
|
@ -238,6 +238,8 @@ digits and nothing else follows.
|
||||
|
||||
from lxml import etree
|
||||
import datetime
|
||||
from ipapython.dn import DN
|
||||
from ldap.filter import escape_filter_chars
|
||||
|
||||
# These are general status return values used when
|
||||
# CMSServlet.outputError() is invoked.
|
||||
@ -1239,8 +1241,8 @@ class ra(rabase.rabase):
|
||||
|
||||
Check if a specified host is a master for a specified service.
|
||||
"""
|
||||
base_dn = 'cn=%s,cn=masters,cn=ipa,cn=etc,%s' % (host, api.env.basedn)
|
||||
filter = '(&(objectClass=ipaConfigObject)(cn=%s)(ipaConfigString=enabledService))' % service
|
||||
base_dn = DN(('cn', host), ('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
|
||||
filter = '(&(objectClass=ipaConfigObject)(cn=%s)(ipaConfigString=enabledService))' % escape_filter_chars(service)
|
||||
try:
|
||||
ldap2 = self.api.Backend.ldap2
|
||||
ent,trunc = ldap2.find_entries(filter=filter, base_dn=base_dn)
|
||||
@ -1258,14 +1260,16 @@ class ra(rabase.rabase):
|
||||
|
||||
Select any host which is a master for a specified service.
|
||||
"""
|
||||
base_dn = 'cn=masters,cn=ipa,cn=etc,%s' % api.env.basedn
|
||||
filter = '(&(objectClass=ipaConfigObject)(cn=%s)(ipaConfigString=enabledService))' % service
|
||||
base_dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
|
||||
filter = '(&(objectClass=ipaConfigObject)(cn=%s)(ipaConfigString=enabledService))' % escape_filter_chars(service)
|
||||
try:
|
||||
ldap2 = self.api.Backend.ldap2
|
||||
ent,trunc = ldap2.find_entries(filter=filter, base_dn=base_dn)
|
||||
if len(ent):
|
||||
entry = random.choice(ent)
|
||||
return ldap.explode_dn(dn=entry[0],notypes=True)[1]
|
||||
dn = entry[0]
|
||||
assert isinstance(dn, DN)
|
||||
return dn[1].value
|
||||
except Exception, e:
|
||||
pass
|
||||
return None
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,6 +39,7 @@ from ipalib import Backend
|
||||
from ipalib import errors
|
||||
from ipalib import x509
|
||||
from ipalib import pkcs10
|
||||
from ipapython.dn import DN, EditableDN, RDN
|
||||
from ipapython.certdb import get_ca_nickname
|
||||
import subprocess
|
||||
import os
|
||||
@ -86,16 +87,14 @@ class ra(rabase.rabase):
|
||||
"""
|
||||
try:
|
||||
config = api.Command['config_show']()['result']
|
||||
subject_base = config.get('ipacertificatesubjectbase')[0]
|
||||
subject_base = EditableDN(config.get('ipacertificatesubjectbase')[0])
|
||||
hostname = get_csr_hostname(csr)
|
||||
base = re.split(',\s*(?=\w+=)', subject_base)
|
||||
base.insert(0,'CN=%s' % hostname)
|
||||
subject_base = ",".join(base)
|
||||
subject_base.insert(0, RDN(('CN', hostname)))
|
||||
request = pkcs10.load_certificate_request(csr)
|
||||
# python-nss normalizes the request subject
|
||||
request_subject = str(pkcs10.get_subject(request))
|
||||
request_subject = DN(pkcs10.get_subject(request))
|
||||
|
||||
if str(subject_base).lower() != request_subject.lower():
|
||||
if subject_base != request_subject:
|
||||
raise errors.CertificateOperationError(error=_('Request subject "%(request_subject)s" does not match the form "%(subject_base)s"') % \
|
||||
{'request_subject' : request_subject, 'subject_base' : subject_base})
|
||||
except errors.CertificateOperationError, e:
|
||||
|
@ -32,7 +32,7 @@ from ipalib.errors import PublicError, InternalError, CommandError, JSONError, C
|
||||
from ipalib.request import context, Connection, destroy_context
|
||||
from ipalib.rpc import xml_dumps, xml_loads
|
||||
from ipalib.util import parse_time_duration
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
from ipaserver.plugins.ldap2 import ldap2
|
||||
from ipapython.compat import json
|
||||
from ipalib.session import session_mgr, AuthManager, get_ipa_ccache_name, load_ccache_data, bind_ipa_ccache, release_ipa_ccache, fmt_time, default_max_session_duration
|
||||
@ -418,29 +418,17 @@ def json_encode_binary(val):
|
||||
if isinstance(val, dict):
|
||||
new_dict = {}
|
||||
for k,v in val.items():
|
||||
if isinstance(v, str):
|
||||
new_dict[k] = {'__base64__' : base64.b64encode(v)}
|
||||
else:
|
||||
new_dict[k] = json_encode_binary(v)
|
||||
del val
|
||||
new_dict[k] = json_encode_binary(v)
|
||||
return new_dict
|
||||
elif isinstance(val, (list, tuple)):
|
||||
new_list = []
|
||||
n = len(val)
|
||||
i = 0
|
||||
while i < n:
|
||||
v = val[i]
|
||||
if isinstance(v, str):
|
||||
new_list.append({'__base64__' : base64.b64encode(v)})
|
||||
else:
|
||||
new_list.append(json_encode_binary(v))
|
||||
i += 1
|
||||
del val
|
||||
new_list = [json_encode_binary(v) for v in val]
|
||||
return new_list
|
||||
elif isinstance(val, str):
|
||||
return {'__base64__' : base64.b64encode(val)}
|
||||
elif isinstance(val, Decimal):
|
||||
return {'__base64__' : base64.b64encode(str(val))}
|
||||
elif isinstance(val, DN):
|
||||
return str(val)
|
||||
else:
|
||||
return val
|
||||
|
||||
@ -474,7 +462,6 @@ def json_decode_binary(val):
|
||||
new_dict[k] = base64.b64decode(v['__base64__'])
|
||||
else:
|
||||
new_dict[k] = json_decode_binary(v)
|
||||
del val
|
||||
return new_dict
|
||||
elif isinstance(val, list):
|
||||
new_list = []
|
||||
@ -488,7 +475,6 @@ def json_decode_binary(val):
|
||||
else:
|
||||
new_list.append(json_decode_binary(v))
|
||||
i += 1
|
||||
del val
|
||||
return new_list
|
||||
else:
|
||||
if isinstance(val, basestring):
|
||||
@ -963,9 +949,9 @@ class login_password(Backend, KerberosSession, HTTP_Status):
|
||||
# Ok, now why is this bad. Is the password simply bad or is the
|
||||
# password expired?
|
||||
try:
|
||||
dn = str(DN(('uid', user),
|
||||
self.api.env.container_user,
|
||||
self.api.env.basedn))
|
||||
dn = DN(('uid', user),
|
||||
self.api.env.container_user,
|
||||
self.api.env.basedn)
|
||||
conn = ldap2(shared_instance=False,
|
||||
ldap_uri=self.api.env.ldap_uri)
|
||||
conn.connect(bind_dn=dn, bind_pw=password)
|
||||
@ -1059,8 +1045,8 @@ class change_password(Backend, HTTP_Status):
|
||||
result = 'error'
|
||||
policy_error = None
|
||||
|
||||
bind_dn = str(DN((self.api.Object.user.primary_key.name, data['user']),
|
||||
self.api.env.container_user, self.api.env.basedn))
|
||||
bind_dn = DN((self.api.Object.user.primary_key.name, data['user']),
|
||||
self.api.env.container_user, self.api.env.basedn)
|
||||
|
||||
try:
|
||||
conn = ldap2(shared_instance=False,
|
||||
|
@ -65,6 +65,10 @@ class IPATypeChecker(TypeChecker):
|
||||
'ipalib.parameters.Enum': ['values'],
|
||||
'ipalib.parameters.File': ['stdin_if_missing'],
|
||||
'urlparse.SplitResult': ['netloc'],
|
||||
'ipaserver.install.ldapupdate.LDAPUpdate' : ['log', 'debug', 'info', 'warning', 'error', 'critical', 'exception'],
|
||||
'ipaserver.plugins.ldap2.SchemaCache' : ['log', 'debug', 'info', 'warning', 'error', 'critical', 'exception'],
|
||||
'ipaserver.plugins.ldap2.IPASimpleLDAPObject' : ['log', 'debug', 'info', 'warning', 'error', 'critical', 'exception'],
|
||||
'ipaserver.plugins.ldap2.ldap2' : ['log', 'debug', 'info', 'warning', 'error', 'critical', 'exception'],
|
||||
'ipaserver.rpcserver.KerberosSession' : ['api', 'log', 'debug', 'info', 'warning', 'error', 'critical', 'exception'],
|
||||
'ipaserver.rpcserver.HTTP_Status' : ['log', 'debug', 'info', 'warning', 'error', 'critical', 'exception'],
|
||||
'ipalib.krb_utils.KRB5_CCache' : ['log', 'debug', 'info', 'warning', 'error', 'critical', 'exception'],
|
||||
|
@ -31,6 +31,7 @@ import nss.nss as nss
|
||||
from ipalib import api, x509, backend, errors
|
||||
from ipaserver.plugins import rabase
|
||||
from ipapython import ipautil
|
||||
from ipapython.dn import DN
|
||||
|
||||
CERTPATH = 'tests/test_xmlrpc/service.crt'
|
||||
|
||||
@ -101,9 +102,9 @@ def makecert(reqdir):
|
||||
subject_base = res['result']['ipacertificatesubjectbase'][0]
|
||||
|
||||
cert = None
|
||||
subject = 'CN=%s,%s' % (api.env.host, subject_base)
|
||||
subject = DN(('CN', api.env.host), subject_base)
|
||||
princ = 'unittest/%s@%s' % (api.env.host, api.env.realm)
|
||||
csr = unicode(generateCSR(reqdir, pwname, subject))
|
||||
csr = unicode(generateCSR(reqdir, pwname, str(subject)))
|
||||
|
||||
try:
|
||||
res = api.Backend.client.run('cert_request', csr, principal=princ,
|
||||
|
@ -31,7 +31,7 @@ import nose
|
||||
import tempfile
|
||||
import krbV
|
||||
from ipaserver.plugins.ldap2 import ldap2
|
||||
from ipalib.dn import *
|
||||
from ipapython.dn import DN
|
||||
|
||||
def use_keytab(principal, keytab):
|
||||
try:
|
||||
|
@ -1,5 +1,5 @@
|
||||
dn: uid=tuser, cn=test, cn=accounts, $SUFFIX
|
||||
deleteentry: reset: nada
|
||||
deleteentry:
|
||||
|
||||
dn: cn=test, cn=accounts, $SUFFIX
|
||||
deleteentry: reset: nada
|
||||
|
@ -20,19 +20,18 @@
|
||||
Test the `ipaserver/install/ldapupdate.py` module.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import os
|
||||
import sys
|
||||
import ldap
|
||||
import nose
|
||||
from nose.tools import raises
|
||||
from tests.util import PluginTester
|
||||
from tests.data import unicode_str
|
||||
from ipalib import api
|
||||
from ipalib import errors
|
||||
from ipaserver.install.ldapupdate import LDAPUpdate, BadSyntax, UPDATES_DIR
|
||||
from ipaserver.install import installutils
|
||||
from ipaserver import ipaldap
|
||||
from ipapython import ipautil
|
||||
from ipapython.dn import DN
|
||||
|
||||
"""
|
||||
The updater works through files only so this is just a thin-wrapper controlling
|
||||
@ -46,7 +45,7 @@ have occurred as expected.
|
||||
The DM password needs to be set in ~/.ipa/.dmpw
|
||||
"""
|
||||
|
||||
class test_update(object):
|
||||
class test_update(unittest.TestCase):
|
||||
"""
|
||||
Test the LDAP updater.
|
||||
"""
|
||||
@ -70,13 +69,16 @@ class test_update(object):
|
||||
else:
|
||||
raise nose.SkipTest("Unable to find test update files")
|
||||
|
||||
self.container_dn = DN(self.updater._template_str('cn=test, cn=accounts, $SUFFIX'))
|
||||
self.user_dn = DN(self.updater._template_str('uid=tuser, cn=test, cn=accounts, $SUFFIX'))
|
||||
|
||||
def tearDown(self):
|
||||
if self.ld:
|
||||
self.ld.unbind()
|
||||
|
||||
def test_0_reset(self):
|
||||
"""
|
||||
Reset the updater test data to a known initial state
|
||||
Reset the updater test data to a known initial state (test_0_reset)
|
||||
"""
|
||||
try:
|
||||
modified = self.updater.update([self.testdir + "0_reset.update"])
|
||||
@ -84,96 +86,121 @@ class test_update(object):
|
||||
# Just means the entry doesn't exist yet
|
||||
modified = True
|
||||
|
||||
assert(modified == True)
|
||||
self.assertTrue(modified)
|
||||
|
||||
with self.assertRaises(errors.NotFound):
|
||||
entries = self.ld.getList(self.container_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
|
||||
with self.assertRaises(errors.NotFound):
|
||||
entries = self.ld.getList(self.user_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
|
||||
def test_1_add(self):
|
||||
"""
|
||||
Test the updater with an add directive
|
||||
Test the updater with an add directive (test_1_add)
|
||||
"""
|
||||
modified = self.updater.update([self.testdir + "1_add.update"])
|
||||
|
||||
assert(modified == True)
|
||||
self.assertTrue(modified)
|
||||
|
||||
entries = self.ld.getList(self.container_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
self.assertEqual(len(entries), 1)
|
||||
entry = entries[0]
|
||||
|
||||
objectclasses = entry.getValues('objectclass')
|
||||
for item in ('top', 'nsContainer'):
|
||||
self.assertTrue(item in objectclasses)
|
||||
|
||||
self.assertEqual(entry.getValue('cn'), 'test')
|
||||
|
||||
entries = self.ld.getList(self.user_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
self.assertEqual(len(entries), 1)
|
||||
entry = entries[0]
|
||||
|
||||
objectclasses = entry.getValues('objectclass')
|
||||
for item in ('top', 'person', 'posixaccount', 'krbprincipalaux', 'inetuser'):
|
||||
self.assertTrue(item in objectclasses)
|
||||
|
||||
self.assertEqual(entry.getValue('loginshell'), '/bin/bash')
|
||||
self.assertEqual(entry.getValue('sn'), 'User')
|
||||
self.assertEqual(entry.getValue('uid'), 'tuser')
|
||||
self.assertEqual(entry.getValue('cn'), 'Test User')
|
||||
|
||||
|
||||
def test_2_update(self):
|
||||
"""
|
||||
Test the updater when adding an attribute to an existing entry
|
||||
Test the updater when adding an attribute to an existing entry (test_2_update)
|
||||
"""
|
||||
modified = self.updater.update([self.testdir + "2_update.update"])
|
||||
assert(modified == True)
|
||||
self.assertTrue(modified)
|
||||
|
||||
# The update passed, lets look at the record and see if it is
|
||||
# really updated
|
||||
dn = self.updater._template_str('uid=tuser, cn=test, cn=accounts, $SUFFIX')
|
||||
entry = self.ld.getList(dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
assert (len(entry) == 1)
|
||||
assert(entry[0].gecos == 'Test User')
|
||||
entries = self.ld.getList(self.user_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
self.assertEqual(len(entries), 1)
|
||||
entry = entries[0]
|
||||
self.assertEqual(entry.getValue('gecos'), 'Test User')
|
||||
|
||||
def test_3_update(self):
|
||||
"""
|
||||
Test the updater forcing an attribute to a given value
|
||||
Test the updater forcing an attribute to a given value (test_3_update)
|
||||
"""
|
||||
modified = self.updater.update([self.testdir + "3_update.update"])
|
||||
assert(modified == True)
|
||||
self.assertTrue(modified)
|
||||
|
||||
# The update passed, lets look at the record and see if it is
|
||||
# really updated
|
||||
dn = self.updater._template_str('uid=tuser, cn=test, cn=accounts, $SUFFIX')
|
||||
entry = self.ld.getList(dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
assert (len(entry) == 1)
|
||||
assert(entry[0].gecos == 'Test User New')
|
||||
entries = self.ld.getList(self.user_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
self.assertEqual(len(entries), 1)
|
||||
entry = entries[0]
|
||||
self.assertEqual(entry.getValue('gecos'), 'Test User New')
|
||||
|
||||
def test_4_update(self):
|
||||
"""
|
||||
Test the updater adding a new value to a single-valued attribute
|
||||
Test the updater adding a new value to a single-valued attribute (test_4_update)
|
||||
"""
|
||||
modified = self.updater.update([self.testdir + "4_update.update"])
|
||||
assert(modified == True)
|
||||
self.assertTrue(modified)
|
||||
|
||||
entries = self.ld.getList(self.user_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
self.assertEqual(len(entries), 1)
|
||||
entry = entries[0]
|
||||
self.assertEqual(entry.getValue('gecos'), 'Test User New2')
|
||||
|
||||
def test_5_update(self):
|
||||
"""
|
||||
Test the updater adding a new value to a multi-valued attribute
|
||||
Test the updater adding a new value to a multi-valued attribute (test_5_update)
|
||||
"""
|
||||
modified = self.updater.update([self.testdir + "5_update.update"])
|
||||
assert(modified == True)
|
||||
self.assertTrue(modified)
|
||||
|
||||
# The update passed, lets look at the record and see if it is
|
||||
# really updated
|
||||
dn = self.updater._template_str('uid=tuser, cn=test, cn=accounts, $SUFFIX')
|
||||
entry = self.ld.getList(dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
assert (len(entry) == 1)
|
||||
assert(entry[0].getValues('cn') == ['Test User', 'Test User New'])
|
||||
entries = self.ld.getList(self.user_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
self.assertEqual(len(entries), 1)
|
||||
entry = entries[0]
|
||||
self.assertEqual(sorted(entry.getValues('cn')), sorted(['Test User', 'Test User New']))
|
||||
|
||||
def test_6_update(self):
|
||||
"""
|
||||
Test the updater removing a value from a multi-valued attribute
|
||||
Test the updater removing a value from a multi-valued attribute (test_6_update)
|
||||
"""
|
||||
modified = self.updater.update([self.testdir + "6_update.update"])
|
||||
assert(modified == True)
|
||||
self.assertTrue(modified)
|
||||
|
||||
# The update passed, lets look at the record and see if it is
|
||||
# really updated
|
||||
dn = self.updater._template_str('uid=tuser, cn=test, cn=accounts, $SUFFIX')
|
||||
entry = self.ld.getList(dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
assert (len(entry) == 1)
|
||||
assert(entry[0].cn == 'Test User')
|
||||
entries = self.ld.getList(self.user_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
self.assertEqual(len(entries), 1)
|
||||
entry = entries[0]
|
||||
self.assertEqual(sorted(entry.getValues('cn')), sorted(['Test User']))
|
||||
|
||||
def test_6_update_1(self):
|
||||
"""
|
||||
Test the updater removing a non-existent value from a multi-valued attribute
|
||||
Test the updater removing a non-existent value from a multi-valued attribute (test_6_update_1)
|
||||
"""
|
||||
modified = self.updater.update([self.testdir + "6_update.update"])
|
||||
assert(modified == False)
|
||||
self.assertFalse(modified)
|
||||
|
||||
# The update passed, lets look at the record and see if it is
|
||||
# really updated
|
||||
dn = self.updater._template_str('uid=tuser, cn=test, cn=accounts, $SUFFIX')
|
||||
entry = self.ld.getList(dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
assert (len(entry) == 1)
|
||||
assert(entry[0].cn == 'Test User')
|
||||
entries = self.ld.getList(self.user_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
self.assertEqual(len(entries), 1)
|
||||
entry = entries[0]
|
||||
self.assertEqual(sorted(entry.getValues('cn')), sorted(['Test User']))
|
||||
|
||||
def test_7_cleanup(self):
|
||||
"""
|
||||
Reset the test data to a known initial state
|
||||
Reset the test data to a known initial state (test_7_cleanup)
|
||||
"""
|
||||
try:
|
||||
modified = self.updater.update([self.testdir + "0_reset.update"])
|
||||
@ -181,18 +208,113 @@ class test_update(object):
|
||||
# Just means the entry doesn't exist yet
|
||||
modified = True
|
||||
|
||||
assert(modified == True)
|
||||
self.assertTrue(modified)
|
||||
|
||||
with self.assertRaises(errors.NotFound):
|
||||
entries = self.ld.getList(self.container_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
|
||||
with self.assertRaises(errors.NotFound):
|
||||
entries = self.ld.getList(self.user_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
|
||||
@raises(BadSyntax)
|
||||
def test_8_badsyntax(self):
|
||||
"""
|
||||
Test the updater with an unknown keyword
|
||||
Test the updater with an unknown keyword (test_8_badsyntax)
|
||||
"""
|
||||
modified = self.updater.update([self.testdir + "8_badsyntax.update"])
|
||||
with self.assertRaises(BadSyntax):
|
||||
modified = self.updater.update([self.testdir + "8_badsyntax.update"])
|
||||
|
||||
@raises(BadSyntax)
|
||||
def test_9_badsyntax(self):
|
||||
"""
|
||||
Test the updater with an incomplete line
|
||||
Test the updater with an incomplete line (test_9_badsyntax)
|
||||
"""
|
||||
modified = self.updater.update([self.testdir + "9_badsyntax.update"])
|
||||
with self.assertRaises(BadSyntax):
|
||||
modified = self.updater.update([self.testdir + "9_badsyntax.update"])
|
||||
|
||||
def test_from_dict(self):
|
||||
"""
|
||||
Test updating from a dict.
|
||||
|
||||
This replicates what was done in test 1.
|
||||
"""
|
||||
|
||||
# First make sure we're clean
|
||||
with self.assertRaises(errors.NotFound):
|
||||
entries = self.ld.getList(self.container_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
|
||||
with self.assertRaises(errors.NotFound):
|
||||
entries = self.ld.getList(self.user_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
|
||||
|
||||
update = {
|
||||
self.container_dn:
|
||||
{'dn': self.container_dn,
|
||||
'updates': ['add:objectClass: top',
|
||||
'add:objectClass: nsContainer',
|
||||
'add:cn: test'
|
||||
],
|
||||
},
|
||||
self.user_dn:
|
||||
{'dn': self.user_dn,
|
||||
'updates': ['add:objectclass: top',
|
||||
'add:objectclass: person',
|
||||
'add:objectclass: posixaccount',
|
||||
'add:objectclass: krbprincipalaux',
|
||||
'add:objectclass: inetuser',
|
||||
'add:homedirectory: /home/tuser',
|
||||
'add:loginshell: /bin/bash',
|
||||
'add:sn: User',
|
||||
'add:uid: tuser',
|
||||
'add:uidnumber: 999',
|
||||
'add:gidnumber: 999',
|
||||
'add:cn: Test User',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
modified = self.updater.update_from_dict(update)
|
||||
self.assertTrue(modified)
|
||||
|
||||
entries = self.ld.getList(self.container_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
self.assertEqual(len(entries), 1)
|
||||
entry = entries[0]
|
||||
|
||||
objectclasses = entry.getValues('objectclass')
|
||||
for item in ('top', 'nsContainer'):
|
||||
self.assertTrue(item in objectclasses)
|
||||
|
||||
self.assertEqual(entry.getValue('cn'), 'test')
|
||||
|
||||
entries = self.ld.getList(self.user_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
self.assertEqual(len(entries), 1)
|
||||
entry = entries[0]
|
||||
|
||||
objectclasses = entry.getValues('objectclass')
|
||||
for item in ('top', 'person', 'posixaccount', 'krbprincipalaux', 'inetuser'):
|
||||
self.assertTrue(item in objectclasses)
|
||||
|
||||
self.assertEqual(entry.getValue('loginshell'), '/bin/bash')
|
||||
self.assertEqual(entry.getValue('sn'), 'User')
|
||||
self.assertEqual(entry.getValue('uid'), 'tuser')
|
||||
self.assertEqual(entry.getValue('cn'), 'Test User')
|
||||
|
||||
# Now delete
|
||||
|
||||
update = {
|
||||
self.container_dn:
|
||||
{'dn': self.container_dn,
|
||||
'deleteentry': None,
|
||||
},
|
||||
self.user_dn:
|
||||
{'dn': self.user_dn,
|
||||
'deleteentry': 'deleteentry: reset: nada',
|
||||
},
|
||||
}
|
||||
|
||||
modified = self.updater.update_from_dict(update)
|
||||
self.assertTrue(modified)
|
||||
|
||||
with self.assertRaises(errors.NotFound):
|
||||
entries = self.ld.getList(self.container_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
|
||||
with self.assertRaises(errors.NotFound):
|
||||
entries = self.ld.getList(self.user_dn, ldap.SCOPE_BASE, 'objectclass=*', ['*'])
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,149 +0,0 @@
|
||||
# encoding: utf-8
|
||||
# Authors:
|
||||
# Pavel Zuna <pzuna@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2009 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, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Test the `ipalib.encoder` module.
|
||||
"""
|
||||
|
||||
import string
|
||||
|
||||
from tests.util import ClassChecker, assert_equal
|
||||
from ipalib.encoder import Encoder, EncoderSettings, encode_args, decode_retval
|
||||
|
||||
_encoder_settings = EncoderSettings()
|
||||
|
||||
_test_str_d = u'ěščřžýáíé'
|
||||
_test_str_e = u'ěščřžýáíé'.encode(_encoder_settings.encode_to)
|
||||
|
||||
|
||||
class test_Encoder(ClassChecker):
|
||||
"""
|
||||
Test the `ipalib.encoder.Encoder` class.
|
||||
"""
|
||||
_cls = Encoder
|
||||
|
||||
def test_encode(self):
|
||||
"""
|
||||
Test the `ipalib.encoder.Encoder.encode` method.
|
||||
"""
|
||||
o = self.cls()
|
||||
encode_to = o.encoder_settings.encode_to
|
||||
o.encoder_settings.encode_postprocessor = lambda x: x
|
||||
# strings
|
||||
assert_equal(o.encode('ahoj'), 'ahoj'.encode(encode_to))
|
||||
assert_equal(o.encode(_test_str_d), _test_str_e)
|
||||
# bool, float, int, long
|
||||
assert_equal(o.encode(True), 'TRUE'.encode(encode_to))
|
||||
assert_equal(o.encode(1.01), str(1.01).encode(encode_to))
|
||||
assert_equal(o.encode(1000), str(1000).encode(encode_to))
|
||||
assert_equal(o.encode(long(1)), str(long(1)).encode(encode_to))
|
||||
# lists
|
||||
expected = [_test_str_e, '1']
|
||||
assert_equal(o.encode([_test_str_d, 1]), expected)
|
||||
expected = ['1', ['1', '2', '3']]
|
||||
assert_equal(o.encode([1, [1, 2, 3]]), expected)
|
||||
# tuples
|
||||
expected = (_test_str_e, '1')
|
||||
assert_equal(o.encode((_test_str_d, 1)), expected)
|
||||
expected = ('1', ('1', '2', '3'))
|
||||
assert_equal(o.encode((1, (1, 2, 3))), expected)
|
||||
# dicts: only values, no postprocessing
|
||||
o.encoder_settings.encode_dict_keys = False
|
||||
o.encoder_settings.encode_dict_keys_postprocess = False
|
||||
o.encoder_settings.encode_dict_vals = True
|
||||
o.encoder_settings.encode_dict_vals_postprocess = False
|
||||
expected = {_test_str_d: _test_str_e}
|
||||
assert_equal(o.encode({_test_str_d: _test_str_d}), expected)
|
||||
# dicts: only keys, no postprocessing
|
||||
o.encoder_settings.encode_dict_keys = True
|
||||
o.encoder_settings.encode_dict_vals = False
|
||||
expected = {_test_str_e: _test_str_d}
|
||||
assert_equal(o.encode({_test_str_d: _test_str_d}), expected)
|
||||
# dicts: both keys and values, no postprocessing
|
||||
o.encoder_settings.encode_dict_vals = True
|
||||
expected = {_test_str_e: _test_str_e}
|
||||
assert_equal(o.encode({_test_str_d: _test_str_d}), expected)
|
||||
# dicts: both keys and values, postprocessing on keys only
|
||||
o.encoder_settings.encode_dict_keys = True
|
||||
o.encoder_settings.encode_dict_keys_postprocess = True
|
||||
o.encoder_settings.encode_postprocessor = string.upper
|
||||
expected = {_test_str_e.upper(): _test_str_e}
|
||||
assert_equal(o.encode({u'ěščřžýáíé': u'ěščřžýáíé'}), expected)
|
||||
# None
|
||||
o.encoder_settings.encode_postprocessor = lambda x: x
|
||||
o.encoder_settings.encode_none = False
|
||||
assert_equal(o.encode(None), None)
|
||||
o.encoder_settings.encode_none = True
|
||||
assert_equal(o.encode(None), str(None).encode(encode_to))
|
||||
|
||||
def test_decode(self):
|
||||
"""
|
||||
Test the `ipalib.encoder.Encoder.decode` method.
|
||||
"""
|
||||
o = self.cls()
|
||||
decode_from = o.encoder_settings.decode_from
|
||||
o.encoder_settings.decode_postprocessor = lambda x: x
|
||||
# strings
|
||||
assert_equal(o.decode('ahoj'), 'ahoj'.decode(decode_from))
|
||||
assert_equal(o.decode(_test_str_e), _test_str_d)
|
||||
# bool, float, int, long
|
||||
assert_equal(o.decode('True'), str(True).decode(decode_from))
|
||||
assert_equal(o.decode('1.01'), str(1.01).decode(decode_from))
|
||||
assert_equal(o.decode('1000'), str(1000).decode(decode_from))
|
||||
assert_equal(o.decode('1'), str(long(1)).decode(decode_from))
|
||||
# lists
|
||||
expected = [_test_str_d, '1']
|
||||
assert_equal(o.decode([_test_str_e, '1']), expected)
|
||||
expected = [u'1', [u'1', u'2', u'3']]
|
||||
assert_equal(o.decode(['1', ['1', '2', '3']]), expected)
|
||||
# tuples
|
||||
expected = (_test_str_d, 1)
|
||||
assert_equal(o.decode((_test_str_e, 1)), expected)
|
||||
expected = (u'1', (u'1', u'2', u'3'))
|
||||
assert_equal(o.decode(('1', ('1', '2', '3'))), expected)
|
||||
# dicts: only values, no postprocessing
|
||||
o.encoder_settings.decode_dict_keys = False
|
||||
o.encoder_settings.decode_dict_keys_postprocess = False
|
||||
o.encoder_settings.decode_dict_vals = True
|
||||
o.encoder_settings.decode_dict_vals_postprocess = False
|
||||
expected = {_test_str_e: _test_str_d}
|
||||
assert_equal(o.decode({_test_str_e: _test_str_e}), expected)
|
||||
# dicts: only keys, no postprocessing
|
||||
o.encoder_settings.decode_dict_keys = True
|
||||
o.encoder_settings.decode_dict_vals = False
|
||||
expected = {_test_str_d: _test_str_e}
|
||||
assert_equal(o.decode({_test_str_e: _test_str_e}), expected)
|
||||
# dicts: both keys and values, no postprocessing
|
||||
o.encoder_settings.decode_dict_vals = True
|
||||
expected = {_test_str_d: _test_str_d}
|
||||
assert_equal(o.decode({_test_str_e: _test_str_e}), expected)
|
||||
# dicts: both keys and values, postprocessing on keys only
|
||||
o.encoder_settings.decode_dict_keys = True
|
||||
o.encoder_settings.decode_dict_keys_postprocess = True
|
||||
o.encoder_settings.decode_postprocessor = string.upper
|
||||
expected = {_test_str_d.upper(): _test_str_d}
|
||||
assert_equal(o.decode({_test_str_e: _test_str_e}), expected)
|
||||
# TODO: dict decoding using a table
|
||||
# None
|
||||
o.encoder_settings.decode_postprocessor = lambda x: x
|
||||
o.encoder_settings.decode_none = False
|
||||
assert_equal(o.decode(None), None)
|
||||
o.encoder_settings.decode_none = True
|
||||
assert_equal(o.decode(None), str(None).decode(decode_from))
|
||||
|
@ -32,7 +32,7 @@ from ipalib.constants import NAME_REGEX, NAME_ERROR
|
||||
import base64
|
||||
from ipalib import x509
|
||||
from nss.error import NSPRError
|
||||
from ipalib.dn import *
|
||||
from ipapython.dn import DN
|
||||
|
||||
# certutil -
|
||||
|
||||
|
1937
tests/test_ipapython/test_dn.py
Normal file
1937
tests/test_ipapython/test_dn.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@ from httptest import Unauthorized_HTTP_test
|
||||
from tests.test_xmlrpc.xmlrpc_test import XMLRPC_test
|
||||
from tests.util import assert_equal, assert_not_equal
|
||||
from ipalib import api, errors
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
import ldap
|
||||
|
||||
testuser = u'tuser'
|
||||
@ -57,9 +57,7 @@ class test_changepw(XMLRPC_test, Unauthorized_HTTP_test):
|
||||
)
|
||||
|
||||
def _checkpw(self, user, password):
|
||||
dn = str(DN(('uid', user),
|
||||
api.env.container_user,
|
||||
api.env.basedn))
|
||||
dn = str(DN(('uid', user), api.env.container_user, api.env.basedn))
|
||||
conn = ldap.initialize(api.env.ldap_uri)
|
||||
try:
|
||||
conn.simple_bind_s(dn, password)
|
||||
|
@ -33,7 +33,7 @@ from ipalib.plugins.host import host
|
||||
import nss.nss as nss
|
||||
from ipalib import api, x509, create_api, errors
|
||||
from ipapython import ipautil
|
||||
from ipalib.dn import *
|
||||
from ipapython.dn import DN
|
||||
|
||||
class test_ldap(object):
|
||||
"""
|
||||
@ -45,8 +45,8 @@ class test_ldap(object):
|
||||
self.ldapuri = 'ldap://%s' % ipautil.format_netloc(api.env.host)
|
||||
self.ccache = '/tmp/krb5cc_%d' % os.getuid()
|
||||
nss.nss_init_nodb()
|
||||
self.dn = str(DN(('krbprincipalname','ldap/%s@%s' % (api.env.host, api.env.realm)),
|
||||
('cn','services'),('cn','accounts'),api.env.basedn))
|
||||
self.dn = DN(('krbprincipalname','ldap/%s@%s' % (api.env.host, api.env.realm)),
|
||||
('cn','services'),('cn','accounts'),api.env.basedn)
|
||||
|
||||
def tearDown(self):
|
||||
if self.conn and self.conn.isconnected():
|
||||
@ -90,7 +90,7 @@ class test_ldap(object):
|
||||
else:
|
||||
raise nose.SkipTest("No directory manager password in %s" % pwfile)
|
||||
self.conn = ldap2(shared_instance=False, ldap_uri=self.ldapuri)
|
||||
self.conn.connect(bind_dn='cn=directory manager', bind_pw=dm_password)
|
||||
self.conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=dm_password)
|
||||
(dn, entry_attrs) = self.conn.get_entry(self.dn, ['usercertificate'])
|
||||
cert = entry_attrs.get('usercertificate')
|
||||
cert = cert[0]
|
||||
@ -120,7 +120,7 @@ class test_ldap(object):
|
||||
fp.close()
|
||||
else:
|
||||
raise nose.SkipTest("No directory manager password in %s" % pwfile)
|
||||
myapi.Backend.ldap2.connect(bind_dn="cn=Directory Manager", bind_pw=dm_password)
|
||||
myapi.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=dm_password)
|
||||
|
||||
result = myapi.Command['service_show']('ldap/%s@%s' % (api.env.host, api.env.realm,))
|
||||
entry_attrs = result['result']
|
||||
@ -145,4 +145,3 @@ class test_ldap(object):
|
||||
cert = cert[0]
|
||||
serial = unicode(x509.get_serial_number(cert, x509.DER))
|
||||
assert serial is not None
|
||||
|
||||
|
@ -21,29 +21,17 @@
|
||||
Test --setattr and --addattr and other attribute-specific issues
|
||||
"""
|
||||
|
||||
from ipalib import api, errors, x509
|
||||
from ipalib import api, errors
|
||||
from tests.test_xmlrpc import objectclasses
|
||||
from xmlrpc_test import (Declarative, fuzzy_digits, fuzzy_uuid, fuzzy_date,
|
||||
fuzzy_hex, fuzzy_hash, fuzzy_issuer)
|
||||
from ipalib.dn import *
|
||||
import base64
|
||||
from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
|
||||
from ipapython.dn import DN
|
||||
|
||||
user1 = u'tuser1'
|
||||
fqdn1 = u'testhost1.%s' % api.env.domain
|
||||
|
||||
# We can use the same cert we generated for the service tests
|
||||
fd = open('tests/test_xmlrpc/service.crt', 'r')
|
||||
servercert = fd.readlines()
|
||||
servercert = u''.join(servercert)
|
||||
servercert = x509.strip_header(servercert)
|
||||
servercert = servercert.replace('\n', '')
|
||||
fd.close()
|
||||
user1=u'tuser1'
|
||||
|
||||
class test_attr(Declarative):
|
||||
|
||||
cleanup_commands = [
|
||||
('user_del', [user1], {}),
|
||||
('host_del', [fqdn1], {}),
|
||||
]
|
||||
|
||||
tests = [
|
||||
@ -72,16 +60,13 @@ class test_attr(Declarative):
|
||||
cn=[u'Test User1'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=lambda x: [DN(i) for i in x] == \
|
||||
[DN(('cn','global_policy'),('cn',api.env.realm),
|
||||
('cn','kerberos'),api.env.basedn)],
|
||||
mepmanagedentry=lambda x: [DN(i) for i in x] == \
|
||||
[DN(('cn',user1),('cn','groups'),('cn','accounts'),
|
||||
api.env.basedn)],
|
||||
krbpwdpolicyreference=[DN(('cn','global_policy'),('cn',api.env.realm),
|
||||
('cn','kerberos'),api.env.basedn)],
|
||||
mepmanagedentry=[DN(('cn',user1),('cn','groups'),('cn','accounts'),
|
||||
api.env.basedn)],
|
||||
memberof_group=[u'ipausers'],
|
||||
dn=lambda x: DN(x) == \
|
||||
DN(('uid','tuser1'),('cn','users'),('cn','accounts'),
|
||||
api.env.basedn),
|
||||
dn=DN(('uid','tuser1'),('cn','users'),('cn','accounts'),
|
||||
api.env.basedn),
|
||||
has_keytab=False,
|
||||
has_password=False,
|
||||
),
|
||||
@ -563,71 +548,4 @@ class test_attr(Declarative):
|
||||
desc='Server is unwilling to perform', info=''),
|
||||
),
|
||||
|
||||
dict(
|
||||
desc='Try to create %r with description and --addattr description' % fqdn1,
|
||||
command=('host_add', [fqdn1],
|
||||
dict(
|
||||
description=u'Test host 1',
|
||||
addattr=u'description=Test host 2',
|
||||
force=True,
|
||||
),
|
||||
),
|
||||
expected=errors.OnlyOneValueAllowed(attr='description'),
|
||||
),
|
||||
|
||||
dict(
|
||||
desc='Create %r with a certificate' % fqdn1,
|
||||
command=('host_add', [fqdn1],
|
||||
dict(
|
||||
usercertificate=servercert,
|
||||
force=True,
|
||||
),
|
||||
),
|
||||
expected=dict(
|
||||
value=fqdn1,
|
||||
summary=u'Added host "%s"' % fqdn1,
|
||||
result=dict(
|
||||
dn=lambda x: DN(x) == DN(('fqdn',fqdn1),('cn','computers'),
|
||||
('cn','accounts'),api.env.basedn),
|
||||
fqdn=[fqdn1],
|
||||
krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)],
|
||||
objectclass=objectclasses.host,
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
managedby_host=[fqdn1],
|
||||
usercertificate=[base64.b64decode(servercert)],
|
||||
valid_not_before=fuzzy_date,
|
||||
valid_not_after=fuzzy_date,
|
||||
subject=lambda x: DN(x) == \
|
||||
DN(('CN',api.env.host),x509.subject_base()),
|
||||
serial_number=fuzzy_digits,
|
||||
serial_number_hex=fuzzy_hex,
|
||||
md5_fingerprint=fuzzy_hash,
|
||||
sha1_fingerprint=fuzzy_hash,
|
||||
issuer=fuzzy_issuer,
|
||||
has_keytab=False,
|
||||
has_password=False,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
dict(
|
||||
desc='Remove %r certificate using --delattr' % fqdn1,
|
||||
command=('host_mod', [fqdn1],
|
||||
dict(
|
||||
delattr=u'usercertificate=%s' % servercert,
|
||||
),
|
||||
),
|
||||
expected=dict(
|
||||
value=fqdn1,
|
||||
summary=u'Modified host "%s"' % fqdn1,
|
||||
result=dict(
|
||||
fqdn=[fqdn1],
|
||||
krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)],
|
||||
managedby_host=[fqdn1],
|
||||
has_keytab=False,
|
||||
has_password=False,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
]
|
||||
|
@ -22,6 +22,7 @@ Test the `ipalib/plugins/automember.py` module.
|
||||
"""
|
||||
|
||||
from ipalib import api, errors
|
||||
from ipapython.dn import DN
|
||||
from tests.test_xmlrpc import objectclasses
|
||||
from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
|
||||
|
||||
@ -132,7 +133,7 @@ class test_automember(Declarative):
|
||||
gidnumber=[fuzzy_digits],
|
||||
objectclass=objectclasses.group + [u'posixgroup'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
dn=u'cn=%s,cn=groups,cn=accounts,%s' % (group1, api.env.basedn),
|
||||
dn=DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -151,8 +152,8 @@ class test_automember(Declarative):
|
||||
description=[u'Test desc'],
|
||||
objectclass=objectclasses.hostgroup,
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
mepmanagedentry=['cn=%s,cn=ng,cn=alt,%s' % (hostgroup1, api.env.basedn)],
|
||||
dn=u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup1, api.env.basedn),
|
||||
mepmanagedentry=[DN(('cn', hostgroup1), ('cn', 'ng'), ('cn', 'alt'), api.env.basedn)],
|
||||
dn=DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -171,8 +172,8 @@ class test_automember(Declarative):
|
||||
description=[u'Test desc'],
|
||||
objectclass=objectclasses.hostgroup,
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
mepmanagedentry=['cn=%s,cn=ng,cn=alt,%s' % (hostgroup2, api.env.basedn)],
|
||||
dn=u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup2, api.env.basedn),
|
||||
mepmanagedentry=[DN(('cn', hostgroup2), ('cn', 'ng'), ('cn', 'alt'), api.env.basedn)],
|
||||
dn=DN(('cn', hostgroup2), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -191,8 +192,8 @@ class test_automember(Declarative):
|
||||
description=[u'Test desc'],
|
||||
objectclass=objectclasses.hostgroup,
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
mepmanagedentry=['cn=%s,cn=ng,cn=alt,%s' % (hostgroup3, api.env.basedn)],
|
||||
dn=u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup3, api.env.basedn),
|
||||
mepmanagedentry=[DN(('cn', hostgroup3), ('cn', 'ng'), ('cn', 'alt'), api.env.basedn)],
|
||||
dn=DN(('cn', hostgroup3), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -211,8 +212,8 @@ class test_automember(Declarative):
|
||||
description=[u'Test desc'],
|
||||
objectclass=objectclasses.hostgroup,
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
mepmanagedentry=['cn=%s,cn=ng,cn=alt,%s' % (hostgroup4, api.env.basedn)],
|
||||
dn=u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup4, api.env.basedn),
|
||||
mepmanagedentry=[DN(('cn', hostgroup4), ('cn', 'ng'), ('cn', 'alt'), api.env.basedn)],
|
||||
dn=DN(('cn', hostgroup4), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -232,7 +233,7 @@ class test_automember(Declarative):
|
||||
gidnumber=[fuzzy_digits],
|
||||
objectclass=objectclasses.group + [u'posixgroup'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
dn=u'cn=%s,cn=groups,cn=accounts,%s' % (defaultgroup1, api.env.basedn),
|
||||
dn=DN(('cn', defaultgroup1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -251,8 +252,8 @@ class test_automember(Declarative):
|
||||
description=[u'Default test desc'],
|
||||
objectclass=objectclasses.hostgroup,
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
mepmanagedentry=['cn=%s,cn=ng,cn=alt,%s' % (defaulthostgroup1, api.env.basedn)],
|
||||
dn=u'cn=%s,cn=hostgroups,cn=accounts,%s' % (defaulthostgroup1, api.env.basedn),
|
||||
mepmanagedentry=[DN(('cn', defaulthostgroup1), ('cn', 'ng'), ('cn', 'alt'), api.env.basedn)],
|
||||
dn=DN(('cn', defaulthostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -269,9 +270,9 @@ class test_automember(Declarative):
|
||||
result=dict(
|
||||
cn=[group1],
|
||||
description=[u'Test desc'],
|
||||
automembertargetgroup=[u'cn=%s,cn=groups,cn=accounts,%s' % (group1, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
objectclass=objectclasses.automember,
|
||||
dn=u'cn=%s,cn=group,cn=automember,cn=etc,%s' % (group1, api.env.basedn),
|
||||
dn=DN(('cn', group1), ('cn', 'group'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -299,7 +300,7 @@ class test_automember(Declarative):
|
||||
cn=[group1],
|
||||
description=[u'Test desc'],
|
||||
automemberinclusiveregex=[u'manager=%s' % group_include_regex],
|
||||
automembertargetgroup=[u'cn=%s,cn=groups,cn=accounts,%s' % (group1, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -318,9 +319,9 @@ class test_automember(Declarative):
|
||||
result=dict(
|
||||
cn=[hostgroup1],
|
||||
description=[u'Test desc'],
|
||||
automembertargetgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup1, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
objectclass=objectclasses.automember,
|
||||
dn=u'cn=%s,cn=hostgroup,cn=automember,cn=etc,%s' % (hostgroup1, api.env.basedn),
|
||||
dn=DN(('cn', hostgroup1), ('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -348,7 +349,7 @@ class test_automember(Declarative):
|
||||
cn=[hostgroup1],
|
||||
description=[u'Test desc'],
|
||||
automemberinclusiveregex=[u'fqdn=%s' % hostgroup_include_regex],
|
||||
automembertargetgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup1, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -401,7 +402,7 @@ class test_automember(Declarative):
|
||||
result=dict(
|
||||
cn=[hostgroup1],
|
||||
description=[u'Test desc'],
|
||||
automembertargetgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup1, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
automemberinclusiveregex=[u'fqdn=%s' % hostgroup_include_regex,
|
||||
u'fqdn=%s' % hostgroup_include_regex3,
|
||||
u'fqdn=%s' % hostgroup_include_regex2,
|
||||
@ -428,9 +429,9 @@ class test_automember(Declarative):
|
||||
result=dict(
|
||||
cn=[hostgroup2],
|
||||
description=[u'Test desc'],
|
||||
automembertargetgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup2, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', hostgroup2), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
objectclass=objectclasses.automember,
|
||||
dn=u'cn=%s,cn=hostgroup,cn=automember,cn=etc,%s' % (hostgroup2, api.env.basedn),
|
||||
dn=DN(('cn', hostgroup2), ('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -458,7 +459,7 @@ class test_automember(Declarative):
|
||||
cn=[hostgroup2],
|
||||
description=[u'Test desc'],
|
||||
automemberinclusiveregex=[u'fqdn=%s' % hostgroup_exclude_regex],
|
||||
automembertargetgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup2, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', hostgroup2), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -477,9 +478,9 @@ class test_automember(Declarative):
|
||||
result=dict(
|
||||
cn=[hostgroup3],
|
||||
description=[u'Test desc'],
|
||||
automembertargetgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup3, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', hostgroup3), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
objectclass=objectclasses.automember,
|
||||
dn=u'cn=%s,cn=hostgroup,cn=automember,cn=etc,%s' % (hostgroup3, api.env.basedn),
|
||||
dn=DN(('cn', hostgroup3), ('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -507,7 +508,7 @@ class test_automember(Declarative):
|
||||
cn=[hostgroup3],
|
||||
description=[u'Test desc'],
|
||||
automemberinclusiveregex=[u'fqdn=%s' % hostgroup_exclude_regex2],
|
||||
automembertargetgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup3, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', hostgroup3), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -526,9 +527,9 @@ class test_automember(Declarative):
|
||||
result=dict(
|
||||
cn=[hostgroup4],
|
||||
description=[u'Test desc'],
|
||||
automembertargetgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup4, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', hostgroup4), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
objectclass=objectclasses.automember,
|
||||
dn=u'cn=%s,cn=hostgroup,cn=automember,cn=etc,%s' % (hostgroup4, api.env.basedn),
|
||||
dn=DN(('cn', hostgroup4), ('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -556,7 +557,7 @@ class test_automember(Declarative):
|
||||
cn=[hostgroup4],
|
||||
description=[u'Test desc'],
|
||||
automemberinclusiveregex=[u'fqdn=%s' % hostgroup_exclude_regex3],
|
||||
automembertargetgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup4, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', hostgroup4), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -574,8 +575,8 @@ class test_automember(Declarative):
|
||||
cn=[group1],
|
||||
description=[u'Test desc'],
|
||||
automemberinclusiveregex=[u'manager=%s' % group_include_regex],
|
||||
automembertargetgroup=[u'cn=%s,cn=groups,cn=accounts,%s' % (group1, api.env.basedn)],
|
||||
dn=u'cn=%s,cn=group,cn=automember,cn=etc,%s' % (group1, api.env.basedn),
|
||||
automembertargetgroup=[DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
dn=DN(('cn', group1), ('cn', 'group'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn),
|
||||
),
|
||||
summary=None,
|
||||
),
|
||||
@ -596,8 +597,8 @@ class test_automember(Declarative):
|
||||
cn=[group1],
|
||||
description=[u'Test desc'],
|
||||
automemberinclusiveregex=[u'manager=%s' % group_include_regex],
|
||||
automembertargetgroup=[u'cn=%s,cn=groups,cn=accounts,%s' % (group1, api.env.basedn)],
|
||||
dn=u'cn=%s,cn=group,cn=automember,cn=etc,%s' % (group1, api.env.basedn),
|
||||
automembertargetgroup=[DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
dn=DN(('cn', group1), ('cn', 'group'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn),
|
||||
),
|
||||
],
|
||||
summary=u'1 rules matched',
|
||||
@ -618,7 +619,7 @@ class test_automember(Declarative):
|
||||
cn=[group1],
|
||||
description=[u'New desc 1'],
|
||||
automemberinclusiveregex=[u'manager=%s' % group_include_regex],
|
||||
automembertargetgroup=[u'cn=%s,cn=groups,cn=accounts,%s' % (group1, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', group1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
),
|
||||
summary=u'Modified automember rule "%s"' % group1,
|
||||
value=group1,
|
||||
@ -637,7 +638,7 @@ class test_automember(Declarative):
|
||||
result=dict(
|
||||
cn=[hostgroup1],
|
||||
description=[u'Test desc'],
|
||||
automembertargetgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup1, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
automemberinclusiveregex=[u'fqdn=%s' % hostgroup_include_regex,
|
||||
u'fqdn=%s' % hostgroup_include_regex3,
|
||||
u'fqdn=%s' % hostgroup_include_regex2,
|
||||
@ -646,7 +647,7 @@ class test_automember(Declarative):
|
||||
u'fqdn=%s' % hostgroup_exclude_regex3,
|
||||
u'fqdn=%s' % hostgroup_exclude_regex,
|
||||
],
|
||||
dn=u'cn=%s,cn=hostgroup,cn=automember,cn=etc,%s' % (hostgroup1, api.env.basedn),
|
||||
dn=DN(('cn', hostgroup1), ('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn),
|
||||
),
|
||||
summary=None,
|
||||
),
|
||||
@ -666,7 +667,7 @@ class test_automember(Declarative):
|
||||
dict(
|
||||
cn=[hostgroup1],
|
||||
description=[u'Test desc'],
|
||||
automembertargetgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup1, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
automemberinclusiveregex=[u'fqdn=%s' % hostgroup_include_regex,
|
||||
u'fqdn=%s' % hostgroup_include_regex3,
|
||||
u'fqdn=%s' % hostgroup_include_regex2,
|
||||
@ -675,7 +676,7 @@ class test_automember(Declarative):
|
||||
u'fqdn=%s' % hostgroup_exclude_regex3,
|
||||
u'fqdn=%s' % hostgroup_exclude_regex,
|
||||
],
|
||||
dn=u'cn=%s,cn=hostgroup,cn=automember,cn=etc,%s' % (hostgroup1, api.env.basedn),
|
||||
dn=DN(('cn', hostgroup1), ('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn),
|
||||
),
|
||||
],
|
||||
summary=u'1 rules matched',
|
||||
@ -695,7 +696,7 @@ class test_automember(Declarative):
|
||||
result=dict(
|
||||
cn=[hostgroup1],
|
||||
description=[u'New desc 1'],
|
||||
automembertargetgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup1, api.env.basedn)],
|
||||
automembertargetgroup=[DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
automemberinclusiveregex=[u'fqdn=%s' % hostgroup_include_regex,
|
||||
u'fqdn=%s' % hostgroup_include_regex3,
|
||||
u'fqdn=%s' % hostgroup_include_regex2,
|
||||
@ -722,7 +723,7 @@ class test_automember(Declarative):
|
||||
expected=dict(
|
||||
result=dict(
|
||||
cn=[u'Group'],
|
||||
automemberdefaultgroup=[u'cn=%s,cn=groups,cn=accounts,%s' % (defaultgroup1, api.env.basedn)],
|
||||
automemberdefaultgroup=[DN(('cn', defaultgroup1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
),
|
||||
value=u'group',
|
||||
summary=u'Set default (fallback) group for automember "group"',
|
||||
@ -737,9 +738,9 @@ class test_automember(Declarative):
|
||||
),
|
||||
expected=dict(
|
||||
result=dict(
|
||||
dn=u'cn=group,cn=automember,cn=etc,%s' % (api.env.basedn),
|
||||
dn=DN(('cn', 'group'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn),
|
||||
cn=[u'Group'],
|
||||
automemberdefaultgroup=[u'cn=%s,cn=groups,cn=accounts,%s' % (defaultgroup1, api.env.basedn)],
|
||||
automemberdefaultgroup=[DN(('cn', defaultgroup1), ('cn', 'groups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
),
|
||||
value=u'group',
|
||||
summary=None,
|
||||
@ -758,7 +759,7 @@ class test_automember(Declarative):
|
||||
expected=dict(
|
||||
result=dict(
|
||||
cn=[u'Hostgroup'],
|
||||
automemberdefaultgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (defaulthostgroup1, api.env.basedn)],
|
||||
automemberdefaultgroup=[DN(('cn', defaulthostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
),
|
||||
value=u'hostgroup',
|
||||
summary=u'Set default (fallback) group for automember "hostgroup"',
|
||||
@ -775,9 +776,9 @@ class test_automember(Declarative):
|
||||
),
|
||||
expected=dict(
|
||||
result=dict(
|
||||
dn=u'cn=hostgroup,cn=automember,cn=etc,%s' % (api.env.basedn),
|
||||
dn=DN(('cn', 'hostgroup'), ('cn', 'automember'), ('cn', 'etc'), api.env.basedn),
|
||||
cn=[u'Hostgroup'],
|
||||
automemberdefaultgroup=[u'cn=%s,cn=hostgroups,cn=accounts,%s' % (defaulthostgroup1, api.env.basedn)],
|
||||
automemberdefaultgroup=[DN(('cn', defaulthostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn)],
|
||||
),
|
||||
value=u'hostgroup',
|
||||
summary=None,
|
||||
@ -810,10 +811,13 @@ class test_automember(Declarative):
|
||||
cn=[u'Michael Scott'],
|
||||
initials=[u'MS'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (manager1, api.env.basedn)],
|
||||
krbpwdpolicyreference=[DN(('cn', 'global_policy'), ('cn', api.env.realm), ('cn', 'kerberos'),
|
||||
api.env.basedn)],
|
||||
mepmanagedentry=[DN(('cn', manager1), ('cn', 'groups'), ('cn', 'accounts'),
|
||||
api.env.basedn)],
|
||||
memberof_group=[u'defaultgroup1', u'ipausers'],
|
||||
dn=u'uid=mscott,cn=users,cn=accounts,' + api.env.basedn,
|
||||
dn=DN(('uid', 'mscott'), ('cn', 'users'), ('cn', 'accounts'),
|
||||
api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -840,15 +844,18 @@ class test_automember(Declarative):
|
||||
uid=[user1],
|
||||
uidnumber=[fuzzy_digits],
|
||||
gidnumber=[fuzzy_digits],
|
||||
manager=[u'uid=mscott,cn=users,cn=accounts,%s' % api.env.basedn],
|
||||
manager=[DN(('uid', 'mscott'), ('cn', 'users'), ('cn', 'accounts'), api.env.basedn)],
|
||||
displayname=[u'Test User1'],
|
||||
cn=[u'Test User1'],
|
||||
initials=[u'TU'],
|
||||
ipauniqueid=[fuzzy_uuid],
|
||||
krbpwdpolicyreference=[u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
mepmanagedentry=[u'cn=%s,cn=groups,cn=accounts,%s' % (user1, api.env.basedn)],
|
||||
krbpwdpolicyreference=[DN(('cn', 'global_policy'), ('cn', api.env.realm), ('cn', 'kerberos'),
|
||||
api.env.basedn)],
|
||||
mepmanagedentry=[DN(('cn', user1), ('cn', 'groups'), ('cn', 'accounts'),
|
||||
api.env.basedn)],
|
||||
memberof_group=[u'group1', u'ipausers'],
|
||||
dn=u'uid=tuser1,cn=users,cn=accounts,' + api.env.basedn,
|
||||
dn=DN(('uid', 'tuser1'), ('cn', 'users'), ('cn', 'accounts'),
|
||||
api.env.basedn),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -867,7 +874,7 @@ class test_automember(Declarative):
|
||||
value=fqdn1,
|
||||
summary=u'Added host "%s"' % fqdn1,
|
||||
result=dict(
|
||||
dn=u'fqdn=%s,cn=computers,cn=accounts,%s' % (fqdn1, api.env.basedn),
|
||||
dn=DN(('fqdn', fqdn1), ('cn', 'computers'), ('cn', 'accounts'), api.env.basedn),
|
||||
fqdn=[fqdn1],
|
||||
description=[u'Test host 1'],
|
||||
l=[u'Undisclosed location 1'],
|
||||
@ -895,7 +902,7 @@ class test_automember(Declarative):
|
||||
value=fqdn2,
|
||||
summary=u'Added host "%s"' % fqdn2,
|
||||
result=dict(
|
||||
dn=u'fqdn=%s,cn=computers,cn=accounts,%s' % (fqdn2, api.env.basedn),
|
||||
dn=DN(('fqdn', fqdn2), ('cn', 'computers'), ('cn', 'accounts'), api.env.basedn),
|
||||
fqdn=[fqdn2],
|
||||
description=[u'Test host 2'],
|
||||
l=[u'Undisclosed location 1'],
|
||||
@ -923,7 +930,7 @@ class test_automember(Declarative):
|
||||
value=fqdn3,
|
||||
summary=u'Added host "%s"' % fqdn3,
|
||||
result=dict(
|
||||
dn=u'fqdn=%s,cn=computers,cn=accounts,%s' % (fqdn3, api.env.basedn),
|
||||
dn=DN(('fqdn', fqdn3), ('cn', 'computers'), ('cn', 'accounts'), api.env.basedn),
|
||||
fqdn=[fqdn3],
|
||||
description=[u'Test host 3'],
|
||||
l=[u'Undisclosed location 1'],
|
||||
@ -951,7 +958,7 @@ class test_automember(Declarative):
|
||||
value=fqdn4,
|
||||
summary=u'Added host "%s"' % fqdn4,
|
||||
result=dict(
|
||||
dn=u'fqdn=%s,cn=computers,cn=accounts,%s' % (fqdn4, api.env.basedn),
|
||||
dn=DN(('fqdn', fqdn4), ('cn', 'computers'), ('cn', 'accounts'), api.env.basedn),
|
||||
fqdn=[fqdn4],
|
||||
description=[u'Test host 4'],
|
||||
l=[u'Undisclosed location 1'],
|
||||
@ -979,7 +986,7 @@ class test_automember(Declarative):
|
||||
value=fqdn5,
|
||||
summary=u'Added host "%s"' % fqdn5,
|
||||
result=dict(
|
||||
dn=u'fqdn=%s,cn=computers,cn=accounts,%s' % (fqdn5, api.env.basedn),
|
||||
dn=DN(('fqdn', fqdn5), ('cn', 'computers'), ('cn', 'accounts'), api.env.basedn),
|
||||
fqdn=[fqdn5],
|
||||
description=[u'Test host 5'],
|
||||
l=[u'Undisclosed location 1'],
|
||||
@ -1001,7 +1008,7 @@ class test_automember(Declarative):
|
||||
value=hostgroup1,
|
||||
summary=None,
|
||||
result={
|
||||
'dn': u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup1, api.env.basedn),
|
||||
'dn': DN(('cn', hostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn),
|
||||
'member_host': [u'%s' % fqdn1],
|
||||
'cn': [hostgroup1],
|
||||
'description': [u'Test desc'],
|
||||
@ -1017,7 +1024,7 @@ class test_automember(Declarative):
|
||||
value=defaulthostgroup1,
|
||||
summary=None,
|
||||
result={
|
||||
'dn': u'cn=%s,cn=hostgroups,cn=accounts,%s' % (defaulthostgroup1, api.env.basedn),
|
||||
'dn': DN(('cn', defaulthostgroup1), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn),
|
||||
'member_host': [u'%s' % fqdn2],
|
||||
'cn': [defaulthostgroup1],
|
||||
'description': [u'Default test desc'],
|
||||
@ -1033,7 +1040,7 @@ class test_automember(Declarative):
|
||||
value=hostgroup2,
|
||||
summary=None,
|
||||
result={
|
||||
'dn': u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup2, api.env.basedn),
|
||||
'dn': DN(('cn', hostgroup2), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn),
|
||||
'member_host': [u'%s' % fqdn3],
|
||||
'cn': [hostgroup2],
|
||||
'description': [u'Test desc'],
|
||||
@ -1049,7 +1056,7 @@ class test_automember(Declarative):
|
||||
value=hostgroup3,
|
||||
summary=None,
|
||||
result={
|
||||
'dn': u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup3, api.env.basedn),
|
||||
'dn': DN(('cn', hostgroup3), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn),
|
||||
'member_host': [u'%s' % fqdn4],
|
||||
'cn': [hostgroup3],
|
||||
'description': [u'Test desc'],
|
||||
@ -1065,7 +1072,7 @@ class test_automember(Declarative):
|
||||
value=hostgroup4,
|
||||
summary=None,
|
||||
result={
|
||||
'dn': u'cn=%s,cn=hostgroups,cn=accounts,%s' % (hostgroup4, api.env.basedn),
|
||||
'dn': DN(('cn', hostgroup4), ('cn', 'hostgroups'), ('cn', 'accounts'), api.env.basedn),
|
||||
'member_host': [u'%s' % fqdn5],
|
||||
'cn': [hostgroup4],
|
||||
'description': [u'Test desc'],
|
||||
|
@ -28,7 +28,7 @@ import shutil
|
||||
|
||||
from ipalib import api
|
||||
from ipalib import errors
|
||||
from ipalib.dn import DN
|
||||
from ipapython.dn import DN
|
||||
|
||||
from nose.tools import raises, assert_raises # pylint: disable=E0611
|
||||
from xmlrpc_test import XMLRPC_test, assert_attr_equal
|
||||
@ -238,40 +238,36 @@ class test_automount(AutomountTest):
|
||||
result=dict(
|
||||
keys={'auto.direct': ()},
|
||||
orphanmaps=(dict(
|
||||
dn=lambda dn: DN(dn) == DN(
|
||||
('automountmapname', self.mapname),
|
||||
('cn', self.locname),
|
||||
('cn', 'automount'), api.env.basedn),
|
||||
dn=DN(('automountmapname', self.mapname),
|
||||
('cn', self.locname),
|
||||
('cn', 'automount'), api.env.basedn),
|
||||
description=(u'description of map',),
|
||||
automountmapname=(u'testmap',)),),
|
||||
orphankeys=[(
|
||||
dict(
|
||||
dn=lambda dn: DN(dn) == DN(
|
||||
('description', self.keyname2),
|
||||
('automountmapname', 'testmap'),
|
||||
('cn', self.locname),
|
||||
('cn', 'automount'), api.env.basedn),
|
||||
dn=DN(('description', self.keyname2),
|
||||
('automountmapname', 'testmap'),
|
||||
('cn', self.locname),
|
||||
('cn', 'automount'), api.env.basedn),
|
||||
automountkey=(self.keyname2,),
|
||||
description=(self.keyname2,),
|
||||
automountinformation=(u'ro',),
|
||||
),
|
||||
dict(
|
||||
dn=lambda dn: DN(dn) == DN(
|
||||
('description', self.keyname_rename),
|
||||
('automountmapname', 'testmap'),
|
||||
('cn', self.locname),
|
||||
('cn', 'automount'), api.env.basedn),
|
||||
dn=DN(('description', self.keyname_rename),
|
||||
('automountmapname', 'testmap'),
|
||||
('cn', self.locname),
|
||||
('cn', 'automount'), api.env.basedn),
|
||||
automountkey=(self.keyname_rename,),
|
||||
description=(self.keyname_rename,),
|
||||
automountinformation=(u'rw',),
|
||||
))],
|
||||
maps=(
|
||||
dict(
|
||||
dn=lambda dn: DN(dn) == DN(
|
||||
('description', '/- auto.direct'),
|
||||
('automountmapname', 'auto.master'),
|
||||
('cn', self.locname),
|
||||
('cn', 'automount'), api.env.basedn),
|
||||
dn=DN(('description', '/- auto.direct'),
|
||||
('automountmapname', 'auto.master'),
|
||||
('cn', self.locname),
|
||||
('cn', 'automount'), api.env.basedn),
|
||||
automountkey=(u'/-',),
|
||||
description=(u'/- auto.direct',),
|
||||
automountinformation=(u'auto.direct',)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user