1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-02 00:22:11 +03:00

s4:samba_dnsupdate Add a 'file based' mode to samba_dnsupdate

For the testsuite to use DNS like names, we need to write these names
to a file.

Also, to have this run in 'make test' the usual rules about 'no 127.*'
IP addresses in DNS must be skipped, so glue.interface_ips takes two
arguments now
This commit is contained in:
Andrew Bartlett
2010-03-09 23:34:10 +11:00
parent 79b4a3b22e
commit 3723e32e8c
3 changed files with 60 additions and 25 deletions

View File

@ -20,6 +20,7 @@
import getopt import getopt
import os import os
import fcntl
import sys import sys
import tempfile import tempfile
@ -49,6 +50,8 @@ sambaopts = options.SambaOptions(parser)
parser.add_option_group(sambaopts) parser.add_option_group(sambaopts)
parser.add_option_group(options.VersionOptions(parser)) parser.add_option_group(options.VersionOptions(parser))
parser.add_option("--verbose", action="store_true") parser.add_option("--verbose", action="store_true")
parser.add_option("--all-interfaces", action="store_true")
parser.add_option("--use-file", type="string", help="Use a file, rather than real DNS calls")
creds = None creds = None
ccachename = None ccachename = None
@ -63,7 +66,12 @@ lp = sambaopts.get_loadparm()
domain = lp.get("realm") domain = lp.get("realm")
host = lp.get("netbios name") host = lp.get("netbios name")
IPs = glue.interface_ips(lp) if opts.all_interfaces:
all_interfaces = True
else:
all_interfaces = False
IPs = glue.interface_ips(lp, all_interfaces)
nsupdate_cmd = lp.get('nsupdate command') nsupdate_cmd = lp.get('nsupdate command')
if len(IPs) == 0: if len(IPs) == 0:
@ -94,38 +102,37 @@ def get_credentials(lp):
############################################# #############################################
# an object to hold a parsed DNS line # an object to hold a parsed DNS line
class dnsobj(object): class dnsobj(object):
def __init__(self): def __init__(self, string_form):
self.type = None list = string_form.split()
self.name = None
self.dest = None self.dest = None
self.port = None self.port = None
self.ip = None self.ip = None
self.existing_port = None self.existing_port = None
self.existing_weight = None self.existing_weight = None
self.type = list[0]
self.name = list[1]
if self.type == 'SRV':
self.dest = list[2]
self.port = list[3]
elif self.type == 'A':
self.ip = list[2] # usually $IP, which gets replaced
elif self.type == 'CNAME':
self.dest = list[2]
else:
print "Received unexpected DNS reply of type %s" % self.type
raise
def __str__(self): def __str__(self):
if d.type == "A": return "%s:%s:%s" % (self.type, self.name, self.ip) if d.type == "A": return "%s %s %s" % (self.type, self.name, self.ip)
if d.type == "SRV": return "%s:%s:%s:%s" % (self.type, self.name, self.dest, self.port) if d.type == "SRV": return "%s %s %s %s" % (self.type, self.name, self.dest, self.port)
if d.type == "CNAME": return "%s:%s:%s" % (self.type, self.name, self.dest) if d.type == "CNAME": return "%s %s %s" % (self.type, self.name, self.dest)
################################################ ################################################
# parse a DNS line from # parse a DNS line from
def parse_dns_line(line, sub_vars): def parse_dns_line(line, sub_vars):
d = dnsobj()
subline = samba.substitute_var(line, sub_vars) subline = samba.substitute_var(line, sub_vars)
list = subline.split() d = dnsobj(subline)
d.type = list[0]
d.name = list[1]
if d.type == 'SRV':
d.dest = list[2]
d.port = list[3]
elif d.type == 'A':
d.ip = list[2] # usually $IP, which gets replaced
elif d.type == 'CNAME':
d.dest = list[2]
else:
print "Received unexpected DNS reply of type %s" % d.type
raise
return d return d
############################################ ############################################
@ -142,6 +149,24 @@ def check_dns_name(d):
normalised_name = d.name.rstrip('.') + '.' normalised_name = d.name.rstrip('.') + '.'
if opts.verbose: if opts.verbose:
print "Looking for DNS entry %s as %s" % (d, normalised_name) print "Looking for DNS entry %s as %s" % (d, normalised_name)
if opts.use_file is not None:
try:
dns_file = open(opts.use_file, "r")
except IOError:
return False
line = dns_file.readline()
while line:
line = line.rstrip().lstrip()
if line[0] == "#":
line = dns_file.readline()
continue
if line.lower() == str(d).lower():
return True
line = dns_file.readline()
return False
try: try:
ans = resolver.query(normalised_name, d.type) ans = resolver.query(normalised_name, d.type)
except resolver.NXDOMAIN: except resolver.NXDOMAIN:
@ -167,6 +192,7 @@ def check_dns_name(d):
d.existing_weight = str(rdata.weight) d.existing_weight = str(rdata.weight)
if opts.verbose: if opts.verbose:
print "Failed to find DNS entry %s" % d print "Failed to find DNS entry %s" % d
return False return False
@ -195,6 +221,14 @@ def call_nsupdate(d):
if opts.verbose: if opts.verbose:
print "Calling nsupdate for %s" % d print "Calling nsupdate for %s" % d
if opts.use_file is not None:
wfile = open(opts.use_file, 'a')
fcntl.lockf(wfile, fcntl.LOCK_EX)
wfile.write(str(d)+"\n")
fcntl.lockf(wfile, fcntl.LOCK_UN)
return
(tmp_fd, tmpfile) = tempfile.mkstemp() (tmp_fd, tmpfile) = tempfile.mkstemp()
f = os.fdopen(tmp_fd, 'w') f = os.fdopen(tmp_fd, 'w')
if d.type == "A": if d.type == "A":

View File

@ -614,8 +614,9 @@ static PyObject *py_interface_ips(PyObject *self, PyObject *args)
struct loadparm_context *lp_ctx; struct loadparm_context *lp_ctx;
struct interface *ifaces; struct interface *ifaces;
int i, ifcount; int i, ifcount;
int all_interfaces;
if (!PyArg_ParseTuple(args, "O", &py_lp_ctx)) if (!PyArg_ParseTuple(args, "Oi", &py_lp_ctx, &all_interfaces))
return NULL; return NULL;
lp_ctx = lp_from_py_object(py_lp_ctx); lp_ctx = lp_from_py_object(py_lp_ctx);
@ -633,7 +634,7 @@ static PyObject *py_interface_ips(PyObject *self, PyObject *args)
/* first count how many are not loopback addresses */ /* first count how many are not loopback addresses */
for (ifcount = i = 0; i<count; i++) { for (ifcount = i = 0; i<count; i++) {
const char *ip = iface_n_ip(ifaces, i); const char *ip = iface_n_ip(ifaces, i);
if (!iface_same_net(ip, "127.0.0.1", "255.0.0.0")) { if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
ifcount++; ifcount++;
} }
} }
@ -641,7 +642,7 @@ static PyObject *py_interface_ips(PyObject *self, PyObject *args)
pylist = PyList_New(ifcount); pylist = PyList_New(ifcount);
for (ifcount = i = 0; i<count; i++) { for (ifcount = i = 0; i<count; i++) {
const char *ip = iface_n_ip(ifaces, i); const char *ip = iface_n_ip(ifaces, i);
if (!iface_same_net(ip, "127.0.0.1", "255.0.0.0")) { if (!(!all_interfaces && iface_same_net(ip, "127.0.0.1", "255.0.0.0"))) {
PyList_SetItem(pylist, ifcount, PyString_FromString(ip)); PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
ifcount++; ifcount++;
} }

View File

@ -1182,7 +1182,7 @@ def provision(setup_dir, message, session_info,
paths.bind_gid = bind_gid paths.bind_gid = bind_gid
if hostip is None: if hostip is None:
hostips = glue.interface_ips(lp) hostips = glue.interface_ips(lp, False)
if len(hostips) == 0: if len(hostips) == 0:
message("No external IPv4 address has been found: I use the loopback.") message("No external IPv4 address has been found: I use the loopback.")
hostip = '127.0.0.1' hostip = '127.0.0.1'