Bug 1044152

Summary: ChainOnUpdate: "cn=directory manager" can modify userRoot on consumer without changes being chained or replicated. Directory integrity compromised.
Product: Red Hat Enterprise Linux 7 Reporter: Nathan Kinder <nkinder>
Component: 389-ds-baseAssignee: Rich Megginson <rmeggins>
Status: CLOSED ERRATA QA Contact: Viktor Ashirov <vashirov>
Severity: unspecified Docs Contact:
Priority: high    
Version: 7.0CC: lkrispen, nhosoi, nkinder, vashirov
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: 389-ds-base-1.3.3.1-1.el7 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-03-05 09:31:40 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Nathan Kinder 2013-12-17 21:29:50 UTC
This bug is created as a clone of upstream ticket:
https://fedorahosted.org/389/ticket/314

Setup would be as follows
be1.foo.com is Master - (dc=foo,dc=com)
be2.foo.com is Consumer to be1, configured to chain on  update - (dc=foo,dc=com)

compromised 
It should be viewed as problematic that the database on a consumer could be directly modified by "cn=directory manager" and those changes are not reflected on the Master (or other masters, hubs, or consumers, for that matter) 

Hypothetically speaking... 
"cn=directory manager" could bind to be1.foo.com and modify the following dn..
dn: uid=jim,dc=foo,dc=com 
changetype: modify 
replace: sn
sn: changed on be1

I could then search be1.foo.com (Master) and be2.foo.com (consumer)
and find the value for "sn" on "uid=jim,dc=foo,dc=com" is "changed on be1" on both servers

The above makes sense.

Now, If i were to  make the same change to be2...
"cn=directory manager" binds to be2.foo.com and modifies ..
changetype: modify 
replace: sn
sn: changed on be2

I would then search be1.foo.com (Master) and find sn to have a value of "changed on be1"
a search of be2.foo.com (Consumer) would show sn has a value of "changed on be2"

It seems this could have a detrimental effect on the integrity of the environment.

Possible Options:
A) ensure "cn=directory manager"s actions on a consumer/ "chain on update" are replicated (chain directory manager's changes to userRoot);
B) prevent ^ from making changes to userRoot/(dc=foo,dc=com) that will not be replicated/chained;
C) give ^ a referral to a master if changes are destined for userRoot/(dc=foo,dc=com);
D) ?

Comment 3 Ludwig 2014-11-18 12:54:58 UTC
the 2 testscenarios and expected behaviour are described in the corresponding ticket in comment #15

Comment 4 Sankar Ramalingam 2014-11-25 09:57:53 UTC
(In reply to Ludwig from comment #3)
> the 2 testscenarios and expected behaviour are described in the
> corresponding ticket in comment #15

The correct link - https://fedorahosted.org/389/ticket/314#comment:15

Comment 5 Viktor Ashirov 2014-11-29 00:08:21 UTC
$ rpm -qa | grep 389
389-ds-base-1.3.3.1-9.el7.x86_64
389-ds-base-debuginfo-1.3.3.1-9.el7.x86_64
389-ds-base-libs-1.3.3.1-9.el7.x86_64

[0] Setup: Master-Consumer replication - M1 (1189) and C1 (1389)

[1] Configure chain on update:
1. Add aci to M1:

$ ldapmodify -v -h localhost:1189 -D "cn=Directory Manager" -w "Secret123" << EOF
dn: dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "*")(version 3.0; acl "Proxied authorization for database l
 inks";allow (proxy) (userdn = "ldap:///cn=SyncManager,cn=config");)
-
EOF


2. Add new database link DBLink1 to C1 for suffix dc=example,dc=com : 

$ ldapmodify -v -h localhost:1389 -D "cn=Directory Manager" -w "Secret123" << EOF
dn: cn=DBLink1,cn=chaining database,cn=plugins,cn=config
objectClass: top
objectClass: extensibleObject
objectClass: nsBackendInstance
cn: DBLink1
nsslapd-suffix: dc=example,dc=com
nsslapd-parent-suffix: dc=example,dc=com 
nsmultiplexorbinddn: cn=SyncManager,cn=config
nsfarmserverurl: ldap://localhost:1189/
nsmultiplexorcredentials: Secret123
EOF

3. Add second backend and distribution plugin to suffix on C1: 
$ ldapmodify -v -h localhost:1389 -D "cn=Directory Manager" -w "Secret123" << EOF
dn: cn=dc\3Dexample\2Cdc\3Dcom,cn=mapping tree,cn=config
changetype: modify
add: nsslapd-backend
nsslapd-backend: DBLink1
-
add: nsslapd-distribution-funct
nsslapd-distribution-funct: repl_chain_on_update
-
add: nsslapd-distribution-plugin
nsslapd-distribution-plugin: libreplication-plugin
-
replace: nsslapd-state
nsslapd-state: backend
-
EOF

4. Restart servers
$ sudo systemctl restart dirsrv.target

[2] Configure nsslapd-distribution-root-update:

$ ldapmodify -v -h localhost:1389 -D "cn=Directory Manager" -w "Secret123" << EOF
dn: cn=dc\3Dexample\2Cdc\3Dcom,cn=mapping tree,cn=config
changetype: modify
replace: nsslapd-distribution-root-update
nsslapd-distribution-root-update: referral
-
EOF

and restart C1

[2.1] nsslapd-distribution-root-update: referral

$ ldapmodify -v -h localhost:1389 -D "cn=Directory Manager" -w "Secret123"  << EOF
dn: ou=People,dc=example,dc=com
changetype: modify
replace: description
description: root update
EOF

ldap_initialize( ldap://localhost:1389 )
replace description:
	root update
modifying entry "ou=People,dc=example,dc=com"
ldap_modify: Referral (10)
	matched DN: dc=example,dc=com
	referrals:
		ldap://rhel7ds.brq.redhat.com:1189

Entry doesn't get updated neither on M1 nor on C1 since chaining doesn't work as root -> PASS

[2.2] nsslapd-distribution-root-update: reject

$ ldapmodify -v -h localhost:1389 -D "cn=Directory Manager" -w "Secret123"  << EOF
dn: ou=People,dc=example,dc=com
changetype: modify
replace: description
description: root update
EOF

ldap_initialize( ldap://localhost:1389 )
replace description:
	root update
modifying entry "ou=People,dc=example,dc=com"
ldap_modify: Server is unwilling to perform (53)

Entry doesn't get updated neither on M1 nor on C1 since server rejects such modifications. This is a default option, when nsslapd-distribution-root-update is not explicitly set in cn=config -> PASS


[2.3] nsslapd-distribution-root-update: local

$ ldapmodify -v -h localhost:1389 -D "cn=Directory Manager" -w "Secret123"  << EOF
dn: ou=People,dc=example,dc=com
changetype: modify
replace: description
description: root update
EOF

ldap_initialize( ldap://localhost:1389 )
replace description:
	root update
modifying entry "ou=People,dc=example,dc=com"
modify complete

On M1:
$ ldapsearch -v -h localhost:1189 -x -LLL -o ldif-wrap=no -b dc=example,dc=com '(ou=People)' description
ldap_initialize( ldap://localhost:1189 )
filter: (ou=People)
requesting: description 
dn: ou=People,dc=example,dc=com

On C1: 
$ ldapsearch -v -h localhost:1389 -x -LLL -o ldif-wrap=no -b dc=example,dc=com '(ou=People)' description
ldap_initialize( ldap://localhost:1389 )
filter: (ou=People)
requesting: description 
dn: ou=People,dc=example,dc=com
description: root update

Entry was updated on C1 -> PASS


One minor issue is that nsslapd-distribution-root-update is multivalued attribute and it can be set to contradicting values. 
Other than that everything works as expected, thus marking as VERIFIED.

Comment 7 errata-xmlrpc 2015-03-05 09:31:40 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHSA-2015-0416.html