Commit Graph

27 Commits

Author SHA1 Message Date
Jan Cholasta
9beb467d98 Fix attempted write to attribute of read-only object.
Add new class "cachedproperty" for creating property-like attributes
that cache the return value of a method call.

Also fix few issues in the unit tests to enable them to succeed.

ticket 1959
2012-01-02 11:51:26 +03:00
Martin Kosek
8526f65f59 Add connection failure recovery to IPAdmin
Recover from connection failures in IPAdmin LDAP bind functions and
rather try reconnect in scope of a given timeout instead of giving
up after the first failed connection.

The recovery fixes ipa-ldap-updater on F-16 which always failed
because of a missing dirsrv socket.

https://fedorahosted.org/freeipa/ticket/2175
2011-12-08 14:58:18 +01:00
John Dennis
39adb6d3a8 ticket #1870 - subclass SimpleLDAPObject
We use convenience types (classes) in IPA which make working with LDAP
easier and more robust. It would be really nice if the basic python-ldap
library understood our utility types and could accept them as parameters
to the basic ldap functions and/or the basic ldap functions returned our
utility types.

Normally such a requirement would trivially be handled in an object-
oriented language (which Python is) by subclassing to extend and modify
the functionality. For some reason we didn't do this with the python-ldap
classes.

python-ldap objects are primarily used in two different places in our
code, ipaserver.ipaldap.py for the IPAdmin class and in
ipaserver/plugins/ldap2.py for the ldap2 class's .conn member.

In IPAdmin we use a IPA utility class called Entry to make it easier to
use the results returned by LDAP. The IPAdmin class is derived from
python-ldap.SimpleLDAPObject. But for some reason when we added the
support for the use of the Entry class in SimpleLDAPObject we didn't
subclass SimpleLDAPObject and extend it for use with the Entry class as
would be the normal expected methodology in an object-oriented language,
rather we used an obscure feature of the Python language to override all
methods of the SimpleLDAPObject class by wrapping those class methods in
another function call. The reason why this isn't a good approach is:

* It violates object-oriented methodology.

* Other classes cannot be derived and inherit the customization (because
the method wrapping occurs in a class instance, not within the class
type).

* It's non-obvious and obscure

* It's inefficient.

Here is a summary of what the code was doing:

It iterated over every member of the SimpleLDAPObject class and if it was
callable it wrapped the method. The wrapper function tested the name of
the method being wrapped, if it was one of a handful of methods we wanted
to customize we modified a parameter and called the original method. If
the method wasn't of interest to use we still wrapped the method.

It was inefficient because every non-customized method (the majority)
executed a function call for the wrapper, the wrapper during run-time used
logic to determine if the method was being overridden and then called the
original method. So every call to ldap was doing extra function calls and
logic processing which for the majority of cases produced nothing useful
(and was non-obvious from brief code reading some methods were being
overridden).

Object-orientated languages have support built in for calling the right
method for a given class object that do not involve extra function call
overhead to realize customized class behaviour. Also when programmers look
for customized class behaviour they look for derived classes. They might
also want to utilize the customized class as the base class for their use.

Also the wrapper logic was fragile, it did things like: if the method name
begins with "add" I'll unconditionally modify the first and second
argument. It would be some much cleaner if the "add", "add_s", etc.
methods were overridden in a subclass where the logic could be seen and
where it would apply to only the explicit functions and parameters being
overridden.

Also we would really benefit if there were classes which could be used as
a base class which had specific ldap customization.

At the moment our ldap customization needs are:

1) Support DN objects being passed to ldap operations

2) Support Entry & Entity objects being passed into and returned from
ldap operations.

We want to subclass the ldap SimpleLDAPObject class, that is the base
ldap class with all the ldap methods we're using. IPASimpleLDAPObject
class would subclass SimpleLDAPObject class which knows about DN
objects (and possilby other IPA specific types that are universally
used in IPA). Then  IPAEntrySimpleLDAPObject would subclass
IPASimpleLDAPObject which knows about Entry objects.

The reason for the suggested class hierarchy is because DN objects will be
used whenever we talk to LDAP (in the future we may want to add other IPA
specific classes which will always be used). We don't add Entry support to
the the IPASimpleLDAPObject class because Entry objects are (currently)
only used in IPAdmin.

What this patch does is:

* Introduce IPASimpleLDAPObject derived from
  SimpleLDAPObject. IPASimpleLDAPObject is DN object aware.

* Introduce IPAEntryLDAPObject derived from
  IPASimpleLDAPObject. IPAEntryLDAPObject is Entry object aware.

* Derive IPAdmin from IPAEntryLDAPObject and remove the funky method
  wrapping from IPAdmin.

* Code which called add_s() with an Entry or Entity object now calls
  addEntry(). addEntry() always existed, it just wasn't always
  used. add_s() had been modified to accept Entry or Entity object
  (why didn't we just call addEntry()?). The add*() ldap routine in
  IPAEntryLDAPObject have been subclassed to accept Entry and Entity
  objects, but that should proably be removed in the future and just
  use addEntry().

* Replace the call to ldap.initialize() in ldap2.create_connection()
  with a class constructor for IPASimpleLDAPObject. The
  ldap.initialize() is a convenience function in python-ldap, but it
  always returns a SimpleLDAPObject created via the SimpleLDAPObject
  constructor, thus ldap.initialize() did not allow subclassing, yet
  has no particular ease-of-use advantage thus we better off using the
  obvious class constructor mechanism.

* Fix the use of _handle_errors(), it's not necessary to construct an
  empty dict to pass to it.

If we follow the standard class derivation pattern for ldap we can make us
of our own ldap utilities in a far easier, cleaner and more efficient
manner.
2011-11-29 13:31:18 +01:00
John Dennis
e1c1fcf543 Ticket #1879 - IPAdmin undefined anonymous parameter lists
The IPAdmin class in ipaserver/ipaldap.py has methods with anonymous
undefined parameter lists.

For example:

    def getList(self,*args):

In Python syntax this means you can call getList with any positional
parameter list you want.

This is bad because:

1) It's not true, *args gets passed to an ldap function with a well
defined parameter list, so you really do have to call it with a
defined parameter list. *args will let you pass anything, but once it
gets passed to the ldap function it will blow up if the parameters do
not match (what parameters are those you're wondering? see item 2).

2) The programmer does not know what the valid parameters are unless
they are defined in the formal parameter list.

3) Without a formal parameter list automatic documentation generators
cannot produce API documentation (see item 2)

4) The Python interpreter cannot validate the parameters being passed
because there is no formal parameter list. Note, Python does not
validate the type of parameters, but it does validate the correct
number of postitional parameters are passed and only defined keyword
parameters are passed. Bypassing the language support facilities leads
to programming errors.

5) Without a formal parameter list program checkers such as pylint
cannot validate the program which leads to progamming errors.

6) Without a formal parameter list which includes default keyword
parameters it's not possible to use keyword arguments nor to know what
their default values are (see item 2). One is forced to pass a keyword
argument as a positional argument, plus you must then pass every
keyword argument between the end of the positional argument list and
keyword arg of interest even of the other keyword arguments are not of
interest. This also demands you know what the default value of the
intermediate keyword arguments are (see item 2) and hope they don't
change.

Also the *args anonymous tuple get passed into the error handling code
so it can report what the called values were. But because the tuple is
anonymous the error handler cannot not describe what it was passed. In
addition the error handling code makes assumptions about the possible
contents of the anonymous tuple based on current practice instead of
actual defined values. Things like "if the number of items in the
tuple is 2 or less then the first tuple item must be a dn
(Distinguished Name)" or "if the number of items in the tuple is
greater than 2 then the 3rd item must be an ldap search filter". These
are constructs which are not robust and will fail at some point in the
future.

This patch also fixes the use of IPAdmin.addEntry(). It was sometimes
being called with (dn, modlist), sometimes a Entry object, or
sometimes a Entity object. Now it's always called with either a Entry
or Entity object and IPAdmin.addEntry() validates the type of the
parameter passed.
2011-11-29 13:30:57 +01:00
Rob Crittenden
9a4fd254ff Work around limits not being updatable in 389-ds.
The bug to fix updates, BZ 741744, isn't working. For the short
term add the attributes we want to update to the REPLACE
whitelist so rather than using an ADD and DEL operation it will
use a REPLACE.

https://fedorahosted.org/freeipa/ticket/1888
2011-10-12 22:42:07 -04:00
Jan Cholasta
12bfed37d4 Add a function for formatting network locations of the form host:port for use in URLs.
If the host part is a literal IPv6 address, it must be enclosed in square
brackets (RFC 2732).

ticket 1869
2011-10-05 10:58:25 +02:00
John Dennis
442973edc5 Clean up existing DN object usage 2011-07-29 13:13:55 +02:00
Alexander Bokovoy
b93e0b8bbf Convert nsaccountlock to always work as bool towards Python code
https://fedorahosted.org/freeipa/ticket/1259

Python code will see nsaccountlock as bool. JavaScript code will also see it as bool.

This allows native boolean operations with the lock field. Passes both CLI and WebUI tests.
2011-07-13 12:02:46 +02:00
Rob Crittenden
00abd47de4 Enable 389-ds SSL host checking by defauilt
Enforce that the remote hostname matches the remote SSL server certificate
when 389-ds operates as an SSL client.

Also add an update file to turn this off for existing installations.

This also changes the way the ldapupdater modlist is generated to be more
like the framework. Single-value attributes are done as replacements
and there is a list of force-replacement attributes.

ticket 1069
2011-05-20 10:08:11 -04:00
Rob Crittenden
46a3411420 Wait for memberof task and DS to start before proceeding in installation.
This was causing a replica DS instance to crash if the task was not
completed when we attempted a shutdown to do a restart.

In replication.py we were restarting the DS instance without waiting
for the ports to become available.

It is unlikely that the dn of the memberof task will change but just in
case I noted it in the two places it is referenced.

ticket 1188
2011-04-22 11:43:50 +02:00
Rob Crittenden
b9a2c11d6f Fix ORDERING in some attributetypes and remove other unnecessary elements.
Looking at the schema in 60basev2.ldif there were many attributes that did
not have an ORDERING matching rule specified correctly. There were also a
number of attributeTypes that should have been just SUP
distinguishedName that had a combination of SUP, SYNTAX, ORDERING, etc.

This requires 389-ds-base-1.2.8.0-1+

ticket 1153
2011-04-05 21:46:32 -04:00
Simo Sorce
2028695d88 Use wrapper for sasl gssapi binds so it behaves like other binds
By calling directly sasl_interactive_bind_s() we were not calling __lateinit()
This in turn resulted in some variables like dbdir not to be set on the
IPAadmin object.
Keep all bind types in the same place so the same common sbind steps can be
performed in each case.

Related to: https://fedorahosted.org/freeipa/ticket/1022
2011-03-01 11:02:55 -05:00
Jakub Hrozek
ab2ca8022e Fix assorted bugs found by pylint 2011-01-25 14:01:36 -05:00
Simo Sorce
1cf67fe850 Remove common entries when deleting a master.
Fixes: https://fedorahosted.org/freeipa/ticket/550
2010-12-21 17:28:13 -05:00
Jakub Hrozek
7493d781df Change FreeIPA license to GPLv3+
The changes include:
 * Change license blobs in source files to mention GPLv3+ not GPLv2 only
 * Add GPLv3+ license text
 * Package COPYING not LICENSE as the license blobs (even the old ones)
   mention COPYING specifically, it is also more common, I think

 https://fedorahosted.org/freeipa/ticket/239
2010-12-20 17:19:53 -05:00
Rob Crittenden
b29de6bf27 Add LDAP upgrade over ldapi support.
This disables all but the ldapi listener in DS so it will be quiet when
we perform our upgrades. It is expected that any other clients that
also use ldapi will be shut down by other already (krb5 and dns).

Add ldapi as an option in ipaldap and add the beginning of pure offline
support (e.g. direct editing of LDIF files).
2010-06-01 09:52:10 -04:00
Rob Crittenden
9147f0da69 Don't pass non-existent arguments to _handle_errors() 2009-05-19 09:48:35 -04:00
Rob Crittenden
1c31b5bc08 Add a reason to the NotFound exception so we can provide more robust errors 2009-05-13 14:16:44 -04:00
Rob Crittenden
064240def3 Fix replica installation for self-signed CA (no dogtag) 2009-05-04 17:42:03 -04:00
Pavel Zuna
7d0bd4b895 Rename errors2.py to errors.py. Modify all affected files. 2009-04-23 10:29:14 -04:00
Rob Crittenden
64fa3dd4c3 Finish work replacing the errors module with errors2
Once this is committed we can start the process of renaming errors2 as errors.
I thought that combinig this into one commit would be more difficult to
review.
2009-04-20 13:58:26 -04:00
Rob Crittenden
233a4cb5fd Raise a more specific error when a user lacks the proper permissions.
The info part of the message will contain details on what permission
failed on what attribute.
2009-03-25 11:02:44 -04:00
Rob Crittenden
3fdf9abfce Enforce netgroup uniqueness, allow netgroups to be members of netgroups
When adding an entry, convert a constraint violation of "already exists"
into a DuplicateEntry exception so the user gets a useful response
2009-02-27 12:57:21 -05:00
Rob Crittenden
412104e34c Remove more unused files and functions, replace ipaerror with new error classes 2009-02-06 15:25:34 -05:00
Rob Crittenden
5717c9d668 Applied Rob's errors patch 2009-02-03 15:29:04 -05:00
Rob Crittenden
785851bf66 Add new method, delAttr(), to completely remove an attribute
Fix some errors that weren't being raised properly
2009-01-19 10:40:11 -05:00
Jason Gerard DeRose
7442ad2e27 Renamed ipa_server/ to ipaserver/ and tests/test_ipa_server/ to tests/test_ipaserver 2009-01-04 18:44:16 -07:00