python: Add provisioning support for MIT KDC in samba-tool
authorAndreas Schneider <asn@samba.org>
Fri, 9 Oct 2015 13:06:52 +0000 (15:06 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Sat, 29 Apr 2017 21:31:11 +0000 (23:31 +0200)
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Andrew Bartlet <abartlet@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
python/samba/__init__.py
python/samba/netcmd/domain.py
python/samba/provision/__init__.py
python/samba/provision/kerberos.py [new file with mode: 0644]

index 67aa82300f93017f8efe3474d659040e9976ff0f..6f79b3cc960e8b0e03d37c6d9d3cc1663d1a716f 100644 (file)
@@ -391,6 +391,7 @@ generate_random_machine_password = _glue.generate_random_machine_password
 strcasecmp_m = _glue.strcasecmp_m
 strstr_m = _glue.strstr_m
 is_ntvfs_fileserver_built = _glue.is_ntvfs_fileserver_built
+is_heimdal_built = _glue.is_heimdal_built
 
 NTSTATUSError = _glue.NTSTATUSError
 HRESULTError = _glue.HRESULTError
index 4bd99ba6ff5c8b2dedbdd3a36e6e4ca876900854..bfc4772b7b1cec64a077523827f0e9aaa26dab41 100644 (file)
@@ -87,6 +87,9 @@ from samba.provision import (
     ProvisioningError
     )
 
+from samba.provision.kerberos_implementation import (
+    kdc_default_config_dir)
+
 from samba.provision.common import (
     FILL_FULL,
     FILL_NT4SYNC,
@@ -263,12 +266,20 @@ class cmd_domain_provision(Command):
                default="auto")
     ]
 
+    kdc_options = [
+        Option("--kdc-config-dir", type="string", metavar="KDC-CONFIG-DIR",
+               help="Set the MIT KDC config directory (default='%s')" % kdc_default_config_dir),
+    ]
+
     if os.getenv('TEST_LDAP', "no") == "yes":
         takes_options.extend(openldap_options)
 
     if samba.is_ntvfs_fileserver_built():
          takes_options.extend(ntvfs_options)
 
+    if not samba.is_heimdal_built():
+        takes_options.extend(kdc_options)
+
     takes_args = []
 
     def run(self, sambaopts=None, versionopts=None,
@@ -304,6 +315,7 @@ class cmd_domain_provision(Command):
             use_xattrs="auto",
             slapd_path=None,
             use_ntvfs=False,
+            kdc_config_dir=None,
             use_rfc2307=None,
             ldap_backend_nosync=None,
             ldap_backend_extra_port=None,
@@ -471,7 +483,8 @@ class cmd_domain_provision(Command):
                   use_rfc2307=use_rfc2307, skip_sysvolacl=False,
                   ldap_backend_extra_port=ldap_backend_extra_port,
                   ldap_backend_forced_uri=ldap_backend_forced_uri,
-                  nosync=ldap_backend_nosync, ldap_dryrun_mode=ldap_dryrun_mode)
+                  nosync=ldap_backend_nosync, ldap_dryrun_mode=ldap_dryrun_mode,
+                  kdcconfdir=kdc_config_dir)
 
         except ProvisioningError, e:
             raise CommandError("Provision failed", e)
index f8e4696a2fd435305a6d027ade58d0b94c2e1023..b001c544fb9a65e429348fbea70dee715b278773 100644 (file)
@@ -118,7 +118,7 @@ import samba.registry
 from samba.schema import Schema
 from samba.samdb import SamDB
 from samba.dbchecker import dbcheck
-
+from samba.provision.kerberos import make_kdcconf
 
 DEFAULT_POLICY_GUID = "31B2F340-016D-11D2-945F-00C04FB984F9"
 DEFAULT_DC_POLICY_GUID = "6AC1786C-016F-11D2-945F-00C04FB984F9"
@@ -668,10 +668,9 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None,
 
     return names
 
-
 def make_smbconf(smbconf, hostname, domain, realm, targetdir,
                  serverrole=None, eadb=False, use_ntvfs=False, lp=None,
-                 global_param=None):
+                 global_param=None, kdcconfdir=None):
     """Create a new smb.conf file based on a couple of basic settings.
     """
     assert smbconf is not None
@@ -732,6 +731,11 @@ def make_smbconf(smbconf, hostname, domain, realm, targetdir,
                 statedir = lp.get("state directory")
             lp.set("xattr_tdb:file", os.path.abspath(os.path.join(statedir, "xattr.tdb")))
 
+    make_kdcconf(realm, domain, kdcconfdir, os.path.dirname(lp.get("log file")))
+    if kdcconfdir is not None:
+        kdcconf = "%s/kdc.conf" % kdcconfdir
+        lp.set("mit kdc config", kdcconf)
+
     shares = {}
     if serverrole == "active directory domain controller":
         shares["sysvol"] = os.path.join(lp.get("state directory"), "sysvol")
@@ -1925,7 +1929,7 @@ def provision_fake_ypserver(logger, samdb, domaindn, netbiosname, nisdomain,
         samdb.transaction_commit()
 
 
-def provision(logger, session_info, smbconf=None,
+def provision(logger, session_info, smbconf=None, kdcconfdir=None,
         targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None,
         domaindn=None, schemadn=None, configdn=None, serverdn=None,
         domain=None, hostname=None, hostip=None, hostip6=None, domainsid=None,
@@ -2009,11 +2013,13 @@ def provision(logger, session_info, smbconf=None,
             make_smbconf(smbconf, hostname, domain, realm,
                          targetdir, serverrole=serverrole,
                          eadb=useeadb, use_ntvfs=use_ntvfs,
-                         lp=lp, global_param=global_param)
+                         lp=lp, global_param=global_param,
+                         kdcconfdir=kdcconfdir)
     else:
         make_smbconf(smbconf, hostname, domain, realm, targetdir,
                      serverrole=serverrole,
-                     eadb=useeadb, use_ntvfs=use_ntvfs, lp=lp, global_param=global_param)
+                     eadb=useeadb, use_ntvfs=use_ntvfs, lp=lp, global_param=global_param,
+                     kdcconfdir=kdcconfdir)
 
     if lp is None:
         lp = samba.param.LoadParm()
diff --git a/python/samba/provision/kerberos.py b/python/samba/provision/kerberos.py
new file mode 100644 (file)
index 0000000..f874ff6
--- /dev/null
@@ -0,0 +1,101 @@
+# Unix SMB/CIFS implementation
+#
+# Backend code for provisioning a Samba AD server
+#
+# Copyright (c) 2015      Andreas Schneider <asn@samba.org>
+#
+# 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/>.
+#
+
+from samba.provision.kerberos_implementation import (
+    kdb_modules_dir,
+    kdc_default_config_dir)
+from samba import _glue
+import os
+
+def make_kdcconf(realm, domain, kdcconfdir, logdir):
+
+    if _glue.is_heimdal_built:
+        return
+
+    # Do nothing if kdc.conf has been set
+    if 'KRB5_KDC_PROFILE' in os.environ:
+        return
+
+    # We are in selftest
+    if 'SAMBA_SELFTEST' in os.environ and 'MITKRB5' in os.environ:
+        return
+
+    # If not specified use the default
+    if kdcconfdir is None:
+        kdcconfdir = kdc_default_config_dir
+
+    kdcconf = "%s/kdc.conf" % kdcconfdir
+
+    assert domain is not None
+    domain = domain.upper()
+
+    assert realm is not None
+    realm = realm.upper()
+
+    f = open(kdcconf, 'w')
+    try:
+        f.write("[kdcdefaults]\n")
+
+        f.write("\tkdc_ports = 88\n")
+        f.write("\tkdc_tcp_ports = 88\n")
+        f.write("\tkadmind_port = 464\n")
+        f.write("\n")
+
+        f.write("[realms]\n")
+
+        f.write("\t%s = {\n" % realm)
+        f.write("\t}\n")
+        f.write("\n")
+
+        f.write("\t%s = {\n" % realm.lower())
+        f.write("\t}\n")
+        f.write("\n")
+
+        f.write("\t%s = {\n" % domain)
+        f.write("\t}\n")
+        f.write("\n")
+
+        f.write("[dbmodules]\n")
+
+        f.write("\tdb_modules_dir = %s\n" % kdb_modules_dir)
+        f.write("\n")
+
+        f.write("\t%s = {\n" % realm)
+        f.write("\t\tdb_library = samba\n")
+        f.write("\t}\n")
+        f.write("\n")
+
+        f.write("\t%s = {\n" % realm.lower())
+        f.write("\t\tdb_library = samba\n")
+        f.write("\t}\n")
+        f.write("\n")
+
+        f.write("\t%s = {\n" % domain)
+        f.write("\t\tdb_library = samba\n")
+        f.write("\t}\n")
+        f.write("\n")
+
+        f.write("[logging]\n")
+
+        f.write("\tkdc = FILE:%s/mit_kdc.log\n" % logdir)
+        f.write("\tadmin_server = FILE:%s/mit_kadmin.log\n" % logdir)
+        f.write("\n")
+    finally:
+        f.close()