[PATCH] Create a 'binddns dir' for files used by the bind_dlz module and named
Andreas Schneider
asn at samba.org
Wed Aug 23 14:27:17 UTC 2017
Hi,
we have an issue that the files for bind are stored in the private directory.
Distributions package the private directory normally with 0700 permissions. So
'named' of bind is not able to access the directory.
We should have a seperate directory where bind is allowed to enter for
security reasons!
The attached patchset adds a 'binddns dir' parameter which normally ends up
with /var/lib/samba/bind-dns as the directory. The changes are fully
backwards-compatible and the installation can be upgraded using
samba_upgradedns. Then the old files are removed!
We need this for Samba 4.7!
Please review!
Thanks,
Andreas
--
Andreas Schneider GPG-ID: CC014E3D
Samba Team asn at samba.org
www.samba.org
-------------- next part --------------
>From 68d1b7d34a2de4693e6ae6a8323f869870a52199 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 10 Aug 2017 11:36:52 +0200
Subject: [PATCH 1/9] wafsamba: Add INSTALL_DIR function
The install_dir function in waf has been deprecated and it doesn't
support setting directory permissions. So we need to implement our own
function anyway.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12957
Signed-off-by: Andreas Schneider <asn at samba.org>
---
buildtools/wafsamba/wafsamba.py | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/buildtools/wafsamba/wafsamba.py b/buildtools/wafsamba/wafsamba.py
index 1bdabf60640..b1e617916e0 100644
--- a/buildtools/wafsamba/wafsamba.py
+++ b/buildtools/wafsamba/wafsamba.py
@@ -885,6 +885,24 @@ def INSTALL_WILDCARD(bld, destdir, pattern, chmod=MODE_644, flat=False,
python_fixup=python_fixup, base_name=trim_path)
Build.BuildContext.INSTALL_WILDCARD = INSTALL_WILDCARD
+def INSTALL_DIR(bld, path, chmod=0o755):
+ """Install a directory if it doesn't exist, always set permissions."""
+
+ if not path:
+ return []
+
+ if bld.is_install > 0:
+ path = bld.EXPAND_VARIABLES(path)
+ if not os.path.isdir(path):
+ try:
+ os.makedirs(path)
+ os.chmod(path, chmod)
+ except OSError, e:
+ if not os.path.isdir(path):
+ raise Utils.WafError("Cannot create the folder '%s' (error: %s)" % (path, e))
+ else:
+ os.chmod(path, chmod)
+Build.BuildContext.INSTALL_DIR = INSTALL_DIR
def INSTALL_DIRS(bld, destdir, dirs):
'''install a set of directories'''
--
2.14.1
>From 7e05ee50cd4dc31ea22172496fd5c5c723c4f7c6 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 10 Aug 2017 11:40:06 +0200
Subject: [PATCH 2/9] wafsamba: Call INSTALL_DIR in INSTALL_DIRS
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12957
Signed-off-by: Andreas Schneider <asn at samba.org>
---
buildtools/wafsamba/wafsamba.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/buildtools/wafsamba/wafsamba.py b/buildtools/wafsamba/wafsamba.py
index b1e617916e0..57913af2bd7 100644
--- a/buildtools/wafsamba/wafsamba.py
+++ b/buildtools/wafsamba/wafsamba.py
@@ -904,12 +904,12 @@ def INSTALL_DIR(bld, path, chmod=0o755):
os.chmod(path, chmod)
Build.BuildContext.INSTALL_DIR = INSTALL_DIR
-def INSTALL_DIRS(bld, destdir, dirs):
+def INSTALL_DIRS(bld, destdir, dirs, chmod=0o755):
'''install a set of directories'''
destdir = bld.EXPAND_VARIABLES(destdir)
dirs = bld.EXPAND_VARIABLES(dirs)
for d in TO_LIST(dirs):
- bld.install_dir(os.path.join(destdir, d))
+ INSTALL_DIR(bld, os.path.join(destdir, d), chmod)
Build.BuildContext.INSTALL_DIRS = INSTALL_DIRS
--
2.14.1
>From dd2122c37705c7dcee29c4f878536144f8f48515 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 10 Aug 2017 11:42:46 +0200
Subject: [PATCH 3/9] dynconfig: Use INSTALL_DIR to create directories
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12957
Signed-off-by: Andreas Schneider <asn at samba.org>
---
dynconfig/wscript | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/dynconfig/wscript b/dynconfig/wscript
index 4eaa4c0b0c4..7e9bde929d0 100644
--- a/dynconfig/wscript
+++ b/dynconfig/wscript
@@ -415,9 +415,12 @@ def build(bld):
cflags=cflags)
# install some extra empty directories
- bld.INSTALL_DIRS("", "${CONFIGDIR} ${PRIVATE_DIR} ${LOGFILEBASE}");
- bld.INSTALL_DIRS("", "${PRIVATE_DIR} ${PRIVILEGED_SOCKET_DIR}")
- bld.INSTALL_DIRS("", "${STATEDIR} ${CACHEDIR}");
+ bld.INSTALL_DIR("${CONFIGDIR}")
+ bld.INSTALL_DIR("${LOGFILEBASE}")
+ bld.INSTALL_DIR("${PRIVILEGED_SOCKET_DIR}")
+ bld.INSTALL_DIR("${PRIVATE_DIR}")
+ bld.INSTALL_DIR("${STATEDIR}")
+ bld.INSTALL_DIR("${CACHEDIR}")
# these might be on non persistent storage
bld.INSTALL_DIRS("", "${LOCKDIR} ${PIDDIR} ${SOCKET_DIR}")
--
2.14.1
>From 36acc3e55c12aa0490185cf3b0c1cdac67fa2381 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 10 Aug 2017 11:43:11 +0200
Subject: [PATCH 4/9] dynconfig: Change permission of the private dir to 0700
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12957
Signed-off-by: Andreas Schneider <asn at samba.org>
---
dynconfig/wscript | 2 +-
python/samba/provision/__init__.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dynconfig/wscript b/dynconfig/wscript
index 7e9bde929d0..ba0c896b90e 100644
--- a/dynconfig/wscript
+++ b/dynconfig/wscript
@@ -418,7 +418,7 @@ def build(bld):
bld.INSTALL_DIR("${CONFIGDIR}")
bld.INSTALL_DIR("${LOGFILEBASE}")
bld.INSTALL_DIR("${PRIVILEGED_SOCKET_DIR}")
- bld.INSTALL_DIR("${PRIVATE_DIR}")
+ bld.INSTALL_DIR("${PRIVATE_DIR}", 0o700)
bld.INSTALL_DIR("${STATEDIR}")
bld.INSTALL_DIR("${CACHEDIR}")
diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py
index 2387931987e..91d2105929c 100644
--- a/python/samba/provision/__init__.py
+++ b/python/samba/provision/__init__.py
@@ -2065,7 +2065,7 @@ def provision(logger, session_info, smbconf=None,
serverrole = lp.get("server role")
if not os.path.exists(paths.private_dir):
- os.mkdir(paths.private_dir)
+ os.mkdir(paths.private_dir, 0o700)
if not os.path.exists(os.path.join(paths.private_dir, "tls")):
os.makedirs(os.path.join(paths.private_dir, "tls"), 0700)
if not os.path.exists(paths.state_dir):
--
2.14.1
>From 2f603e93fdc497816b586a0667244d63bf9639c1 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 11 Aug 2017 12:45:14 +0200
Subject: [PATCH 5/9] python:samba: Remove code to change group
This is the wrong place, it will just prepare the ldif. The file is not
created here.
The code is corrently changing the group in:
python/samba/provision/__init__.py
Signed-off-by: Andreas Schneider <asn at samba.org>
---
python/samba/provision/sambadns.py | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/python/samba/provision/sambadns.py b/python/samba/provision/sambadns.py
index 961f37e16a6..dcb19c7053c 100644
--- a/python/samba/provision/sambadns.py
+++ b/python/samba/provision/sambadns.py
@@ -1199,16 +1199,6 @@ def setup_bind9_dns(samdb, secretsdb, names, paths, lp, logger,
dns_keytab_path=paths.dns_keytab, dnspass=dnspass,
key_version_number=key_version_number)
- dns_keytab_path = os.path.join(paths.private_dir, paths.dns_keytab)
- if os.path.isfile(dns_keytab_path) and paths.bind_gid is not None:
- try:
- os.chmod(dns_keytab_path, 0640)
- os.chown(dns_keytab_path, -1, paths.bind_gid)
- except OSError:
- if not os.environ.has_key('SAMBA_SELFTEST'):
- logger.info("Failed to chown %s to bind gid %u",
- dns_keytab_path, paths.bind_gid)
-
create_dns_dir(logger, paths)
if dns_backend == "BIND9_FLATFILE":
--
2.14.1
>From 4d9a622e33c89c2821e5e7067e0337a7b1397a9d Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 10 Aug 2017 15:04:08 +0200
Subject: [PATCH 6/9] param: Add 'binddns dir' parameter
This allows to us to have restricted acess to the directory by the group
'named' which bind is a member of.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12957
Signed-off-by: Andreas Schneider <asn at samba.org>
---
buildtools/wafsamba/samba_patterns.py | 1 +
docs-xml/smbdotconf/generate-file-list.sh | 1 +
docs-xml/smbdotconf/security/binddnsdir.xml | 18 ++++++++++++++++++
dynconfig/dynconfig.c | 1 +
dynconfig/dynconfig.h | 1 +
dynconfig/wscript | 7 +++++++
lib/param/loadparm.c | 1 +
lib/param/param.h | 1 +
8 files changed, 31 insertions(+)
create mode 100644 docs-xml/smbdotconf/security/binddnsdir.xml
diff --git a/buildtools/wafsamba/samba_patterns.py b/buildtools/wafsamba/samba_patterns.py
index e809f26a095..2b939372fa4 100644
--- a/buildtools/wafsamba/samba_patterns.py
+++ b/buildtools/wafsamba/samba_patterns.py
@@ -108,6 +108,7 @@ def write_build_options_header(fp):
fp.write(" output(screen,\" PIDDIR: %s\\n\", get_dyn_PIDDIR());\n")
fp.write(" output(screen,\" SMB_PASSWD_FILE: %s\\n\",get_dyn_SMB_PASSWD_FILE());\n")
fp.write(" output(screen,\" PRIVATE_DIR: %s\\n\",get_dyn_PRIVATE_DIR());\n")
+ fp.write(" output(screen,\" BINDDNS_DIR: %s\\n\",get_dyn_BINDDNS_DIR());\n")
fp.write("\n")
def write_build_options_footer(fp):
diff --git a/docs-xml/smbdotconf/generate-file-list.sh b/docs-xml/smbdotconf/generate-file-list.sh
index 4a25f1e6d49..7ab1b7caf76 100755
--- a/docs-xml/smbdotconf/generate-file-list.sh
+++ b/docs-xml/smbdotconf/generate-file-list.sh
@@ -11,6 +11,7 @@ echo "<!DOCTYPE section [
<!ENTITY pathconfig.PIDDIR '\${prefix}/var/run'>
<!ENTITY pathconfig.STATEDIR '\${prefix}/var/locks'>
<!ENTITY pathconfig.PRIVATE_DIR '\${prefix}/private'>
+<!ENTITY pathconfig.BINDDNS_DIR '\${prefix}/bind-dns'>
<!ENTITY pathconfig.SMB_PASSWD_FILE '\${prefix}/private/smbpasswd'>
<!ENTITY pathconfig.WINBINDD_SOCKET_DIR '\${prefix}/var/run/winbindd'>
<!ENTITY pathconfig.CACHEDIR '\${prefix}/var/cache'>
diff --git a/docs-xml/smbdotconf/security/binddnsdir.xml b/docs-xml/smbdotconf/security/binddnsdir.xml
new file mode 100644
index 00000000000..c296a0ef81d
--- /dev/null
+++ b/docs-xml/smbdotconf/security/binddnsdir.xml
@@ -0,0 +1,18 @@
+<samba:parameter name="binddns dir"
+ context="G"
+ type="string"
+ constant="1"
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<synonym>bind dns directory</synonym>
+<description>
+ <para>
+ This parameters defines the directory samba will use to store the configuration
+ files for bind, such as named.conf.
+
+ NOTE: The bind dns directory needs to be on the same mount point as the private
+ directory!
+ </para>
+</description>
+
+<value type="default">&pathconfig.BINDDNS_DIR;</value>
+</samba:parameter>
diff --git a/dynconfig/dynconfig.c b/dynconfig/dynconfig.c
index e75d7db553a..e70a10f8cfe 100644
--- a/dynconfig/dynconfig.c
+++ b/dynconfig/dynconfig.c
@@ -95,6 +95,7 @@ DEFINE_DYN_CONFIG_PARAM(PIDDIR)
DEFINE_DYN_CONFIG_PARAM(NCALRPCDIR)
DEFINE_DYN_CONFIG_PARAM(SMB_PASSWD_FILE)
DEFINE_DYN_CONFIG_PARAM(PRIVATE_DIR)
+DEFINE_DYN_CONFIG_PARAM(BINDDNS_DIR)
DEFINE_DYN_CONFIG_PARAM(LOCALEDIR)
DEFINE_DYN_CONFIG_PARAM(NMBDSOCKETDIR)
DEFINE_DYN_CONFIG_PARAM(DATADIR)
diff --git a/dynconfig/dynconfig.h b/dynconfig/dynconfig.h
index 4d07c103d74..bdab2e8f242 100644
--- a/dynconfig/dynconfig.h
+++ b/dynconfig/dynconfig.h
@@ -46,6 +46,7 @@ DEFINE_DYN_CONFIG_PROTO(PIDDIR)
DEFINE_DYN_CONFIG_PROTO(NCALRPCDIR)
DEFINE_DYN_CONFIG_PROTO(SMB_PASSWD_FILE)
DEFINE_DYN_CONFIG_PROTO(PRIVATE_DIR)
+DEFINE_DYN_CONFIG_PROTO(BINDDNS_DIR)
DEFINE_DYN_CONFIG_PROTO(LOCALEDIR)
DEFINE_DYN_CONFIG_PROTO(NMBDSOCKETDIR)
DEFINE_DYN_CONFIG_PROTO(DATADIR)
diff --git a/dynconfig/wscript b/dynconfig/wscript
index ba0c896b90e..fee37eaaf5f 100644
--- a/dynconfig/wscript
+++ b/dynconfig/wscript
@@ -192,6 +192,12 @@ dynconfig = {
'OPTION': '--with-statedir',
'HELPTEXT': 'Where to put persistent state files',
},
+ 'BINDDNS_DIR' : {
+ 'STD-PATH': '${LOCALSTATEDIR}/lib',
+ 'FHS-PATH': '${LOCALSTATEDIR}/lib/samba/bind-dns',
+ 'OPTION': '--with-bind-dns-dir',
+ 'HELPTEXT': 'bind-dns config directory',
+ },
'CACHEDIR' : {
'STD-PATH': '${LOCALSTATEDIR}/cache',
'FHS-PATH': '${LOCALSTATEDIR}/cache/samba',
@@ -419,6 +425,7 @@ def build(bld):
bld.INSTALL_DIR("${LOGFILEBASE}")
bld.INSTALL_DIR("${PRIVILEGED_SOCKET_DIR}")
bld.INSTALL_DIR("${PRIVATE_DIR}", 0o700)
+ bld.INSTALL_DIR("${BINDDNS_DIR}", 0o770)
bld.INSTALL_DIR("${STATEDIR}")
bld.INSTALL_DIR("${CACHEDIR}")
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index a221e879d07..b91f9657f1c 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2655,6 +2655,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
/* the winbind method for domain controllers is for both RODC
auth forwarding and for trusted domains */
lpcfg_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
+ lpcfg_do_global_parameter(lp_ctx, "binddns dir", dyn_BINDDNS_DIR);
lpcfg_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
/* This hive should be dynamically generated by Samba using
diff --git a/lib/param/param.h b/lib/param/param.h
index 589b8906db5..680c053a6cc 100644
--- a/lib/param/param.h
+++ b/lib/param/param.h
@@ -56,6 +56,7 @@ const char **lpcfg_interfaces(struct loadparm_context *);
const char *lpcfg_realm(struct loadparm_context *);
const char *lpcfg_netbios_name(struct loadparm_context *);
const char *lpcfg_private_dir(struct loadparm_context *);
+const char *lpcfg_binddns_dir(struct loadparm_context *);
int lpcfg_server_role(struct loadparm_context *);
int lpcfg_allow_dns_updates(struct loadparm_context *);
--
2.14.1
>From 563175910963bfa9b2b0ea3cb3e45f5ff6b372e7 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Tue, 22 Aug 2017 17:10:01 +0200
Subject: [PATCH 7/9] s4:bind_dlz: Use the 'binddns dir' if possible
The code makes sure we are backwards compatible. It will first check if
we still have files in the private directory, if yes it will use those.
If the the file is not in the private directory it will try the binddns
dir.
Signed-off-by: Andreas Schneider <asn at samba.org>
---
source4/dns_server/dlz_bind9.c | 44 +++++++++++++++++++++++++++++++++++++---
source4/dsdb/dns/dns_update.c | 46 +++++++++++++++++++++++++++++++++++++++---
2 files changed, 84 insertions(+), 6 deletions(-)
diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c
index 7fec9423924..75a9ce0f648 100644
--- a/source4/dns_server/dlz_bind9.c
+++ b/source4/dns_server/dlz_bind9.c
@@ -682,11 +682,23 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname,
}
if (state->options.url == NULL) {
- state->options.url = lpcfg_private_path(state, state->lp, "dns/sam.ldb");
+ state->options.url = lpcfg_private_path(state,
+ state->lp,
+ "dns/sam.ldb");
if (state->options.url == NULL) {
result = ISC_R_NOMEMORY;
goto failed;
}
+
+ if (!file_exist(state->options.url)) {
+ state->options.url = talloc_asprintf(state,
+ "%s/dns/sam.ldb",
+ lpcfg_binddns_dir(state->lp));
+ if (state->options.url == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto failed;
+ }
+ }
}
state->samdb = samdb_connect_url(state, state->ev_ctx, state->lp,
@@ -1266,6 +1278,7 @@ _PUBLIC_ isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const
DATA_BLOB ap_req;
struct cli_credentials *server_credentials;
char *keytab_name;
+ char *keytab_file = NULL;
int ret;
int ldb_ret;
NTSTATUS nt_status;
@@ -1309,8 +1322,33 @@ _PUBLIC_ isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const
cli_credentials_set_krb5_context(server_credentials, state->smb_krb5_ctx);
cli_credentials_set_conf(server_credentials, state->lp);
- keytab_name = talloc_asprintf(tmp_ctx, "FILE:%s/dns.keytab",
- lpcfg_private_dir(state->lp));
+ keytab_file = talloc_asprintf(tmp_ctx,
+ "%s/dns.keytab",
+ lpcfg_private_dir(state->lp));
+ if (keytab_file == NULL) {
+ state->log(ISC_LOG_ERROR, "samba_dlz: Out of memory!");
+ talloc_free(tmp_ctx);
+ return ISC_FALSE;
+ }
+
+ if (!file_exist(keytab_file)) {
+ keytab_file = talloc_asprintf(tmp_ctx,
+ "%s/dns.keytab",
+ lpcfg_binddns_dir(state->lp));
+ if (keytab_file == NULL) {
+ state->log(ISC_LOG_ERROR, "samba_dlz: Out of memory!");
+ talloc_free(tmp_ctx);
+ return ISC_FALSE;
+ }
+ }
+
+ keytab_name = talloc_asprintf(tmp_ctx, "FILE:%s", keytab_file);
+ if (keytab_name == NULL) {
+ state->log(ISC_LOG_ERROR, "samba_dlz: Out of memory!");
+ talloc_free(tmp_ctx);
+ return ISC_FALSE;
+ }
+
ret = cli_credentials_set_keytab_name(server_credentials, state->lp, keytab_name,
CRED_SPECIFIED);
if (ret != 0) {
diff --git a/source4/dsdb/dns/dns_update.c b/source4/dsdb/dns/dns_update.c
index f74256d95ea..ba8431a3d1d 100644
--- a/source4/dsdb/dns/dns_update.c
+++ b/source4/dsdb/dns/dns_update.c
@@ -170,16 +170,56 @@ static void dnsupdate_rebuild(struct dnsupdate_service *service)
path = lpcfg_parm_string(service->task->lp_ctx, NULL, "dnsupdate", "path");
if (path == NULL) {
- path = lpcfg_private_path(tmp_ctx, service->task->lp_ctx, "named.conf.update");
+ path = lpcfg_private_path(tmp_ctx,
+ service->task->lp_ctx,
+ "named.conf.update");
+ if (path == NULL) {
+ DBG_ERR("Out of memory!");
+ talloc_free(tmp_ctx);
+ return;
+ }
+
+ /*
+ * If the file doesn't exist, we provisioned in a the new
+ * bind-dns directory
+ */
+ if (!file_exist(path)) {
+ path = talloc_asprintf(tmp_ctx,
+ "%s/named.conf.update",
+ lpcfg_binddns_dir(service->task->lp_ctx));
+ if (path == NULL) {
+ DBG_ERR("Out of memory!");
+ talloc_free(tmp_ctx);
+ return;
+ }
+ }
}
path_static = lpcfg_parm_string(service->task->lp_ctx, NULL, "dnsupdate", "extra_static_grant_rules");
if (path_static == NULL) {
- path_static = lpcfg_private_path(tmp_ctx, service->task->lp_ctx, "named.conf.update.static");
+ path_static = lpcfg_private_path(tmp_ctx,
+ service->task->lp_ctx,
+ "named.conf.update.static");
+ if (path_static == NULL) {
+ DBG_ERR("Out of memory!");
+ talloc_free(tmp_ctx);
+ return;
+ }
+
+ if (!file_exist(path_static)) {
+ path_static = talloc_asprintf(tmp_ctx,
+ "%s/named.conf.update.static",
+ lpcfg_binddns_dir(service->task->lp_ctx));
+ if (path_static == NULL) {
+ DBG_ERR("Out of memory!");
+ talloc_free(tmp_ctx);
+ return;
+ }
+ }
}
tmp_path = talloc_asprintf(tmp_ctx, "%s.tmp", path);
- if (path == NULL || tmp_path == NULL || path_static == NULL ) {
+ if (tmp_path == NULL) {
DEBUG(0,(__location__ ": Unable to get paths\n"));
talloc_free(tmp_ctx);
return;
--
2.14.1
>From 36d3c9e71510bf6abc184e073e15f57b4d644d96 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 10 Aug 2017 15:37:54 +0200
Subject: [PATCH 8/9] python:samba: Use 'binddns dir' in samba-tool and
samba_upgradedns
This provisions the bind_dlz files in the 'binddns dir'. If you want to
migrate to the new files strcuture you can run samba_upgradedns!
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12957
Signed-off-by: Andreas Schneider <asn at samba.org>
---
python/samba/provision/__init__.py | 31 +++++++++++++++++++++++++------
python/samba/provision/sambadns.py | 12 +++++++-----
source4/scripting/bin/samba_upgradedns | 6 +++---
3 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py
index 91d2105929c..60a7fae373a 100644
--- a/python/samba/provision/__init__.py
+++ b/python/samba/provision/__init__.py
@@ -145,6 +145,7 @@ class ProvisionPaths(object):
self.dns = None
self.winsdb = None
self.private_dir = None
+ self.binddns_dir = None
self.state_dir = None
@@ -531,6 +532,7 @@ def provision_paths_from_lp(lp, dnsdomain):
"""
paths = ProvisionPaths()
paths.private_dir = lp.get("private dir")
+ paths.binddns_dir = lp.get("binddns dir")
paths.state_dir = lp.get("state directory")
# This is stored without path prefix for the "privateKeytab" attribute in
@@ -543,16 +545,18 @@ def provision_paths_from_lp(lp, dnsdomain):
paths.idmapdb = os.path.join(paths.private_dir, "idmap.ldb")
paths.secrets = os.path.join(paths.private_dir, "secrets.ldb")
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")
paths.krb5conf = os.path.join(paths.private_dir, "krb5.conf")
paths.kdcconf = os.path.join(paths.private_dir, "kdc.conf")
paths.winsdb = os.path.join(paths.private_dir, "wins.ldb")
paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi")
+
+ paths.dns = os.path.join(paths.binddns_dir, "dns", dnsdomain + ".zone")
+ paths.namedconf = os.path.join(paths.binddns_dir, "named.conf")
+ paths.namedconf_update = os.path.join(paths.binddns_dir, "named.conf.update")
+ paths.namedtxt = os.path.join(paths.binddns_dir, "named.txt")
+
paths.hklm = "hklm.ldb"
paths.hkcr = "hkcr.ldb"
paths.hkcu = "hkcu.ldb"
@@ -945,7 +949,7 @@ def setup_secretsdb(paths, session_info, backend_credentials, lp):
if os.path.exists(keytab_path):
os.unlink(keytab_path)
- dns_keytab_path = os.path.join(paths.private_dir, paths.dns_keytab)
+ dns_keytab_path = os.path.join(paths.binddns_dir, paths.dns_keytab)
if os.path.exists(dns_keytab_path):
os.unlink(dns_keytab_path)
@@ -2070,6 +2074,8 @@ def provision(logger, session_info, smbconf=None,
os.makedirs(os.path.join(paths.private_dir, "tls"), 0700)
if not os.path.exists(paths.state_dir):
os.mkdir(paths.state_dir)
+ if not os.path.exists(paths.binddns_dir):
+ os.mkdir(paths.binddns_dir, 0o770)
if paths.sysvol and not os.path.exists(paths.sysvol):
os.makedirs(paths.sysvol, 0775)
@@ -2199,7 +2205,20 @@ def provision(logger, session_info, smbconf=None,
secrets_ldb.transaction_commit()
# the commit creates the dns.keytab, now chown it
- dns_keytab_path = os.path.join(paths.private_dir, paths.dns_keytab)
+ dns_private_keytab_path = os.path.join(paths.private_dir, paths.dns_keytab)
+ dns_keytab_path = os.path.join(paths.binddns_dir, paths.dns_keytab)
+
+ if os.path.isfile(dns_keytab_path):
+ os.unlink(dns_keytab_path)
+
+ if os.path.isfile(dns_private_keytab_path):
+ try:
+ os.link(dns_private_keytab_path, dns_keytab_path)
+ except OSError:
+ logger.error("Failed to setup DNS keytab for BIND, "
+ "AD based DNS cannot be used")
+ raise
+
if os.path.isfile(dns_keytab_path) and paths.bind_gid is not None:
try:
os.chmod(dns_keytab_path, 0640)
diff --git a/python/samba/provision/sambadns.py b/python/samba/provision/sambadns.py
index dcb19c7053c..268c949e34e 100644
--- a/python/samba/provision/sambadns.py
+++ b/python/samba/provision/sambadns.py
@@ -665,6 +665,8 @@ def secretsdb_setup_dns(secretsdb, names, private_dir, realm,
if key_version_number is None:
key_version_number = 1
+ # This will create the dns.keytab file in the private_dir when it is
+ # commited!
setup_ldb(secretsdb, setup_path("secrets_dns.ldif"), {
"REALM": realm,
"DNSDOMAIN": dnsdomain,
@@ -954,7 +956,7 @@ def create_named_conf(paths, realm, dnsdomain, dns_backend, logger):
})
-def create_named_txt(path, realm, dnsdomain, dnsname, private_dir,
+def create_named_txt(path, realm, dnsdomain, dnsname, binddns_dir,
keytab_name):
"""Write out a file containing zone statements suitable for inclusion in a
named.conf file (including GSS-TSIG configuration).
@@ -962,7 +964,7 @@ def create_named_txt(path, realm, dnsdomain, dnsname, private_dir,
:param path: Path of the new named.conf file.
:param realm: Realm name
:param dnsdomain: DNS Domain name
- :param private_dir: Path to private directory
+ :param binddns_dir: Path to bind dns directory
:param keytab_name: File name of DNS keytab file
"""
setup_file(setup_path("named.txt"), path, {
@@ -970,8 +972,8 @@ def create_named_txt(path, realm, dnsdomain, dnsname, private_dir,
"DNSNAME" : dnsname,
"REALM": realm,
"DNS_KEYTAB": keytab_name,
- "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name),
- "PRIVATE_DIR": private_dir
+ "DNS_KEYTAB_ABS": os.path.join(binddns_dir, keytab_name),
+ "PRIVATE_DIR": binddns_dir
})
@@ -1218,7 +1220,7 @@ def setup_bind9_dns(samdb, secretsdb, names, paths, lp, logger,
create_named_txt(paths.namedtxt,
realm=names.realm, dnsdomain=names.dnsdomain,
dnsname = "%s.%s" % (names.hostname, names.dnsdomain),
- private_dir=paths.private_dir,
+ binddns_dir=paths.binddns_dir,
keytab_name=paths.dns_keytab)
logger.info("See %s for an example configuration include file for BIND",
paths.namedconf)
diff --git a/source4/scripting/bin/samba_upgradedns b/source4/scripting/bin/samba_upgradedns
index d00b67daca1..316ad930721 100755
--- a/source4/scripting/bin/samba_upgradedns
+++ b/source4/scripting/bin/samba_upgradedns
@@ -446,7 +446,7 @@ if __name__ == '__main__':
dns_key_version_number = None
secretsdb_setup_dns(ldbs.secrets, names,
- paths.private_dir, realm=names.realm,
+ paths.binddns_dir, realm=names.realm,
dnsdomain=names.dnsdomain,
dns_keytab_path=paths.dns_keytab, dnspass=dnspass,
key_version_number=dns_key_version_number)
@@ -454,7 +454,7 @@ if __name__ == '__main__':
else:
logger.info("dns-%s account already exists" % hostname)
- dns_keytab_path = os.path.join(paths.private_dir, paths.dns_keytab)
+ dns_keytab_path = os.path.join(paths.binddns_dir, paths.dns_keytab)
if os.path.isfile(dns_keytab_path) and paths.bind_gid is not None:
try:
os.chmod(dns_keytab_path, 0640)
@@ -476,7 +476,7 @@ if __name__ == '__main__':
create_named_conf(paths, names.realm, dnsdomain, opts.dns_backend, logger)
create_named_txt(paths.namedtxt, names.realm, dnsdomain, dnsname,
- paths.private_dir, paths.dns_keytab)
+ paths.binddns_dir, paths.dns_keytab)
logger.info("See %s for an example configuration include file for BIND", paths.namedconf)
logger.info("and %s for further documentation required for secure DNS "
"updates", paths.namedtxt)
--
2.14.1
>From d136a05136874e35ec283102e76b0d32182afca3 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 23 Aug 2017 15:36:23 +0200
Subject: [PATCH 9/9] python:samba: Add code to remove obsolete files in the
private dir
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12957
Signed-off-by: Andreas Schneider <asn at samba.org>
---
source4/scripting/bin/samba_upgradedns | 35 ++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/source4/scripting/bin/samba_upgradedns b/source4/scripting/bin/samba_upgradedns
index 316ad930721..cac6815d3ec 100755
--- a/source4/scripting/bin/samba_upgradedns
+++ b/source4/scripting/bin/samba_upgradedns
@@ -20,6 +20,7 @@
import sys
import os
+import errno
import optparse
import logging
import grp
@@ -209,6 +210,37 @@ def import_zone_data(samdb, logger, zone, serial, domaindn, forestdn,
raise
logger.debug("Added DNS record %s" % (fqdn))
+def cleanup_remove_file(file_path):
+ try:
+ os.remove(file_path)
+ except OSError as e:
+ if e.errno not in [errno.EEXIST, errno.ENOENT]:
+ pass
+ else:
+ logger.debug("Could not remove %s: %s" % (file_path, e.strerror))
+
+def cleanup_remove_dir(dir_path):
+ try:
+ for root, dirs, files in os.walk(dir_path, topdown=False):
+ for name in files:
+ os.remove(os.path.join(root, name))
+ for name in dirs:
+ os.rmdir(os.path.join(root, name))
+ os.rmdir(dir_path)
+ except OSError as e:
+ if e.errno not in [errno.EEXIST, errno.ENOENT]:
+ pass
+ else:
+ logger.debug("Could not delete dir %s: %s" % (dir_path, e.strerror))
+
+def cleanup_obsolete_dns_files(paths):
+ cleanup_remove_file(os.path.join(paths.private_dir, "named.conf"))
+ cleanup_remove_file(os.path.join(paths.private_dir, "named.conf.update"))
+ cleanup_remove_file(os.path.join(paths.private_dir, "named.txt"))
+ cleanup_remove_file(os.path.join(paths.private_dir, "dns.keytab"))
+
+ cleanup_remove_dir(os.path.join(paths.private_dir, "dns"))
+
# dnsprovision creates application partitions for AD based DNS mainly if the existing
# provision was created using earlier snapshots of samba4 which did not have support
@@ -477,6 +509,9 @@ if __name__ == '__main__':
create_named_txt(paths.namedtxt, names.realm, dnsdomain, dnsname,
paths.binddns_dir, paths.dns_keytab)
+
+ cleanup_obsolete_dns_files(paths)
+
logger.info("See %s for an example configuration include file for BIND", paths.namedconf)
logger.info("and %s for further documentation required for secure DNS "
"updates", paths.namedtxt)
--
2.14.1
More information about the samba-technical
mailing list