Create a user for Windows PassSync and grant password changing permissions

This does 3 things:
1. Create a user for the Windows PassSync service
2. Add this use to the list of users that can skip password policies
3. Add an aci that grants permission to write the password attributes

471130
This commit is contained in:
Rob Crittenden 2008-11-12 14:01:59 -05:00
parent 49e4876ba9
commit 17261c2520
2 changed files with 44 additions and 2 deletions

View File

@ -46,6 +46,8 @@ def parse_options():
help="Full path and filename of CA certificate to use with TLS/SSL to the remote server")
parser.add_option("--win-subtree", dest="win_subtree",
help="DN of Windows subtree containing the users you want to sync (default cn=Users,<domain suffix)")
parser.add_option("--passsync", dest="passsync",
help="Password for the Windows PassSync user")
options, args = parser.parse_args()
@ -115,10 +117,12 @@ def add_master(replman, hostname, options):
other_args['cacert'] = options.cacert
if options.win_subtree:
other_args['win_subtree'] = options.win_subtree
if options.passsync:
other_args['passsync'] = options.passsync
if options.winsync:
other_args['winsync'] = True
if not options.binddn or not options.bindpw or not options.cacert:
logging.error("The arguments --binddn, --bindpw, and --cacert are required to create a winsync agreement")
if not options.binddn or not options.bindpw or not options.cacert or not options.passsync:
logging.error("The arguments --binddn, --bindpw, --passsync and --cacert are required to create a winsync agreement")
sys.exit(1)
if options.cacert:
# have to install the given CA cert before doing anything else

View File

@ -246,6 +246,43 @@ class ReplicationManager:
chainbe = self.setup_chaining_backend(other_conn)
self.enable_chain_on_update(chainbe)
def add_passsync_user(self, conn, password):
pass_dn = "uid=passsync,cn=sysaccounts,cn=etc,%s" % self.suffix
print "The user for the Windows PassSync service is %s" % pass_dn
try:
conn.getEntry(pass_dn, ldap.SCOPE_BASE)
print "Windows PassSync entry exists, not resetting password"
return
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
pass
# The user doesn't exist, add it
entry = ipaldap.Entry(pass_dn)
entry.setValues("objectclass", ["account", "simplesecurityobject"])
entry.setValues("uid", "passsync")
entry.setValues("userPassword", password)
conn.add_s(entry)
# Add it to the list of users allowed to bypass password policy
extop_dn = "cn=ipa_pwd_extop,cn=plugins,cn=config"
entry = conn.getEntry(extop_dn, ldap.SCOPE_BASE)
pass_mgrs = entry.getValues('passSyncManagersDNs')
if not pass_mgrs:
pass_mgrs = []
if not isinstance(pass_mgrs, list):
pass_mgrs = [pass_mgrs]
pass_mgrs.append(pass_dn)
mod = [(ldap.MOD_REPLACE, 'passSyncManagersDNs', pass_mgrs)]
conn.modify_s(extop_dn, mod)
# And finally grant it permission to write passwords
mod = [(ldap.MOD_ADD, 'aci',
['(targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory")(version 3.0; acl "Windows PassSync service can write passwords"; allow (write) userdn="ldap:///%s";)' % pass_dn])]
try:
conn.modify_s(self.suffix, mod)
except ldap.TYPE_OR_VALUE_EXISTS:
logging.debug("passsync aci already exists in suffix %s on %s" % (self.suffix, conn.host))
def setup_winsync_agmt(self, entry, **kargs):
entry.setValues("objectclass", "nsDSWindowsReplicationAgreement")
entry.setValues("nsds7WindowsReplicaSubtree",
@ -407,6 +444,7 @@ class ReplicationManager:
self.setup_agreement(self.conn, other_conn)
return self.start_replication(other_conn)
else:
self.add_passsync_user(self.conn, kargs.get("passsync"))
self.setup_agreement(self.conn, other_conn, **kargs)
return self.start_replication(self.conn, other_conn)