summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2010-09-28 20:47:03 -0700
committerAndrew Tridgell <tridge@samba.org>2010-09-29 03:55:04 +0000
commit31310826e02a398eec6569a9150a798ee216f745 (patch)
tree4eadf7a737f510911acf889017fa0da7963cbe48 /source4
parent739a4e4e2361fad17a4d041e2e0b4fc73a9d18c2 (diff)
downloadsamba-31310826e02a398eec6569a9150a798ee216f745.tar.gz
samba-31310826e02a398eec6569a9150a798ee216f745.tar.bz2
samba-31310826e02a398eec6569a9150a798ee216f745.zip
s4-spnupdate: when we are a RODC we need to use the WriteSPN DRS call
we can't do SPN updates via sam writes and replication, as the sam is read-only
Diffstat (limited to 'source4')
-rwxr-xr-xsource4/scripting/bin/samba_spnupdate67
1 files changed, 57 insertions, 10 deletions
diff --git a/source4/scripting/bin/samba_spnupdate b/source4/scripting/bin/samba_spnupdate
index b6501fbc47..6a69f48a45 100755
--- a/source4/scripting/bin/samba_spnupdate
+++ b/source4/scripting/bin/samba_spnupdate
@@ -108,9 +108,6 @@ except ldb.LdbError, (num, msg):
print("Unable to open sam database %s : %s" % (lp.get("sam database"), msg))
sys.exit(1)
-if samdb.am_rodc():
- # don't try and update SPNs on RODC
- exit(0)
# get the substitution dictionary
sub_vars = get_subst_vars(samdb)
@@ -138,6 +135,8 @@ if not res or len(res) != 1:
print("Failed to find computer object for %s$" % sub_vars['NETBIOSNAME'])
sys.exit(1)
+machine_dn = res[0]["dn"]
+
old_spns = []
for s in res[0]['servicePrincipalName']:
old_spns.append(s)
@@ -165,10 +164,58 @@ if add_list == []:
print("Nothing to add")
sys.exit(0)
-# build the modify request
-msg = ldb.Message()
-msg.dn = res[0]['dn']
-msg[""] = ldb.MessageElement(add_list,
- ldb.FLAG_MOD_ADD, "servicePrincipalName")
-res = samdb.modify(msg)
-sys.exit(0)
+def local_update(add_list):
+ '''store locally'''
+ global res
+ msg = ldb.Message()
+ msg.dn = res[0]['dn']
+ msg[""] = ldb.MessageElement(add_list,
+ ldb.FLAG_MOD_ADD, "servicePrincipalName")
+ res = samdb.modify(msg)
+
+def call_rodc_update(d):
+ '''RODCs need to use the writeSPN DRS call'''
+ global lp, sub_vars
+ from samba import drs_utils
+ from samba.dcerpc import drsuapi, nbt
+ from samba.net import Net
+
+ if opts.verbose:
+ print("Using RODC SPN update")
+
+ creds = credopts.get_credentials(lp)
+ creds.set_machine_account(lp)
+
+ net = Net(creds=creds, lp=lp)
+ try:
+ cldap_ret = net.finddc(domain, nbt.NBT_SERVER_DS | nbt.NBT_SERVER_WRITABLE)
+ except Exception, reason:
+ print("Unable to find writeable DC for domain '%s' to send DRS writeSPN to : %s" % (domain, reason))
+ sys.exit(1)
+ server = cldap_ret.pdc_dns_name
+ try:
+ drs = drsuapi.drsuapi('ncacn_ip_tcp:%s[seal,print]' % server, lp, creds)
+ drs_handle = drs_utils.drs_DsBind(drs)
+ except Exception, reason:
+ print("Unable to connect to DC '%s' for domain '%s' : %s" % (server, domain, reason))
+ sys.exit(1)
+ req1 = drsuapi.DsWriteAccountSpnRequest1()
+ req1.operation = drsuapi.DRSUAPI_DS_SPN_OPERATION_ADD
+ req1.object_dn = str(machine_dn)
+ req1.count = 0
+ spn_names = []
+ for n in add_list:
+ if n.find('E3514235-4B06-11D1-AB04-00C04FC2DCD2') != -1:
+ # this one isn't allowed for RODCs, but we don't know why yet
+ continue
+ ns = drsuapi.DsNameString()
+ ns.str = n
+ spn_names.append(ns)
+ req1.count = req1.count + 1
+ req1.spn_names = spn_names
+ (level, res) = drs.DsWriteAccountSpn(drs_handle, 1, req1)
+
+if samdb.am_rodc():
+ call_rodc_update(add_list)
+else:
+ local_update(add_list)