Is there any way to use the idassert feature ONLY for anonymous connections,
while allowing all other binddns to be directly proxied as themselves?
I ask because we have root LDAP servers that have ACL configurations that work
for our purposes, and we don't want to change them. We also do not allow
anonymous binds to our root servers. To be clear, we do not want to change
anything whatsoever on our root servers.
however, some clients do need to be able to bind anonymously. We're ok with
this, as long as anonymous is allowed against LDAP proxies only, and not on our
root LDAP servers. This way, we can control what anonymous user sees.
I am trying to make the proxy behave in the following ways:
* authenticated non-admin Users may bind as themselves, they can see groups,
etc., (anything non-confidential) but can only see their own account (we have
this one working, but is an essential element of the larger picture)
* anonymous users see all of the same non-sensitive material, but no user
accounts whatsoever
* there are proxybind users in our DIT, one for read-ops and one for
write-ops. The writer-proxybind user typically is needed for changing a users'
password, etc. The read user is the one that performs lookups for strictly
read-only operations. He can see all users.
If I set the idassert-bind to the read-only user, then no one can do writes. If
i set it to the write-user, then everyone (even those who shouldn't) can do
writes (except anonymous, which is good). The understanding I have is that we
should be setting the proxy user in slapd's proxy config to be the
highest-privileged user that we're ok with being "asserted". For example, we're
not asserting to the rootdn or anything, rather we assert to a bind user that is
designed to read the very information that the proxy is designed to lookup.
Here is our running config, though its been hacked up so much you should
understand its probably not perfect around the edges. Also ignore the comments
as they haven't been updated with the rest of the real parameters.
PS - I tried to upload as anonymous to your ftp and got this:
local: j-gropefruit-100114.txt remote: j-gropefruit-100114.txt
229 Entering Extended Passive Mode (|||60518|)
553 j-gropefruit-100114.txt: Permission denied.
So you'll just have to read it here:
###################################
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/misc.schema
include /etc/ldap/schema/openldap.schema
include /etc/ldap/schema/duaconf.schema
include /etc/ldap/schema/dyngroup.schema
include /etc/ldap/schema/ppolicy.schema
include /etc/ldap/schema/sudo.schema
include /etc/ldap/schema/dhcp.schema
include /etc/ldap/schema/samba.schema
include /usr/share/doc/libpam-ldap/ldapns.schema
include /etc/ldap/schema/hdb.schema
include /etc/ldap/schema/uber.schema
pidfile /var/run/slapd/slapd.pid
argsfile /var/run/slapd/slapd.args
loglevel stats stats2 conns parse
idletimeout 0
sizelimit unlimited
timelimit unlimited
defaultsearchbase dc=fake,dc=example,dc=com
limits dn.regex="^uid=([^,]+).,cn=plain,*"
time.soft=unlimited
time.hard=unlimited
size.soft=unlimited
size.hard=unlimited
access to dn.base=""
by * read
access to dn.base="cn=Subschema"
by * read
## Load modules here
modulepath /usr/lib/ldap
moduleload back_relay
moduleload back_ldap
moduleload back_hdb
moduleload pcache
moduleload rwm.la
## SSL/TLS
TLSCertificateFile /etc/ldap/ssl/wildcard.fake.example.com.crt
TLSCertificateKeyFile /etc/ldap/ssl/wildcard.fake.example.com.key
TLSCACertificateFile /etc/ldap/ssl/wildcard.fake.example.com.pem
## This is for SASL/GSSAPI authentication
sasl-realm FAKE.EXAMPLE.COM
sasl-host ds-fake-int.fake.example.com
authz-regexp "uid=\(.*\),cn=FAKE.EXAMPLE.COM,cn=gssapi,cn=auth"
"uid=$1,cn=plain,cn=auth,dc=real,dc=example,dc=com"
authz-regexp "uid=\(.*\),cn=DEV.EXAMPLE.COM,cn=gssapi,cn=auth"
"uid=$1,cn=plain,cn=auth,cn=dev,dc=real,dc=example,dc=com"
## Define the actual 'database', as referenced by the suffix.
database ldap
uri ldaps://10.9.8.7:636/
suffix "dc=real,dc=example,dc=com"
rootdn "uid=rootdn,cn=plain,cn=auth,dc=real,dc=example,dc=com"
overlay rwm
rwm-rewriteEngine on
# all dataflow from server to client
rwm-rewriteContext searchEntryDN
rwm-rewriteRule "(.+,)?dc=real,dc=example,dc=com$"
"$1dc=fake,dc=example,dc=com"
## When proxying information, configure what identity to assert.
#acl-bind
# bindmethod="simple"
# binddn="uid=plainproxy,cn=plain,cn=auth,dc=real,dc=example,dc=com"
# credentials="pass"
# starttls="no"
# tls_reqcert="never"
idassert-bind
bindmethod="simple"
binddn="uid=plainchange,cn=plain,cn=auth,dc=real,dc=example,dc=com"
credentials="pass"
starttls="no"
tls_reqcert="never"
mode="legacy"
flags="override,non-prescriptive"
idassert-authzFrom "dn.subtree:cn=plain,cn=auth,dc=real,dc=example,dc=com"
idassert-authzFrom "dn.subtree:cn=plain,cn=auth,dc=real,dc=example,dc=com"
idassert-authzFrom "dn.exact:"
chase-referrals NO
rebind-as-user NO
## Cache data for PERFORMANCE - this only works when the upstream proxy
## is online. There's no way to cache data in its entirety if the provider
## goes down (that's what actual replication is for).
overlay pcache
proxycache hdb 2000 5 100 1800
directory "/var/lib/ldap/cache"
dbconfig set_cachesize 0 4097152 0
dbconfig set_lg_regionmax 1048576
dbconfig set_lg_max 1048576
dbconfig set_lg_dir /var/lib/ldap/cache
dbconfig set_tmp_dir /tmp
index uid,cn,sn,givenName eq,sub
index uidNumber,gidNumber eq
index homeDirectory,loginShell,gecos,objectClass eq
proxycachequeries 10000
proxyattrset 0 uid userPassword uidNumber gidNumber cn homeDirectory loginShell
gecos description objectClass
proxytemplate (&(objectclass=)(uidNumber=)) 0 1200
proxytemplate (&(objectclass=)(uid=)) 0 1200
proxyattrset 1 objectclass
proxytemplate (objectclass=) 1 1200
proxyattrset 2 uid
proxytemplate (uid=) 2 1200
proxyattrset 3 cn nisNetgroupTriple memberNisNetgroup
proxytemplate (&(objectClass=)(cn=)) 3 1200
proxyattrset 4 gidNumber
proxytemplate (&(objectClass=)(memberUid=)) 4 1200
## Set a global rule to allow everything to our service/proxy users, then
forbid
## all others access, but BREAK the rule so it keeps processing the rest of the
rules,
## which are all much less-permissive ...
access to dn.subtree="dc=real,dc=example,dc=com"
by group/groupOfUniqueNames/uniqueMember="cn=ldapadmin,cn=ldap,cn=groups,dc=real,dc=example,dc=com"
write
by dn.regex="^uid=plain\(modify|change\),cn=plain,cn=auth,dc=real,dc=example,dc=com"
write
by dn.regex="^uid=plain\(proxy|agent\),cn=plain,cn=auth,dc=real,dc=example,dc=com"
read
by * none break
access to attrs=userPassword
by self =w
by * =x
## OMFGZZZZ the Solipsism rule - if you touch this I will kill you.
## This fixes the MUST-BIND-AS-SELF logic problem with Sun VDI
access to dn.regex="^uid=([^,]+),cn=plain,cn=auth,dc=real,dc=example,dc=com"
by dn.base,expand="uid=$1,cn=plain,cn=auth,dc=real,dc=example,dc=com" read
by * none break
########## Relay Instance for the "fake" zone
database relay
suffix dc=fake,dc=example,dc=com
relay dc=real,dc=example,dc=com
overlay rwm
rwm-suffixmassage dc=real,dc=example,dc=com
rwm-rewriteEngine on
rwm-normalize-mapped-attrs yes
rwm-rewriteContext searchAttrDN
rwm-rewriteRule "(.+,)?dc=real,dc=example,dc=com$"
"$1dc=fake,dc=example,dc=com"
access to dn.subtree="dc=fake,dc=example,dc=com"
by group/groupOfUniqueNames/uniqueMember="cn=ldapadmin,cn=ldap,cn=groups,dc=real,dc=example,dc=com"
write
by dn.exact="uid=plainchange,cn=plain,cn=auth,dc=real,dc=example,dc=com"
read
by dn.exact="uid=plainmodify,cn=plain,cn=auth,dc=real,dc=example,dc=com"
read
by dn.exact="uid=plainproxy,cn=plain,cn=auth,dc=real,dc=example,dc=com" read
by dn.exact="uid=plainagent,cn=plain,cn=auth,dc=real,dc=example,dc=com" read
by * none break
access to dn.children="cn=plain,cn=auth,dc=fake,dc=example,dc=com"
attrs=userPassword
filter=(&(uid=*)(|(objectClass=posixAccount)(objectClass=simpleSecurityObject)(objectClass=shadowAccount)(objectClass=inetOrgPerson)(objectClass=account)))
by self write
by dn.exact="uid=plainchange,cn=plain,cn=auth,dc=real,dc=example,dc=com"
write
by dn.exact="uid=plainmodify,cn=plain,cn=auth,dc=real,dc=example,dc=com"
write
by anonymous auth
by * none break
access to dn.children="cn=plain,cn=auth,dc=fake,dc=example,dc=com"
filter=(&(uid=*)(|(objectClass=posixAccount)(objectClass=simpleSecurityObject)(objectClass=shadowAccount)(objectClass=inetOrgPerson)(objectClass=account)))
by self read
by dn.exact="uid=plainchange,cn=plain,cn=auth,dc=real,dc=example,dc=com"
read
by dn.exact="uid=plainmodify,cn=plain,cn=auth,dc=real,dc=example,dc=com"
read
by dn.exact="uid=plainproxy,cn=plain,cn=auth,dc=real,dc=example,dc=com" read
by dn.exact="uid=plainagent,cn=plain,cn=auth,dc=real,dc=example,dc=com" read
by * none break
access to dn.subtree="cn=groups,dc=fake,dc=example,dc=com"
filter=(|(objectClass=posixGroup)(objectClass=nisNetgroup)(objectClass=groupOfUniqueNames)(objectClass=groupOfNames)(objectClass=organizationalRole))
by dn.exact="uid=plainmodify,cn=plain,cn=auth,dc=real,dc=example,dc=com"
read
by dn.exact="uid=plainchange,cn=plain,cn=auth,dc=real,dc=example,dc=com"
read
by dn.exact="uid=plainagent,cn=plain,cn=auth,dc=real,dc=example,dc=com" read
by dn.exact="uid=plainproxy,cn=plain,cn=auth,dc=real,dc=example,dc=com" read
by anonymous read
by * none break
access to dn.onelevel="cn=gssapi,cn=auth,dc=fake,dc=example,dc=com"
by dn="uidNumber=0+gidNumber=0,cn=peercred,cn=external,cn=auth" read
by * none break
access to dn.onelevel="cn=FAKE.EXAMPLE.COM,cn=gssapi,cn=auth,dc=fake,dc=example,dc=com"
by dn="uidNumber=0+gidNumber=0,cn=peercred,cn=external,cn=auth" write
by * none break
access to dn.subtree="cn=sys,dc=fake,dc=example,dc=com"
by * read
access to dn.subtree="cn=tester,dc=fake,dc=example,dc=com"
by * read
access to dn.subtree="cn=dev,dc=fake,dc=example,dc=com"
by * none
access to dn.subtree="cn=elements,dc=fake,dc=example,dc=com"
by * none
###################################
The man pages and examples on OpenLDAP.org have helped tremendously, but I need some
living & breathing opinions. Thanks
J