The branch, master has been updated
via ef13264... s4-provision: setup spn_update_list in provision
via b5b8e6b... s4-dns: install samba_spnupdate
via ff2edd5... s4-dns: call spn update command alongside dns update
via 37dfaff... s4-param: added a "spn update command" option
via fa26383... s4-dsdb: added samba_spnupdate
via 570c892... s4-dns: explain what the file is for
via 7872efc... s4-dns: cope better with comments in dns_update_list
from 1ae9044... s4:gensec Use a different form of 'name' in GSSAPI
import_name()
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit ef1326412573777b0a5457c06d130c6455932af7
Author: Andrew Tridgell <[email protected]>
Date: Tue Apr 27 18:38:47 2010 +1000
s4-provision: setup spn_update_list in provision
commit b5b8e6b6adc0abcb833c034f8dc33f338dd6b815
Author: Andrew Tridgell <[email protected]>
Date: Tue Apr 27 18:38:25 2010 +1000
s4-dns: install samba_spnupdate
commit ff2edd52cba6e99763be5193847900119670ad7e
Author: Andrew Tridgell <[email protected]>
Date: Tue Apr 27 18:38:04 2010 +1000
s4-dns: call spn update command alongside dns update
call samba_spnupdate at the same time as samba_spnupdate
commit 37dfaff82cb554492fb0a3ddc95d3144d0508bc6
Author: Andrew Tridgell <[email protected]>
Date: Tue Apr 27 18:37:12 2010 +1000
s4-param: added a "spn update command" option
used by SPN update code
commit fa26383884751c5775ccb65e3fbbf9ec7eeda28c
Author: Andrew Tridgell <[email protected]>
Date: Tue Apr 27 18:25:55 2010 +1000
s4-dsdb: added samba_spnupdate
this script adds all our required servicePrincipalName entries at
runtime. The admin can add more entries to spn_update_list as needed
commit 570c89287e3f5e424db65098d5e60c9e37a5b6f3
Author: Andrew Tridgell <[email protected]>
Date: Tue Apr 27 18:25:06 2010 +1000
s4-dns: explain what the file is for
commit 7872efcbc0d02ef5ca79abf08f3274463ff3ec26
Author: Andrew Tridgell <[email protected]>
Date: Tue Apr 27 18:24:52 2010 +1000
s4-dns: cope better with comments in dns_update_list
-----------------------------------------------------------------------
Summary of changes:
source4/dsdb/dns/dns_update.c | 46 +++++++++
source4/param/loadparm.c | 4 +
source4/param/param.h | 1 +
source4/script/installmisc.sh | 2 +-
source4/scripting/bin/samba_dnsupdate | 11 +--
source4/scripting/bin/samba_spnupdate | 137 +++++++++++++++++++++++++++
source4/scripting/python/samba/provision.py | 6 +-
source4/scripting/wscript_build | 2 +-
source4/setup/dns_update_list | 2 +
source4/setup/spn_update_list | 27 +++++
10 files changed, 228 insertions(+), 10 deletions(-)
create mode 100755 source4/scripting/bin/samba_spnupdate
create mode 100644 source4/setup/spn_update_list
Changeset truncated at 500 lines:
diff --git a/source4/dsdb/dns/dns_update.c b/source4/dsdb/dns/dns_update.c
index 1420bb7..7242acf 100644
--- a/source4/dsdb/dns/dns_update.c
+++ b/source4/dsdb/dns/dns_update.c
@@ -55,6 +55,7 @@ struct dnsupdate_service {
uint32_t interval;
struct tevent_timer *te;
struct tevent_req *subreq;
+ struct tevent_req *spnreq;
NTSTATUS status;
} nameupdate;
};
@@ -251,12 +252,42 @@ static void dnsupdate_nameupdate_done(struct tevent_req
*subreq)
}
}
+
+/*
+ called when spn update script has finished
+ */
+static void dnsupdate_spnupdate_done(struct tevent_req *subreq)
+{
+ struct dnsupdate_service *service = tevent_req_callback_data(subreq,
+ struct dnsupdate_service);
+ int ret;
+ int sys_errno;
+
+ service->nameupdate.spnreq = NULL;
+
+ ret = samba_runcmd_recv(subreq, &sys_errno);
+ TALLOC_FREE(subreq);
+ if (ret != 0) {
+ service->nameupdate.status = map_nt_error_from_unix(sys_errno);
+ } else {
+ service->nameupdate.status = NT_STATUS_OK;
+ }
+
+ if (!NT_STATUS_IS_OK(service->nameupdate.status)) {
+ DEBUG(0,(__location__ ": Failed SPN update - %s\n",
+ nt_errstr(service->nameupdate.status)));
+ } else {
+ DEBUG(3,("Completed SPN update check OK\n"));
+ }
+}
+
/*
called every 'dnsupdate:name interval' seconds
*/
static void dnsupdate_check_names(struct dnsupdate_service *service)
{
const char * const *dns_update_command =
lp_dns_update_command(service->task->lp_ctx);
+ const char * const *spn_update_command =
lp_spn_update_command(service->task->lp_ctx);
/* kill any existing child */
TALLOC_FREE(service->nameupdate.subreq);
@@ -275,6 +306,21 @@ static void dnsupdate_check_names(struct dnsupdate_service
*service)
tevent_req_set_callback(service->nameupdate.subreq,
dnsupdate_nameupdate_done,
service);
+
+ DEBUG(3,("Calling SPN name update script\n"));
+ service->nameupdate.spnreq = samba_runcmd_send(service,
+ service->task->event_ctx,
+ timeval_current_ofs(10,
0),
+ 2, 0,
+ spn_update_command,
+ NULL);
+ if (service->nameupdate.spnreq == NULL) {
+ DEBUG(0,(__location__ ": samba_runcmd_send() failed with no
memory\n"));
+ return;
+ }
+ tevent_req_set_callback(service->nameupdate.spnreq,
+ dnsupdate_spnupdate_done,
+ service);
}
static NTSTATUS dnsupdate_nameupdate_schedule(struct dnsupdate_service
*service);
diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c
index b7dcd9b..45b2064 100644
--- a/source4/param/loadparm.c
+++ b/source4/param/loadparm.c
@@ -188,6 +188,7 @@ struct loadparm_global
char *szNTPSignDSocketDirectory;
const char **szRNDCCommand;
const char **szDNSUpdateCommand;
+ const char **szSPNUpdateCommand;
char *szNSUpdateCommand;
struct parmlist_entry *param_opt;
};
@@ -508,6 +509,7 @@ static struct parm_struct parm_table[] = {
{"ntp signd socket directory", P_STRING, P_GLOBAL,
GLOBAL_VAR(szNTPSignDSocketDirectory), NULL, NULL },
{"rndc command", P_LIST, P_GLOBAL, GLOBAL_VAR(szRNDCCommand), NULL,
NULL },
{"dns update command", P_LIST, P_GLOBAL,
GLOBAL_VAR(szDNSUpdateCommand), NULL, NULL },
+ {"spn update command", P_LIST, P_GLOBAL,
GLOBAL_VAR(szSPNUpdateCommand), NULL, NULL },
{"nsupdate command", P_STRING, P_GLOBAL, GLOBAL_VAR(szNSUpdateCommand),
NULL, NULL },
{NULL, P_BOOL, P_NONE, 0, NULL, NULL}
@@ -662,6 +664,7 @@ _PUBLIC_ FN_GLOBAL_STRING(lp_display_charset,
display_charset)
_PUBLIC_ FN_GLOBAL_STRING(lp_piddir, szPidDir)
_PUBLIC_ FN_GLOBAL_LIST(lp_rndc_command, szRNDCCommand)
_PUBLIC_ FN_GLOBAL_LIST(lp_dns_update_command, szDNSUpdateCommand)
+_PUBLIC_ FN_GLOBAL_LIST(lp_spn_update_command, szSPNUpdateCommand)
_PUBLIC_ FN_GLOBAL_STRING(lp_nsupdate_command, szNSUpdateCommand)
_PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, dcerpc_ep_servers)
_PUBLIC_ FN_GLOBAL_LIST(lp_server_services, server_services)
@@ -2458,6 +2461,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX
*mem_ctx)
lp_do_global_parameter(lp_ctx, "ntp signd socket directory",
dyn_NTP_SIGND_SOCKET_DIR);
lp_do_global_parameter(lp_ctx, "rndc command", "/usr/sbin/rndc");
lp_do_global_parameter_var(lp_ctx, "dns update command",
"%s/samba_dnsupdate", dyn_SBINDIR);
+ lp_do_global_parameter_var(lp_ctx, "spn update command",
"%s/samba_spnupdate", dyn_SBINDIR);
lp_do_global_parameter(lp_ctx, "nsupdate command", "/usr/bin/nsupdate
-g");
for (i = 0; parm_table[i].label; i++) {
diff --git a/source4/param/param.h b/source4/param/param.h
index 5435941..8bb368f 100644
--- a/source4/param/param.h
+++ b/source4/param/param.h
@@ -132,6 +132,7 @@ const char *lp_socket_address(struct loadparm_context *);
const char **lp_netbios_aliases(struct loadparm_context *);
const char **lp_rndc_command(struct loadparm_context *);
const char **lp_dns_update_command(struct loadparm_context *);
+const char **lp_spn_update_command(struct loadparm_context *);
bool lp_disable_netbios(struct loadparm_context *);
bool lp_wins_support(struct loadparm_context *);
bool lp_wins_dns_proxy(struct loadparm_context *);
diff --git a/source4/script/installmisc.sh b/source4/script/installmisc.sh
index d8fd156..f9ac073 100755
--- a/source4/script/installmisc.sh
+++ b/source4/script/installmisc.sh
@@ -57,7 +57,7 @@ do
done
echo "Installing sbin scripts from scripting/bin/*"
-for p in upgradeprovision samba_dnsupdate
+for p in upgradeprovision samba_dnsupdate samba_spnupdate
do
cp scripting/bin/$p $SBINDIR || exit 1
chmod a+x $SBINDIR/$p
diff --git a/source4/scripting/bin/samba_dnsupdate
b/source4/scripting/bin/samba_dnsupdate
index 3fe55e2..70fec25 100755
--- a/source4/scripting/bin/samba_dnsupdate
+++ b/source4/scripting/bin/samba_dnsupdate
@@ -150,7 +150,7 @@ def check_dns_name(d):
for line in dns_file:
line = line.strip()
- if line[0] == "#":
+ if line == '' or line[0] == "#":
continue
if line.lower() == str(d).lower():
return True
@@ -253,15 +253,12 @@ update_list = []
dns_list = []
# read each line, and check that the DNS name exists
-line = file.readline()
-while line:
- line = line.rstrip().lstrip()
- if line[0] == "#":
- line = file.readline()
+for line in file:
+ line = line.strip()
+ if line == '' or line[0] == "#":
continue
d = parse_dns_line(line, sub_vars)
dns_list.append(d)
- line = file.readline()
# now expand the entries, if any are A record with ip set to $IP
# then replace with multiple entries, one for each interface IP
diff --git a/source4/scripting/bin/samba_spnupdate
b/source4/scripting/bin/samba_spnupdate
new file mode 100755
index 0000000..1971ea1
--- /dev/null
+++ b/source4/scripting/bin/samba_spnupdate
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+#
+# update our servicePrincipalName names from spn_update_list
+#
+# Copyright (C) Andrew Tridgell 2010
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+import os, sys
+
+# ensure we get messages out immediately, so they get in the samba logs,
+# and don't get swallowed by a timeout
+os.putenv('PYTHONUNBUFFERED', '1')
+
+# Find right directory when running from source tree
+sys.path.insert(0, "bin/python")
+
+import samba, ldb
+import optparse
+from samba import getopt as options
+from samba.auth import system_session
+from samba.samdb import SamDB
+
+parser = optparse.OptionParser("samba_spnupdate")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+parser.add_option_group(options.VersionOptions(parser))
+parser.add_option("--verbose", action="store_true")
+
+creds = None
+ccachename = None
+
+opts, args = parser.parse_args()
+
+if len(args) != 0:
+ parser.print_usage()
+ sys.exit(1)
+
+lp = sambaopts.get_loadparm()
+
+domain = lp.get("realm")
+host = lp.get("netbios name")
+
+
+# get the list of substitution vars
+def get_subst_vars(samdb):
+ global lp
+ vars = {}
+
+ vars['DNSDOMAIN'] = lp.get('realm').lower()
+ vars['HOSTNAME'] = lp.get('netbios name').lower() + "." +
vars['DNSDOMAIN']
+ vars['NETBIOSNAME'] = lp.get('netbios name').upper()
+ vars['WORKGROUP'] = lp.get('workgroup')
+ vars['NTDSGUID'] = samdb.get_ntds_GUID()
+ res = samdb.search(base=None, scope=ldb.SCOPE_BASE, attrs=["objectGUID"])
+ guid = samdb.schema_format_value("objectGUID", res[0]['objectGUID'][0])
+ vars['DOMAINGUID'] = guid
+ return vars
+
+try:
+ samdb = SamDB(url=lp.get("sam database"), session_info=system_session(),
lp=lp)
+except ldb.LdbError, (num, msg):
+ print("Unable to open sam database %s : %s" % (lp.get("sam database")),
msg)
+ sys.exit(1)
+
+# get the substitution dictionary
+sub_vars = get_subst_vars(samdb)
+
+# get the list of SPN entries we should have
+spn_update_list = lp.private_path('spn_update_list')
+
+file = open(spn_update_list, "r")
+
+spn_list = []
+
+# build the spn list
+for line in file:
+ line = line.strip()
+ if line == '' or line[0] == "#":
+ continue
+ line = samba.substitute_var(line, sub_vars)
+ spn_list.append(line)
+
+# get the current list of SPNs in our sam
+res = samdb.search(base="",
+ expression='(&(objectClass=computer)(samaccountname=%s$))'
% sub_vars['NETBIOSNAME'],
+ attrs=["servicePrincipalName"])
+if not res or len(res) != 1:
+ print("Failed to find computer object for %s$" % sub_vars['NETBIOSNAME'])
+ sys.exit(1)
+
+old_spns = []
+for s in res[0]['servicePrincipalName']:
+ old_spns.append(s)
+
+if opts.verbose:
+ print("Existing SPNs: %s" % old_spns)
+
+add_list = []
+
+# work out what needs to be added
+for s in spn_list:
+ in_list = False
+ for s2 in old_spns:
+ if s2.upper() == s.upper():
+ in_list = True
+ break
+ if not in_list:
+ add_list.append(s)
+
+if opts.verbose:
+ print("New SPNs: %s" % add_list)
+
+if add_list == []:
+ if opts.verbose:
+ 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)
diff --git a/source4/scripting/python/samba/provision.py
b/source4/scripting/python/samba/provision.py
index 0757a72..8e79a8c 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -293,6 +293,7 @@ def provision_paths_from_lp(lp, dnsdomain):
paths.privilege = os.path.join(paths.private_dir, "privilege.ldb")
paths.dns = os.path.join(paths.private_dir, "dns", dnsdomain + ".zone")
paths.dns_update_list = os.path.join(paths.private_dir, "dns_update_list")
+ paths.spn_update_list = os.path.join(paths.private_dir, "spn_update_list")
paths.namedconf = os.path.join(paths.private_dir, "named.conf")
paths.namedconf_update = os.path.join(paths.private_dir,
"named.conf.update")
paths.namedtxt = os.path.join(paths.private_dir, "named.txt")
@@ -1556,6 +1557,9 @@ def create_zone_file(lp, message, paths, targetdir,
setup_path, dnsdomain,
# the substitution is done at runtime by samba_dnsupdate
setup_file(setup_path("dns_update_list"), paths.dns_update_list, None)
+ # and the SPN update list
+ setup_file(setup_path("spn_update_list"), paths.spn_update_list, None)
+
if paths.bind_gid is not None:
try:
os.chown(dns_dir, -1, paths.bind_gid)
@@ -1575,7 +1579,7 @@ def create_dns_update_list(lp, message, paths,
setup_path):
# note that we use no variable substitution on this file
# the substitution is done at runtime by samba_dnsupdate
setup_file(setup_path("dns_update_list"), paths.dns_update_list, None)
-
+ setup_file(setup_path("spn_update_list"), paths.spn_update_list, None)
def create_named_conf(paths, setup_path, realm, dnsdomain,
private_dir):
diff --git a/source4/scripting/wscript_build b/source4/scripting/wscript_build
index 5911364..834e80b 100644
--- a/source4/scripting/wscript_build
+++ b/source4/scripting/wscript_build
@@ -1,7 +1,7 @@
#!/usr/bin/env python
O755 = 493
-bld.INSTALL_FILES('${SBINDIR}','bin/upgradeprovision bin/samba_dnsupdate',
+bld.INSTALL_FILES('${SBINDIR}','bin/upgradeprovision bin/samba_dnsupdate
bin/samba_spnupdate',
chmod=O755, python_fixup=True, flat=True)
diff --git a/source4/setup/dns_update_list b/source4/setup/dns_update_list
index 0e32cda..c69e155 100644
--- a/source4/setup/dns_update_list
+++ b/source4/setup/dns_update_list
@@ -1,3 +1,5 @@
+# this is a list of DNS entries which will be put into DNS using
+# dynamic DNS update. It is processed by the samba_dnsupdate script
A ${DNSDOMAIN} $IP
A ${HOSTNAME} $IP
CNAME ${NTDSGUID}._msdcs.${DNSDOMAIN} ${HOSTNAME}
diff --git a/source4/setup/spn_update_list b/source4/setup/spn_update_list
new file mode 100644
index 0000000..e015e35
--- /dev/null
+++ b/source4/setup/spn_update_list
@@ -0,0 +1,27 @@
+# this is a list of servicePrincipalName entries
+# that we need to add on our account. It is processed by
+# the samba_spnupdate script
+
+ldap/${HOSTNAME}/${DNSDOMAIN}
+ldap/${HOSTNAME}
+ldap/${NETBIOSNAME}
+ldap/${HOSTNAME}/${WORKGROUP}
+ldap/${NTDSGUID}._msdcs.${DNSDOMAIN}
+ldap/${NETBIOSNAME}/${WORKGROUP}
+E3514235-4B06-11D1-AB04-00C04FC2DCD2/${NTDSGUID}/${DNSDOMAIN}
+HOST/${HOSTNAME}/${DNSDOMAIN}
+HOST/${HOSTNAME}
+HOST/${NETBIOSNAME}
+HOST/${HOSTNAME}/${WORKGROUP}
+HOST/${NETBIOSNAME}/${WORKGROUP}
+RestrictedKrbHost/${NETBIOSNAME}
+RestrictedKrbHost/${HOSTNAME}
+GC/${HOSTNAME}/${DNSDOMAIN}
+DNS/${HOSTNAME}
+
+# these are not supported yet
+# Dfsr-12F9A27C-BF97-4787-9364-D31B6C55EB04/${HOSTNAME}
+# TERMSRV/${HOSTNAME}
+# TERMSRV/${NETBIOSNAME}
+# ldap/${HOSTNAME}/DomainDnsZones.${DNSDOMAIN}
+# ldap/${HOSTNAME}/ForestDnsZones.${DNSDOMAIN}
--
Samba Shared Repository