|
|
dc8c34 |
From 075e22b5f19eea42f7985aafb25055919b6ec2d8 Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
dc8c34 |
Date: Tue, 18 Nov 2014 09:24:21 -0500
|
|
|
dc8c34 |
Subject: [PATCH 275/305] Ticket 47950 - Bind DN tracking unable to write to
|
|
|
dc8c34 |
internalModifiersName without special permissions
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Bug Description: When a non-rootDN entry makes an update when plugin bind dn tracking
|
|
|
dc8c34 |
is enabled, it is incorrectly rejected with an error 50.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Fix Description: Create a function to check if an attribute is one of last mod attributes,
|
|
|
dc8c34 |
including the internalModfieresname/internalModifytimestamp. Use this
|
|
|
dc8c34 |
new function wherever we are checking for last mod attributes.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/47950
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Reviewed by: rmeggins(Thanks!)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
(cherry picked from commit c973e7150cf1e7fb3f61a76cf1baf3c0fa91f756)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Conflicts:
|
|
|
dc8c34 |
ldap/servers/plugins/acl/acl.c
|
|
|
dc8c34 |
ldap/servers/slapd/configdse.c
|
|
|
dc8c34 |
|
|
|
dc8c34 |
(cherry picked from commit 0c47dfb627ab4fc5f7d8d067028cc74c90f61dad)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
dirsrvtests/tickets/ticket47950_test.py | 273 +++++++++++++++++++++
|
|
|
dc8c34 |
ldap/servers/plugins/acl/acl.c | 6 +-
|
|
|
dc8c34 |
ldap/servers/plugins/replication/cl5_config.c | 9 +-
|
|
|
dc8c34 |
ldap/servers/plugins/replication/repl5_agmtlist.c | 3 +-
|
|
|
dc8c34 |
.../plugins/replication/repl5_replica_config.c | 3 +-
|
|
|
dc8c34 |
ldap/servers/slapd/add.c | 4 +-
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/ldbm_config.c | 3 +-
|
|
|
dc8c34 |
ldap/servers/slapd/configdse.c | 5 +-
|
|
|
dc8c34 |
ldap/servers/slapd/opshared.c | 17 ++
|
|
|
dc8c34 |
ldap/servers/slapd/result.c | 2 +
|
|
|
dc8c34 |
ldap/servers/slapd/slapi-plugin.h | 2 +
|
|
|
dc8c34 |
ldap/servers/slapd/task.c | 4 +-
|
|
|
dc8c34 |
ldap/servers/slapd/tools/mmldif.c | 12 +-
|
|
|
dc8c34 |
13 files changed, 313 insertions(+), 30 deletions(-)
|
|
|
dc8c34 |
create mode 100644 dirsrvtests/tickets/ticket47950_test.py
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/dirsrvtests/tickets/ticket47950_test.py b/dirsrvtests/tickets/ticket47950_test.py
|
|
|
dc8c34 |
new file mode 100644
|
|
|
dc8c34 |
index 0000000..976f964
|
|
|
dc8c34 |
--- /dev/null
|
|
|
dc8c34 |
+++ b/dirsrvtests/tickets/ticket47950_test.py
|
|
|
dc8c34 |
@@ -0,0 +1,273 @@
|
|
|
dc8c34 |
+import os
|
|
|
dc8c34 |
+import sys
|
|
|
dc8c34 |
+import time
|
|
|
dc8c34 |
+import ldap
|
|
|
dc8c34 |
+import logging
|
|
|
dc8c34 |
+import socket
|
|
|
dc8c34 |
+import pytest
|
|
|
dc8c34 |
+from lib389 import DirSrv, Entry, tools, tasks
|
|
|
dc8c34 |
+from lib389.tools import DirSrvTools
|
|
|
dc8c34 |
+from lib389._constants import *
|
|
|
dc8c34 |
+from lib389.properties import *
|
|
|
dc8c34 |
+from lib389.tasks import *
|
|
|
dc8c34 |
+from constants import *
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+log = logging.getLogger(__name__)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+installation_prefix = None
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+USER1_DN = "uid=user1,%s" % DEFAULT_SUFFIX
|
|
|
dc8c34 |
+USER2_DN = "uid=user2,%s" % DEFAULT_SUFFIX
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+class TopologyStandalone(object):
|
|
|
dc8c34 |
+ def __init__(self, standalone):
|
|
|
dc8c34 |
+ standalone.open()
|
|
|
dc8c34 |
+ self.standalone = standalone
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+@pytest.fixture(scope="module")
|
|
|
dc8c34 |
+def topology(request):
|
|
|
dc8c34 |
+ '''
|
|
|
dc8c34 |
+ This fixture is used to standalone topology for the 'module'.
|
|
|
dc8c34 |
+ At the beginning, It may exists a standalone instance.
|
|
|
dc8c34 |
+ It may also exists a backup for the standalone instance.
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ Principle:
|
|
|
dc8c34 |
+ If standalone instance exists:
|
|
|
dc8c34 |
+ restart it
|
|
|
dc8c34 |
+ If backup of standalone exists:
|
|
|
dc8c34 |
+ create/rebind to standalone
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ restore standalone instance from backup
|
|
|
dc8c34 |
+ else:
|
|
|
dc8c34 |
+ Cleanup everything
|
|
|
dc8c34 |
+ remove instance
|
|
|
dc8c34 |
+ remove backup
|
|
|
dc8c34 |
+ Create instance
|
|
|
dc8c34 |
+ Create backup
|
|
|
dc8c34 |
+ '''
|
|
|
dc8c34 |
+ global installation_prefix
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if installation_prefix:
|
|
|
dc8c34 |
+ args_instance[SER_DEPLOYED_DIR] = installation_prefix
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ standalone = DirSrv(verbose=False)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Args for the standalone instance
|
|
|
dc8c34 |
+ args_instance[SER_HOST] = HOST_STANDALONE
|
|
|
dc8c34 |
+ args_instance[SER_PORT] = PORT_STANDALONE
|
|
|
dc8c34 |
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
|
|
|
dc8c34 |
+ args_standalone = args_instance.copy()
|
|
|
dc8c34 |
+ standalone.allocate(args_standalone)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Get the status of the backups
|
|
|
dc8c34 |
+ backup_standalone = standalone.checkBackupFS()
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Get the status of the instance and restart it if it exists
|
|
|
dc8c34 |
+ instance_standalone = standalone.exists()
|
|
|
dc8c34 |
+ if instance_standalone:
|
|
|
dc8c34 |
+ # assuming the instance is already stopped, just wait 5 sec max
|
|
|
dc8c34 |
+ standalone.stop(timeout=5)
|
|
|
dc8c34 |
+ standalone.start(timeout=10)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if backup_standalone:
|
|
|
dc8c34 |
+ # The backup exist, assuming it is correct
|
|
|
dc8c34 |
+ # we just re-init the instance with it
|
|
|
dc8c34 |
+ if not instance_standalone:
|
|
|
dc8c34 |
+ standalone.create()
|
|
|
dc8c34 |
+ # Used to retrieve configuration information (dbdir, confdir...)
|
|
|
dc8c34 |
+ standalone.open()
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # restore standalone instance from backup
|
|
|
dc8c34 |
+ standalone.stop(timeout=10)
|
|
|
dc8c34 |
+ standalone.restoreFS(backup_standalone)
|
|
|
dc8c34 |
+ standalone.start(timeout=10)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ else:
|
|
|
dc8c34 |
+ # We should be here only in two conditions
|
|
|
dc8c34 |
+ # - This is the first time a test involve standalone instance
|
|
|
dc8c34 |
+ # - Something weird happened (instance/backup destroyed)
|
|
|
dc8c34 |
+ # so we discard everything and recreate all
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Remove the backup. So even if we have a specific backup file
|
|
|
dc8c34 |
+ # (e.g backup_standalone) we clear backup that an instance may have created
|
|
|
dc8c34 |
+ if backup_standalone:
|
|
|
dc8c34 |
+ standalone.clearBackupFS()
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Remove the instance
|
|
|
dc8c34 |
+ if instance_standalone:
|
|
|
dc8c34 |
+ standalone.delete()
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Create the instance
|
|
|
dc8c34 |
+ standalone.create()
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Used to retrieve configuration information (dbdir, confdir...)
|
|
|
dc8c34 |
+ standalone.open()
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Time to create the backups
|
|
|
dc8c34 |
+ standalone.stop(timeout=10)
|
|
|
dc8c34 |
+ standalone.backupfile = standalone.backupFS()
|
|
|
dc8c34 |
+ standalone.start(timeout=10)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # clear the tmp directory
|
|
|
dc8c34 |
+ standalone.clearTmpDir(__file__)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Here we have standalone instance up and running
|
|
|
dc8c34 |
+ # Either coming from a backup recovery
|
|
|
dc8c34 |
+ # or from a fresh (re)init
|
|
|
dc8c34 |
+ # Time to return the topology
|
|
|
dc8c34 |
+ return TopologyStandalone(standalone)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+def test_ticket47950(topology):
|
|
|
dc8c34 |
+ """
|
|
|
dc8c34 |
+ Testing nsslapd-plugin-binddn-tracking does not cause issues around
|
|
|
dc8c34 |
+ access control and reconfiguring replication/repl agmt.
|
|
|
dc8c34 |
+ """
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ log.info('Testing Ticket 47950 - Testing nsslapd-plugin-binddn-tracking')
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Turn on bind dn tracking
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE, 'nsslapd-plugin-binddn-tracking', 'on')])
|
|
|
dc8c34 |
+ log.info('nsslapd-plugin-binddn-tracking enabled.')
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to enable bind dn tracking: ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add two users
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((USER1_DN, {
|
|
|
dc8c34 |
+ 'objectclass': "top person inetuser".split(),
|
|
|
dc8c34 |
+ 'userpassword': "password",
|
|
|
dc8c34 |
+ 'sn': "1",
|
|
|
dc8c34 |
+ 'cn': "user 1"})))
|
|
|
dc8c34 |
+ log.info('Added test user %s' % USER1_DN)
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add %s: %s' % (USER1_DN, e.message['desc']))
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((USER2_DN, {
|
|
|
dc8c34 |
+ 'objectclass': "top person inetuser".split(),
|
|
|
dc8c34 |
+ 'sn': "2",
|
|
|
dc8c34 |
+ 'cn': "user 2"})))
|
|
|
dc8c34 |
+ log.info('Added test user %s' % USER2_DN)
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add user1: ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add an aci
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ acival = '(targetattr ="cn")(version 3.0;acl "Test bind dn tracking"' + \
|
|
|
dc8c34 |
+ ';allow (all) (userdn = "ldap:///%s");)' % USER1_DN
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ topology.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_ADD, 'aci', acival)])
|
|
|
dc8c34 |
+ log.info('Added aci')
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add aci: ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Make modification as user
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.simple_bind_s(USER1_DN, "password")
|
|
|
dc8c34 |
+ log.info('Bind as user %s successful' % USER1_DN)
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to bind as user1: ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.modify_s(USER2_DN, [(ldap.MOD_REPLACE, 'cn', 'new value')])
|
|
|
dc8c34 |
+ log.info('%s successfully modified user %s' % (USER1_DN, USER2_DN))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to update user2: ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Setup replica and create a repl agmt
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.simple_bind_s(DN_DM, PASSWORD)
|
|
|
dc8c34 |
+ log.info('Bind as %s successful' % DN_DM)
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to bind as rootDN: ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.replica.enableReplication(suffix=DEFAULT_SUFFIX, role=REPLICAROLE_MASTER,
|
|
|
dc8c34 |
+ replicaId=REPLICAID_MASTER)
|
|
|
dc8c34 |
+ log.info('Successfully enabled replication.')
|
|
|
dc8c34 |
+ except ValueError:
|
|
|
dc8c34 |
+ log.error('Failed to enable replication')
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ properties = {RA_NAME: r'test plugin internal bind dn',
|
|
|
dc8c34 |
+ RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
|
|
|
dc8c34 |
+ RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
|
|
|
dc8c34 |
+ RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
|
|
|
dc8c34 |
+ RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ repl_agreement = topology.standalone.agreement.create(suffix=DEFAULT_SUFFIX, host="127.0.0.1",
|
|
|
dc8c34 |
+ port="7777", properties=properties)
|
|
|
dc8c34 |
+ log.info('Successfully created replication agreement')
|
|
|
dc8c34 |
+ except InvalidArgumentError, e:
|
|
|
dc8c34 |
+ log.error('Failed to create replication agreement: ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # modify replica
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ properties = {REPLICA_ID: "7"}
|
|
|
dc8c34 |
+ topology.standalone.replica.setProperties(DEFAULT_SUFFIX, None, None, properties)
|
|
|
dc8c34 |
+ log.info('Successfully modified replica')
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to update replica config: ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # modify repl agmt
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ properties = {RA_CONSUMER_PORT: "8888"}
|
|
|
dc8c34 |
+ topology.standalone.agreement.setProperties(None, repl_agreement, None, properties)
|
|
|
dc8c34 |
+ log.info('Successfully modified replication agreement')
|
|
|
dc8c34 |
+ except ValueError:
|
|
|
dc8c34 |
+ log.error('Failed to update replica agreement: ' + repl_agreement)
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # We passed
|
|
|
dc8c34 |
+ log.info("Test Passed.")
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+def test_ticket47953_final(topology):
|
|
|
dc8c34 |
+ topology.standalone.stop(timeout=10)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+def run_isolated():
|
|
|
dc8c34 |
+ '''
|
|
|
dc8c34 |
+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
|
|
|
dc8c34 |
+ To run isolated without py.test, you need to
|
|
|
dc8c34 |
+ - edit this file and comment '@pytest.fixture' line before 'topology' function.
|
|
|
dc8c34 |
+ - set the installation prefix
|
|
|
dc8c34 |
+ - run this program
|
|
|
dc8c34 |
+ '''
|
|
|
dc8c34 |
+ global installation_prefix
|
|
|
dc8c34 |
+ installation_prefix = None
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ topo = topology(True)
|
|
|
dc8c34 |
+ test_ticket47950(topo)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+if __name__ == '__main__':
|
|
|
dc8c34 |
+ run_isolated()
|
|
|
dc8c34 |
\ No newline at end of file
|
|
|
dc8c34 |
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
|
|
|
dc8c34 |
index 598601b..ad929c5 100644
|
|
|
dc8c34 |
--- a/ldap/servers/plugins/acl/acl.c
|
|
|
dc8c34 |
+++ b/ldap/servers/plugins/acl/acl.c
|
|
|
dc8c34 |
@@ -1383,9 +1383,9 @@ acl_check_mods(
|
|
|
dc8c34 |
if (be != NULL)
|
|
|
dc8c34 |
slapi_pblock_get ( pb, SLAPI_BE_LASTMOD, &lastmod );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- if (lastmod &&
|
|
|
dc8c34 |
- (strcmp (mod->mod_type, "modifiersname")== 0 ||
|
|
|
dc8c34 |
- strcmp (mod->mod_type, "modifytimestamp")== 0)) {
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if (lastmod && slapi_attr_is_last_mod(mod->mod_type)) {
|
|
|
dc8c34 |
+ /* skip pseudo attr(s) */
|
|
|
dc8c34 |
continue;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/plugins/replication/cl5_config.c b/ldap/servers/plugins/replication/cl5_config.c
|
|
|
dc8c34 |
index 900cfc0..f99fde9 100644
|
|
|
dc8c34 |
--- a/ldap/servers/plugins/replication/cl5_config.c
|
|
|
dc8c34 |
+++ b/ldap/servers/plugins/replication/cl5_config.c
|
|
|
dc8c34 |
@@ -355,15 +355,10 @@ changelog5_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
|
|
|
dc8c34 |
config_attr = (char *) mods[i]->mod_type;
|
|
|
dc8c34 |
config_attr_value = (char *) mods[i]->mod_bvalues[j]->bv_val;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
-#define ATTR_MODIFIERSNAME "modifiersname"
|
|
|
dc8c34 |
-#define ATTR_MODIFYTIMESTAMP "modifytimestamp"
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- if ( strcasecmp ( config_attr, ATTR_MODIFIERSNAME ) == 0 ) {
|
|
|
dc8c34 |
- continue;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
- if ( strcasecmp ( config_attr, ATTR_MODIFYTIMESTAMP ) == 0 ) {
|
|
|
dc8c34 |
+ if ( slapi_attr_is_last_mod(config_attr)){
|
|
|
dc8c34 |
continue;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
/* replace existing value */
|
|
|
dc8c34 |
if ( strcasecmp (config_attr, CONFIG_CHANGELOG_DIR_ATTRIBUTE ) == 0 )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c
|
|
|
dc8c34 |
index 70f71a8..d37704d 100644
|
|
|
dc8c34 |
--- a/ldap/servers/plugins/replication/repl5_agmtlist.c
|
|
|
dc8c34 |
+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c
|
|
|
dc8c34 |
@@ -488,8 +488,7 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
|
|
|
dc8c34 |
repl5_set_debug_timeout(val);
|
|
|
dc8c34 |
slapi_ch_free_string(&val;;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- else if (strcasecmp (mods[i]->mod_type, "modifytimestamp") == 0 ||
|
|
|
dc8c34 |
- strcasecmp (mods[i]->mod_type, "modifiersname") == 0 ||
|
|
|
dc8c34 |
+ else if (slapi_attr_is_last_mod(mods[i]->mod_type) ||
|
|
|
dc8c34 |
strcasecmp (mods[i]->mod_type, "description") == 0)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
/* ignore modifier's name and timestamp attributes and the description. */
|
|
|
dc8c34 |
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
|
|
dc8c34 |
index b8dd605..94ab71b 100644
|
|
|
dc8c34 |
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
|
|
dc8c34 |
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
|
|
dc8c34 |
@@ -484,8 +484,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
/* ignore modifiers attributes added by the server */
|
|
|
dc8c34 |
- else if (strcasecmp (config_attr, "modifytimestamp") == 0 ||
|
|
|
dc8c34 |
- strcasecmp (config_attr, "modifiersname") == 0)
|
|
|
dc8c34 |
+ else if (slapi_attr_is_last_mod(config_attr))
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
*returncode = LDAP_SUCCESS;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
|
|
|
dc8c34 |
index 5b3b5ee..e03bc6c 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/add.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/add.c
|
|
|
dc8c34 |
@@ -865,8 +865,8 @@ static int check_rdn_for_created_attrs(Slapi_Entry *e)
|
|
|
dc8c34 |
int i, rc = 0;
|
|
|
dc8c34 |
Slapi_RDN *rdn = NULL;
|
|
|
dc8c34 |
char *value = NULL;
|
|
|
dc8c34 |
- char *type[] = {SLAPI_ATTR_UNIQUEID, "modifytimestamp", "createtimestamp",
|
|
|
dc8c34 |
- "creatorsname", "modifiersname", 0};
|
|
|
dc8c34 |
+ char *type[] = {SLAPI_ATTR_UNIQUEID, "modifytimestamp", "modifiersname", "internalmodifytimestamp",
|
|
|
dc8c34 |
+ "internalmodifiersname", "createtimestamp", "creatorsname", 0};
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ((rdn = slapi_rdn_new())) {
|
|
|
dc8c34 |
slapi_rdn_init_dn(rdn, slapi_entry_get_dn_const(e));
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
|
|
dc8c34 |
index b35004a..11aa42d 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
|
|
dc8c34 |
@@ -1731,10 +1731,9 @@ int ldbm_config_ignored_attr(char *attr_name)
|
|
|
dc8c34 |
if (!strcasecmp("objectclass", attr_name) ||
|
|
|
dc8c34 |
!strcasecmp("cn", attr_name) ||
|
|
|
dc8c34 |
!strcasecmp("creatorsname", attr_name) ||
|
|
|
dc8c34 |
- !strcasecmp("modifiersname", attr_name) ||
|
|
|
dc8c34 |
!strcasecmp("createtimestamp", attr_name) ||
|
|
|
dc8c34 |
!strcasecmp(LDBM_NUMSUBORDINATES_STR, attr_name) ||
|
|
|
dc8c34 |
- !strcasecmp("modifytimestamp", attr_name)) {
|
|
|
dc8c34 |
+ slapi_attr_is_last_mod(attr_name)){
|
|
|
dc8c34 |
return 1;
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
return 0;
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/configdse.c b/ldap/servers/slapd/configdse.c
|
|
|
dc8c34 |
index 9265b98..fff7353 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/configdse.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/configdse.c
|
|
|
dc8c34 |
@@ -117,7 +117,10 @@ ignore_attr_type(const char *attr_type)
|
|
|
dc8c34 |
(strcasecmp (attr_type, "numsubordinates") == 0) ||
|
|
|
dc8c34 |
(strcasecmp (attr_type, "internalModifiersname") == 0) ||
|
|
|
dc8c34 |
(strcasecmp (attr_type, "modifytimestamp") == 0) ||
|
|
|
dc8c34 |
- (strcasecmp (attr_type, "modifiersname") == 0)) {
|
|
|
dc8c34 |
+ (strcasecmp (attr_type, "modifiersname") == 0) ||
|
|
|
dc8c34 |
+ (strcasecmp (attr_type, "internalCreatorsname") == 0) ||
|
|
|
dc8c34 |
+ slapi_attr_is_last_mod((char *)attr_type))
|
|
|
dc8c34 |
+ {
|
|
|
dc8c34 |
return 1;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
|
|
|
dc8c34 |
index 65fcea6..7a0b544 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/opshared.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/opshared.c
|
|
|
dc8c34 |
@@ -224,6 +224,23 @@ modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
+ * If the attribute is one of the last mod attributes return 1,
|
|
|
dc8c34 |
+ * otherwise return 0;
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+int
|
|
|
dc8c34 |
+slapi_attr_is_last_mod(char *attr)
|
|
|
dc8c34 |
+{
|
|
|
dc8c34 |
+ if(strcasecmp (attr, "modifytimestamp") == 0 ||
|
|
|
dc8c34 |
+ strcasecmp (attr, "modifiersname") == 0 ||
|
|
|
dc8c34 |
+ strcasecmp (attr, "internalmodifytimestamp") == 0 ||
|
|
|
dc8c34 |
+ strcasecmp (attr, "internalmodifiersname") == 0)
|
|
|
dc8c34 |
+ {
|
|
|
dc8c34 |
+ return 1;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ return 0;
|
|
|
dc8c34 |
+}
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+/*
|
|
|
dc8c34 |
* Returns: 0 - if the operation is successful
|
|
|
dc8c34 |
* < 0 - if operation fails.
|
|
|
dc8c34 |
* Note that an operation is considered "failed" if a result is sent
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
|
|
|
dc8c34 |
index 5463592..993dc9e 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/result.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/result.c
|
|
|
dc8c34 |
@@ -805,6 +805,8 @@ encode_attr(
|
|
|
dc8c34 |
|
|
|
dc8c34 |
#define LASTMODATTR( x ) (strcasecmp( x, "modifytimestamp" ) == 0 \
|
|
|
dc8c34 |
|| strcasecmp( x, "modifiersname" ) == 0 \
|
|
|
dc8c34 |
+ || strcasecmp( x, "internalmodifytimestamp" ) == 0 \
|
|
|
dc8c34 |
+ || strcasecmp( x, "internalmodifiersname" ) == 0 \
|
|
|
dc8c34 |
|| strcasecmp( x, "createtimestamp" ) == 0 \
|
|
|
dc8c34 |
|| strcasecmp( x, "creatorsname" ) == 0)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
|
|
|
dc8c34 |
index 8fff870..e02127d 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/slapi-plugin.h
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/slapi-plugin.h
|
|
|
dc8c34 |
@@ -4978,6 +4978,8 @@ int slapi_filter_compare(struct slapi_filter *f1, struct slapi_filter *f2);
|
|
|
dc8c34 |
Slapi_Filter *slapi_filter_dup(Slapi_Filter *f);
|
|
|
dc8c34 |
int slapi_filter_changetype(Slapi_Filter *f, const char *newtype);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+int slapi_attr_is_last_mod(char *attr);
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
/**
|
|
|
dc8c34 |
* Normalize in-place the given filter. Normalizes the attribute types always.
|
|
|
dc8c34 |
* If norm_values is true, will also normalize the values.
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
|
|
|
dc8c34 |
index 2fe1de7..0488640 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/task.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/task.c
|
|
|
dc8c34 |
@@ -779,8 +779,8 @@ static int task_modify(Slapi_PBlock *pb, Slapi_Entry *e,
|
|
|
dc8c34 |
* stuck in by the server */
|
|
|
dc8c34 |
if ((strcasecmp(mods[i]->mod_type, "ttl") != 0) &&
|
|
|
dc8c34 |
(strcasecmp(mods[i]->mod_type, "nsTaskCancel") != 0) &&
|
|
|
dc8c34 |
- (strcasecmp(mods[i]->mod_type, "modifiersName") != 0) &&
|
|
|
dc8c34 |
- (strcasecmp(mods[i]->mod_type, "modifyTimestamp") != 0)) {
|
|
|
dc8c34 |
+ !slapi_attr_is_last_mod(mods[i]->mod_type))
|
|
|
dc8c34 |
+ {
|
|
|
dc8c34 |
/* you aren't allowed to change this! */
|
|
|
dc8c34 |
*returncode = LDAP_UNWILLING_TO_PERFORM;
|
|
|
dc8c34 |
return SLAPI_DSE_CALLBACK_ERROR;
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/tools/mmldif.c b/ldap/servers/slapd/tools/mmldif.c
|
|
|
dc8c34 |
index 4213e65..ebadf13 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/tools/mmldif.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/tools/mmldif.c
|
|
|
dc8c34 |
@@ -1017,9 +1017,7 @@ addnew(FILE * edf3, const char *changetype, record_t * first)
|
|
|
dc8c34 |
for (attnum = 1, att = &first->data;
|
|
|
dc8c34 |
attnum <= first->nattrs;
|
|
|
dc8c34 |
attnum++, att = attribnext(att)) {
|
|
|
dc8c34 |
- if (!stricmp(attribname(att), "modifytimestamp"))
|
|
|
dc8c34 |
- continue;
|
|
|
dc8c34 |
- if (!stricmp(attribname(att), "modifiersname"))
|
|
|
dc8c34 |
+ if (slapi_attr_is_last_mod(attribname(att)))
|
|
|
dc8c34 |
continue;
|
|
|
dc8c34 |
if (!putvalue(edf3, NULL, attribname(att), att->namelen,
|
|
|
dc8c34 |
attribvalue(att), att->valuelen)) {
|
|
|
dc8c34 |
@@ -1074,15 +1072,11 @@ addmodified(FILE * edf3, attrib1_t * attrib, record_t * first)
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
while (a != NULL || num_b <= tot_b) {
|
|
|
dc8c34 |
/* ignore operational attrs */
|
|
|
dc8c34 |
- if (num_b <= tot_b &&
|
|
|
dc8c34 |
- (stricmp(attribname(b), "modifytimestamp") == 0 ||
|
|
|
dc8c34 |
- stricmp(attribname(b), "modifiersname") == 0)) {
|
|
|
dc8c34 |
+ if ( num_b <= tot_b && slapi_attr_is_last_mod(attribname(b)) ){
|
|
|
dc8c34 |
b = attribnext(b); num_b++;
|
|
|
dc8c34 |
continue;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- if (a != NULL &&
|
|
|
dc8c34 |
- (stricmp(a->name, "modifytimestamp") == 0 ||
|
|
|
dc8c34 |
- stricmp(a->name, "modifiersname") == 0)) {
|
|
|
dc8c34 |
+ if (a != NULL && slapi_attr_is_last_mod(a->name)) {
|
|
|
dc8c34 |
a = a->next;
|
|
|
dc8c34 |
continue;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
1.9.3
|
|
|
dc8c34 |
|