summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xinstall/tools/ipa-replica-manage22
-rw-r--r--install/updates/40-delegation.update37
-rw-r--r--ipaserver/install/dsinstance.py2
-rw-r--r--ipaserver/install/replication.py20
4 files changed, 76 insertions, 5 deletions
diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
index 20d261c8f..b85c491e5 100755
--- a/install/tools/ipa-replica-manage
+++ b/install/tools/ipa-replica-manage
@@ -27,6 +27,7 @@ from ipaserver.install import replication, dsinstance, installutils
from ipaserver import ipaldap
from ipapython import version
from ipalib import util
+from ipalib import errors
def parse_options():
from optparse import OptionParser
@@ -102,12 +103,15 @@ def del_master(replman, hostname, force=False):
try:
t = replman.get_agreement_type(hostname)
except ldap.NO_SUCH_OBJECT:
- print "No replication agreement found for %s" % hostname
+ print "No replication agreement found for '%s'" % hostname
+ return
+ except errors.NotFound:
+ print "No replication agreement found for '%s'" % hostname
+ return
if t == replication.IPA_REPLICA:
- dirman_passwd = getpass.getpass("Directory Manager password (%s): " % hostname)
try:
- other_replman = replication.ReplicationManager(hostname, dirman_passwd)
+ other_replman = replication.ReplicationManager(hostname, dirman_passwd=None)
other_replman.suffix = get_suffix()
other_replman.delete_agreement(replman.conn.host)
except Exception, e:
@@ -179,10 +183,13 @@ def synch_master(replman, hostname):
def main():
options, args = parse_options()
+ dirman_passwd = None
+
if options.dirman_passwd:
dirman_passwd = options.dirman_passwd
else:
- dirman_passwd = getpass.getpass("Directory Manager password: ")
+ if args[0] in ["add", "init"]:
+ dirman_passwd = getpass.getpass("Directory Manager password: ")
if options.host:
host = options.host
@@ -227,5 +234,12 @@ except SystemExit, e:
except ldap.INVALID_CREDENTIALS:
print "Invalid password"
sys.exit(1)
+except ldap.INSUFFICIENT_ACCESS:
+ print "Insufficient access"
+ sys.exit(1)
+except ldap.LOCAL_ERROR, e:
+ print e.args[0]['info']
+ sys.exit(1)
except Exception, e:
print "unexpected error: %s" % str(e)
+ sys.exit(1)
diff --git a/install/updates/40-delegation.update b/install/updates/40-delegation.update
index 1be178933..77dca721d 100644
--- a/install/updates/40-delegation.update
+++ b/install/updates/40-delegation.update
@@ -72,6 +72,13 @@ add:objectClass: nestedgroup
add:cn: certadmin
add:description: Certificate Administrators
+dn: cn=replicaadmin,cn=rolegroups,cn=accounts,$SUFFIX
+add:objectClass: top
+add:objectClass: nestedgroup
+add:cn: replicaadmin
+add:description: Replication Administrators
+add:member:'uid=admin,cn=users,cn=accounts,$SUFFIX'
+
# Add the taskgroups referenced by the ACIs for user administration
dn: cn=taskgroups,cn=accounts,$SUFFIX
@@ -648,3 +655,33 @@ add: aci: '(targetattr = "objectClass")(target =
$SUFFIX" )(version 3.0 ; acl "Certificate Remove Hold"
; allow (write) groupdn = "ldap:///cn=certificate_remove_hold,
cn=taskgroups,cn=accounts,$SUFFIX";)'
+
+# Taskgroup for managing replicas
+dn: cn=managereplica,cn=taskgroups,cn=accounts,$SUFFIX
+add:objectClass: top
+add:objectClass: nestedgroup
+add:cn: managereplica
+add:description: Manage Replication Agreements
+add:member:'cn=replicaadmin,cn=rolegroups,cn=accounts,$SUFFIX'
+
+# Taskgroup for deleting replicas
+dn: cn=deletereplica,cn=taskgroups,cn=accounts,$SUFFIX
+add:objectClass: top
+add:objectClass: nestedgroup
+add:cn: deletereplica
+add:description: Delete Replication Agreements
+add:member:'cn=replicaadmin,cn=rolegroups,cn=accounts,$SUFFIX'
+
+# Add acis allowing admins to read/write/delete replicas
+dn: cn="$SUFFIX",cn=mapping tree,cn=config
+add: aci: '(targetattr=*)(targetfilter="(|(objectclass=nsds5Replica)
+ (objectclass=nsds5replicationagreement)(objectclass=
+ nsDSWindowsReplicationAgreement))")(version 3.0; acl "Manage
+ replication agreements"; allow (read, write, search) groupdn =
+ "ldap:///cn=managereplica,cn=taskgroups,cn=accounts,$SUFFIX";)'
+
+dn: cn="$SUFFIX",cn=mapping tree,cn=config
+add: aci: '(targetattr=*)(targetfilter="(|(objectclass=
+ nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement
+ ))")(version 3.0;acl "Delete replication agreements";allow (delete)
+ groupdn = "ldap:///cn=deletereplica,cn=taskgroups,cn=accounts,$SUFFIX";)'
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 9a71b7f56..f535b7ba8 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -148,6 +148,8 @@ class DsInstance(service.Service):
self.pkcs12_info = None
self.ds_user = None
self.dercert = None
+ self.uidstart = 1100
+ self.gidstart = 1100
if realm_name:
self.suffix = util.realm_to_suffix(self.realm_name)
self.__setup_sub_dict()
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index 242352975..a09fb3058 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -38,6 +38,8 @@ TIMEOUT = 120
IPA_REPLICA = 1
WINSYNC = 2
+SASL_AUTH = ldap.sasl.sasl({}, 'GSSAPI')
+
class ReplicationManager:
"""Manage replication agreements between DS servers, and sync
agreements with Windows servers"""
@@ -45,8 +47,13 @@ class ReplicationManager:
self.hostname = hostname
self.dirman_passwd = dirman_passwd
+ # If we are passed a password we'll use it as the DM password
+ # otherwise we'll do a GSSAPI bind.
self.conn = ipaldap.IPAdmin(hostname, port=PORT, cacert=CACERT)
- self.conn.do_simple_bind(bindpw=dirman_passwd)
+ if dirman_passwd:
+ self.conn.do_simple_bind(bindpw=dirman_passwd)
+ else:
+ self.conn.sasl_interactive_bind_s('', SASL_AUTH)
self.repl_man_passwd = dirman_passwd
@@ -98,6 +105,16 @@ class ReplicationManager:
return retval
def find_replication_dns(self, conn):
+ """
+ The replication agreements are stored in
+ cn="$SUFFIX",cn=mapping tree,cn=config
+
+ FIXME: Rather than failing with a read error if a user tries
+ to read this it simply returns zero entries. We need to use
+ GER to determine if we are allowed to read this to return a proper
+ response. For now just return "No entries" even if the user may
+ not be allowed to see them.
+ """
filt = "(|(objectclass=nsDSWindowsReplicationAgreement)(objectclass=nsds5ReplicationAgreement))"
try:
ents = conn.search_s("cn=mapping tree,cn=config", ldap.SCOPE_SUBTREE, filt)
@@ -465,6 +482,7 @@ class ReplicationManager:
# allow connections using two different CA certs
other_conn = ipaldap.IPAdmin(other_hostname, port=oth_port, cacert=oth_cacert)
try:
+ # For now we always require a password to set up new replica
other_conn.do_simple_bind(binddn=oth_binddn, bindpw=oth_bindpw)
except Exception, e:
if iswinsync: