[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: access and filters



At 01:45 PM 12/23/2003, Rosser Schwarz wrote:
>We're running OpenLDAP 2.1.25, back-ldbm, on a RH9 box and having
>a problem with access control and searches.  The brief (-ish)
>description:
>
>I'm given a uid and password (by a replacement GINA library I'm
>writing to pass Windows login credentials to a PHP/LDAP backend).
>I know I can't bind as the uid (without using SASL, which, for
>innumerable repeatedly-beating-skull-against-brick-walls sorts of
>reasons, we aren't/can't) so I bind anonymously to search for the
>cn corresponding with that uid, then, theoretically, I'd re-bind
>as that cn with the supplied password.
>
>Unfortunately, my search on uid returns no results unless I have
>an overly permissive set of access controls.  The (global) access
>portion of my slapd.conf is:
>
>access to dn=".*,ou=people,dc=company,dc=com" attr=cn,uid
>    by anonymous read break

I assume you meant dn.regex here, not dn.base.  Assuming dn.regex,
this is equivalent, better version of the directive:
  access to dn.subtree="ou=people,dc=company,dc=com" attr=cn,uid
    by users none
    by * read break

You likely didn't mean to deny authenticated users access
to cn and uid.  Also, give that "break" clause might as
well be "by * none break" since nothing below uses
additive privileges.

>access to dn=".*,ou=people,dc=company,dc=com"
>    attr=userPassword,uniqueIdentifier
>    by self write break
>    by * auth break

Everyone gets a break to non-additive clauses, so this is
a no-op.

>access to *
>    by self read break

This denies access to everyone (implicit by * none clause)
but self (since only self gets the break).

>access to *
>    by dn="cn=Manager,dc=company,dc=com" write stop
>    by dn=".*,ou=IT,ou=departments,dc=company,dc=com" write stop

When taken in combination with the previous statement,
self gets write only if self is one of "cn=Manager,dc=company,dc=com"
or subordinate to "ou=IT,ou=departments,dc=company,dc=com".

Since there is no break for this "to *" statement, remaining
directives are moot.


>access to *
>    by * none stop

Of course, the implicit last statement is:
        access to * by * none

making this statement doubly unnecessary.

>If I add an "access to * by * read" as the first ACL, my search
>works. Else, it fails, and immediately after dumping the cn I'm
>searching for, the debug log (with -d 5) says:
>
>ldbm_search: candidate entry 705 does not match filter
>
>The sole search criterion is "(uid=$uid)".  Wildcarding objectClass
>and/or cn yields the same result, as, logically it should.  I also
>have the same results whether my ACLs are global or backend-specific,
>and with or without the "break" and "stop" keywords on the rules.
>It's obviously finding the entry I want, both for its presence in
>the logs and the fact that the search works with the less restrictive
>permissions, but doesn't otherwise.
>
>I'd like to avoid giving blanket read permissions to my directory
>to the entire world if at all possible (the directory is behind a
>firewall and DMZ, but still...).  To that end, I'd appreciate any
>suggestions on how better to phrase my ACLs so my searches will
>succeed while maintaining the desired level of security.

Before you write any ACLs, you should write down what
your desired access policy.

 From what you've said here, your desired policy is something like:
        a) allow anonymous users to search for authentication
        identity (but not read entry contents)
        b) allow authentication using identity and password
        c) allow authenticated users read access to everything
        except passwords
        d) allow users to update their object
        e) allow managers to update anything and everything

Here's an off-the-cuff implementation of this policy:
        # allow anonymous users to search for authentication identity (a)
        access to attrs=cn,uid
                by anonymous search
                by * none break
        # allow (empty) entry to be returned to anonymous users
        access to attrs=entry
                by anonymous read
                by * none break
        # allow simple authentication (b)
        # allow users to update their password (but not read it) (d,c)
        # allow IT'ers to update passwords (e)
        # disallow all other access (a,c) (implicit by * none)
        access to attr=userPassword
                by anonymous auth
                by self =w
                by dn.one="ou=IT,ou=departments,dc=company,dc=com" write
        # allow user to update own object (d)
        # allow IT'ers to update passwords (e)
        # allow authenticated users to read (c)
        # disallow anonymous access (a) (implicit by * none)
        access to *
                by self write
                by dn.one="ou=IT,ou=departments,dc=company,dc=com" write
                by users read

(I assumed the rootdn is "cn=Manager,dc=company,dc=com" and hence
not subject to access control lists.)

>(As an aside, when run with the overly-permissive ACLs, I have a
>similar issue searching for the bound user's attributes once I get
>the cn and re-bind.  I think the issues are related, but I need to
>get past the above-described problem before I can really work on
>anything else.)
>
>Cheers,
>
>/rls
>
>--
>Rosser Schwarz
>Total Card, Inc.