Hello community,

here is the log from the commit of package 389-ds for openSUSE:Factory checked 
in at 2015-04-30 11:51:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/389-ds (Old)
 and      /work/SRC/openSUSE:Factory/.389-ds.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "389-ds"

Changes:
--------
--- /work/SRC/openSUSE:Factory/389-ds/389-ds.changes    2015-04-23 
08:05:18.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.389-ds.new/389-ds.changes       2015-04-30 
11:51:20.000000000 +0200
@@ -1,0 +2,7 @@
+Wed Apr 29 10:17:58 UTC 2015 - a...@ajaissle.de
+
+- Update to new upstream release 1.3.3.10
+  * One important security bug was fixed:
+    Bug 1216203 - CVE-2015-1854 389ds-base: access control bypass with modrdn
+
+-------------------------------------------------------------------

Old:
----
  389-ds-base-1.3.3.9.tar.bz2

New:
----
  389-ds-base-1.3.3.10.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ 389-ds.spec ++++++
--- /var/tmp/diff_new_pack.8URQRY/_old  2015-04-30 11:51:21.000000000 +0200
+++ /var/tmp/diff_new_pack.8URQRY/_new  2015-04-30 11:51:21.000000000 +0200
@@ -18,7 +18,7 @@
 
 Name:             389-ds
 Summary:          389 Directory Server
-Version:          1.3.3.9
+Version:          1.3.3.10
 Release:          0
 Group:            Productivity/Networking/LDAP/Servers
 License:          GPL-2.0

++++++ 389-ds-base-1.3.3.9.tar.bz2 -> 389-ds-base-1.3.3.10.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/389-ds-base-1.3.3.9/VERSION.sh 
new/389-ds-base-1.3.3.10/VERSION.sh
--- old/389-ds-base-1.3.3.9/VERSION.sh  2015-03-07 01:46:09.000000000 +0100
+++ new/389-ds-base-1.3.3.10/VERSION.sh 2015-04-28 19:16:17.000000000 +0200
@@ -10,7 +10,7 @@
 # PACKAGE_VERSION is constructed from these
 VERSION_MAJOR=1
 VERSION_MINOR=3
-VERSION_MAINT=3.9
+VERSION_MAINT=3.10
 # if this is a PRERELEASE, set VERSION_PREREL
 # otherwise, comment it out
 # be sure to include the dot prefix in the prerel
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-1.3.3.9/dirsrvtests/tickets/ticket47553_rdn_write_test.py 
new/389-ds-base-1.3.3.10/dirsrvtests/tickets/ticket47553_rdn_write_test.py
--- old/389-ds-base-1.3.3.9/dirsrvtests/tickets/ticket47553_rdn_write_test.py   
1970-01-01 01:00:00.000000000 +0100
+++ new/389-ds-base-1.3.3.10/dirsrvtests/tickets/ticket47553_rdn_write_test.py  
2015-04-28 19:16:17.000000000 +0200
@@ -0,0 +1,132 @@
+import os
+import sys
+import time
+import ldap
+import logging
+import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from lib389.utils import *
+from ldap.controls.simple import GetEffectiveRightsControl
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+installation1_prefix = None
+
+SRC_ENTRY_CN = "tuser"
+EXT_RDN = "01"
+DST_ENTRY_CN = SRC_ENTRY_CN + EXT_RDN
+
+SRC_ENTRY_DN = "cn=%s,%s" % (SRC_ENTRY_CN, SUFFIX)
+DST_ENTRY_DN = "cn=%s,%s" % (DST_ENTRY_CN, SUFFIX)
+
+class TopologyStandalone(object):
+    def __init__(self, standalone):
+        standalone.open()
+        self.standalone = standalone
+
+
+#@pytest.fixture(scope="module")
+def topology(request):
+    global installation1_prefix
+
+    # Creating standalone instance ...
+    standalone = DirSrv(verbose=False)
+    if installation1_prefix:
+        args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+    args_instance[SER_HOST] = HOST_STANDALONE
+    args_instance[SER_PORT] = PORT_STANDALONE
+    args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+    args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+    args_standalone = args_instance.copy()
+    standalone.allocate(args_standalone)
+    instance_standalone = standalone.exists()
+    if instance_standalone:
+        standalone.delete()
+    standalone.create()
+    standalone.open()
+
+    # Clear out the tmp dir
+    standalone.clearTmpDir(__file__)
+
+    return TopologyStandalone(standalone)
+
+def test_ticket47553_rdn_write_init(topology):
+    topology.standalone.log.info("\n\n######################### Add entry 
tuser ######################\n")
+    topology.standalone.add_s(Entry((SRC_ENTRY_DN, {
+                                                'objectclass': "top 
person".split(),
+                                                'sn': SRC_ENTRY_CN,
+                                                'cn': SRC_ENTRY_CN})))
+
+def test_ticket47553_rdn_write_get_ger(topology):
+    ANONYMOUS_DN = ""
+    topology.standalone.log.info("\n\n######################### GER rights for 
anonymous ######################\n")
+    request_ctrl = GetEffectiveRightsControl(criticality=True, authzId="dn:" + 
ANONYMOUS_DN)
+    msg_id = topology.standalone.search_ext(SUFFIX, ldap.SCOPE_SUBTREE, 
"objectclass=*", serverctrls=[request_ctrl])
+    rtype, rdata, rmsgid, response_ctrl = topology.standalone.result3(msg_id)
+    value = ''
+    for dn, attrs in rdata:
+        topology.standalone.log.info("dn: %s" % dn)
+        for value in attrs['entryLevelRights']:
+            topology.standalone.log.info("###############  entryLevelRights: 
%r" % value)
+            assert 'n' not in value
+
+def test_ticket47553_rdn_write_modrdn_anonymous(topology):
+    ANONYMOUS_DN = ""
+    topology.standalone.close()
+    topology.standalone.binddn = ANONYMOUS_DN
+    topology.standalone.open()
+    msg_id = topology.standalone.search_ext("", ldap.SCOPE_BASE, 
"objectclass=*")
+    rtype, rdata, rmsgid, response_ctrl = topology.standalone.result3(msg_id)
+    value = ''
+    for dn, attrs in rdata:
+        topology.standalone.log.info("dn: %s" % dn)
+        for attr in attrs:
+            topology.standalone.log.info("###############  %r: %r" % (attr, 
attrs[attr]))
+
+
+    try:
+        topology.standalone.rename_s(SRC_ENTRY_DN, "cn=%s" % DST_ENTRY_CN, 
delold=True)
+    except Exception as e:
+        topology.standalone.log.info("Exception (expected): %s" % 
type(e).__name__)
+        isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+    try:
+        topology.standalone.getEntry(DST_ENTRY_DN, ldap.SCOPE_BASE, 
"objectclass=*")
+        assert False
+    except Exception as e:
+        topology.standalone.log.info("The entry was not renamed (expected)")
+        isinstance(e, ldap.NO_SUCH_OBJECT)
+
+def test_ticket47553_rdn_write(topology):
+    '''
+    Write your testcase here...
+    '''
+
+    log.info('Test complete')
+
+
+def test_ticket47553_rdn_write_final(topology):
+    topology.standalone.delete()
+    log.info('Testcase PASSED')
+
+
+def run_isolated():
+    global installation1_prefix
+    installation1_prefix = '/home/tbordaz/install_master'
+
+    topo = topology(True)
+    test_ticket47553_rdn_write_init(topo)
+    test_ticket47553_rdn_write_get_ger(topo)
+    test_ticket47553_rdn_write(topo)
+    test_ticket47553_rdn_write_modrdn_anonymous(topo)
+    test_ticket47553_rdn_write_final(topo)
+
+
+if __name__ == '__main__':
+    run_isolated()
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-1.3.3.9/dirsrvtests/tickets/ticket47553_single_aci_test.py 
new/389-ds-base-1.3.3.10/dirsrvtests/tickets/ticket47553_single_aci_test.py
--- old/389-ds-base-1.3.3.9/dirsrvtests/tickets/ticket47553_single_aci_test.py  
2015-03-07 01:46:09.000000000 +0100
+++ new/389-ds-base-1.3.3.10/dirsrvtests/tickets/ticket47553_single_aci_test.py 
2015-04-28 19:16:17.000000000 +0200
@@ -276,7 +276,27 @@
     #topology.master1.modify_s(SUFFIX, mod)
     topology.master1.log.info("Add a DENY aci under %s " % PROD_EXCEPT_DN)
     topology.master1.modify_s(PROD_EXCEPT_DN, mod)
-    
+
+def _write_aci_staging(topology, mod_type=None):
+    assert mod_type is not None
+
+    ACI_TARGET = "(targetattr= \"cn\")(target=\"ldap:///cn=*,%s\";)" % 
STAGING_DN
+    ACI_ALLOW        = "(version 3.0; acl \"write staging entries\"; allow 
(write)"
+    ACI_SUBJECT      = " userdn = \"ldap:///%s\";;)" % BIND_DN
+    ACI_BODY         = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
+    mod = [(mod_type, 'aci', ACI_BODY)]
+    topology.master1.modify_s(SUFFIX, mod)
+
+def _write_aci_production(topology, mod_type=None):
+    assert mod_type is not None
+
+    ACI_TARGET = "(targetattr= \"cn\")(target=\"ldap:///cn=*,%s\";)" % 
PRODUCTION_DN
+    ACI_ALLOW        = "(version 3.0; acl \"write production entries\"; allow 
(write)"
+    ACI_SUBJECT      = " userdn = \"ldap:///%s\";;)" % BIND_DN
+    ACI_BODY         = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
+    mod = [(mod_type, 'aci', ACI_BODY)]
+    topology.master1.modify_s(SUFFIX, mod)
+
 def _moddn_aci_staging_to_production(topology, mod_type=None, 
target_from=STAGING_DN, target_to=PRODUCTION_DN):
     assert mod_type != None
 
@@ -293,6 +313,8 @@
     ACI_BODY         = ACI_TARGET_FROM + ACI_TARGET_TO + ACI_ALLOW + 
ACI_SUBJECT
     mod = [(mod_type, 'aci', ACI_BODY)]
     topology.master1.modify_s(SUFFIX, mod)
+    
+    _write_aci_staging(topology, mod_type=mod_type)
 
 def _moddn_aci_from_production_to_staging(topology, mod_type=None):
     assert mod_type != None
@@ -303,6 +325,8 @@
     ACI_BODY         = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
     mod = [(mod_type, 'aci', ACI_BODY)]
     topology.master1.modify_s(SUFFIX, mod)
+    
+    _write_aci_production(topology, mod_type=mod_type)
 
 
 def test_ticket47553_init(topology):
@@ -347,12 +371,9 @@
                                             'description': "production except 
DIT"})))
     
     # enable acl error logging
-    #mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '128')]
-    #topology.master1.modify_s(DN_CONFIG, mod)
-    #topology.master2.modify_s(DN_CONFIG, mod)
-    
-
-    
+    mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', str(128+262144))]
+    topology.master1.modify_s(DN_CONFIG, mod)
+    topology.master2.modify_s(DN_CONFIG, mod)
     
     
     # add dummy entries in the staging DIT
@@ -883,6 +904,7 @@
     _bind_manager(topology)
     mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
     topology.master1.modify_s(PRODUCTION_DN, mod)
+    _write_aci_staging(topology, mod_type=ldap.MOD_ADD)
     _bind_normal(topology)
     
     topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, 
new_superior))
@@ -891,6 +913,7 @@
     _bind_manager(topology)
     mod = [(ldap.MOD_DELETE, 'aci', ACI_BODY)]
     topology.master1.modify_s(PRODUCTION_DN, mod)
+    _write_aci_staging(topology, mod_type=ldap.MOD_DELETE)
     _bind_normal(topology)
     
     
@@ -934,6 +957,7 @@
     _bind_manager(topology)
     mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
     topology.master1.modify_s(PRODUCTION_DN, mod)
+    _write_aci_staging(topology, mod_type=ldap.MOD_ADD)
     _bind_normal(topology)
     
     try:
@@ -949,6 +973,7 @@
     _bind_manager(topology)
     mod = [(ldap.MOD_DELETE, 'aci', ACI_BODY)]
     topology.master1.modify_s(PRODUCTION_DN, mod)
+    _write_aci_staging(topology, mod_type=ldap.MOD_DELETE)
     _bind_normal(topology)
     
     # Add the moddn aci that will be evaluated because of the config flag
@@ -1009,7 +1034,12 @@
     old_dn  = "%s,%s" % (old_rdn, PRODUCTION_DN)
     new_rdn = old_rdn
     new_superior = STAGING_DN
-    
+
+    # add the write right because we want to check the moddn
+    _bind_manager(topology)
+    _write_aci_production(topology, mod_type=ldap.MOD_ADD)
+    _bind_normal(topology)
+
     try:
         topology.master1.log.info("Try to move back MODDN %s -> %s,%s" % 
(old_dn, new_rdn, new_superior))
         topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
@@ -1019,7 +1049,11 @@
     except Exception as e:
         topology.master1.log.info("Exception (expected): %s" % 
type(e).__name__)
         assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
-    
+
+    _bind_manager(topology)
+    _write_aci_production(topology, mod_type=ldap.MOD_DELETE)
+    _bind_normal(topology)
+
     # successfull MOD with the both ACI
     _bind_manager(topology)
     _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, 
target_from=STAGING_DN, target_to=PRODUCTION_DN)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-1.3.3.9/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c 
new/389-ds-base-1.3.3.10/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
--- old/389-ds-base-1.3.3.9/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c  
2015-03-07 01:46:09.000000000 +0100
+++ new/389-ds-base-1.3.3.10/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c 
2015-04-28 19:16:17.000000000 +0200
@@ -677,31 +677,17 @@
             
             /* JCMACL - Should be performed before the child check. */
             /* JCMACL - Why is the check performed against the copy, rather 
than the existing entry? */
+            /* This check must be performed even if the entry is renamed with 
its own name 
+             * No optimization here we need to check we have the write access 
to the target entry
+             */
+            ldap_result_code = plugin_call_acl_plugin(pb, ec->ep_entry,
+                    NULL /*attr*/, NULL /*value*/, SLAPI_ACL_WRITE,
+                    ACLPLUGIN_ACCESS_MODRDN, &errbuf);
+            if (ldap_result_code != LDAP_SUCCESS)
             {
-                Slapi_RDN *new_rdn;
-                Slapi_RDN *old_rdn;
+                goto error_return;
+            }
 
-                /* Taken from the entry */
-                old_rdn = slapi_entry_get_srdn(ec->ep_entry);
-
-                /* Taken from the request */
-                new_rdn = slapi_rdn_new();
-                slapi_sdn_get_rdn(&dn_newrdn, new_rdn);
-
-                /* Only if we change the RDN value, we need the write access 
to the entry */
-                if (slapi_rdn_compare(old_rdn, new_rdn)) {
-                        ldap_result_code = plugin_call_acl_plugin(pb, 
ec->ep_entry,
-                                NULL /*attr*/, NULL /*value*/, SLAPI_ACL_WRITE,
-                                ACLPLUGIN_ACCESS_MODRDN, &errbuf);
-                }
-
-                slapi_rdn_free(&new_rdn);
-
-                if (ldap_result_code != LDAP_SUCCESS) {
-                        goto error_return;
-                }
-            } 
-        
             /* Set the new dn to the copy of the entry */
             slapi_entry_set_sdn( ec->ep_entry, &dn_newdn );
             if (entryrdn_get_switch()) { /* subtree-rename: on */


Reply via email to