1#!/usr/bin/python 2# 3# Unix SMB/CIFS implementation. 4# provision a Samba4 server 5# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008 6# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008 7# 8# Based on the original in EJS: 9# Copyright (C) Andrew Tridgell 2005 10# 11# This program is free software; you can redistribute it and/or modify 12# it under the terms of the GNU General Public License as published by 13# the Free Software Foundation; either version 3 of the License, or 14# (at your option) any later version. 15# 16# This program is distributed in the hope that it will be useful, 17# but WITHOUT ANY WARRANTY; without even the implied warranty of 18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19# GNU General Public License for more details. 20# 21# You should have received a copy of the GNU General Public License 22# along with this program. If not, see <http://www.gnu.org/licenses/>. 23# 24 25import optparse 26import sys 27 28# Find right directory when running from source tree 29sys.path.insert(0, "bin/python") 30 31import samba 32from samba.credentials import DONT_USE_KERBEROS 33from samba.auth import system_session 34import samba.getopt as options 35from samba.provision import provision, FILL_FULL, FILL_NT4SYNC, FILL_DRS, find_setup_dir 36 37# how do we make this case insensitive?? 38 39parser = optparse.OptionParser("provision [options]") 40sambaopts = options.SambaOptions(parser) 41parser.add_option_group(sambaopts) 42parser.add_option_group(options.VersionOptions(parser)) 43credopts = options.CredentialsOptions(parser) 44parser.add_option_group(credopts) 45parser.add_option("--interactive", help="Ask for names", action="store_true") 46parser.add_option("--setupdir", type="string", metavar="DIR", 47 help="directory with setup files") 48parser.add_option("--realm", type="string", metavar="REALM", help="set realm") 49parser.add_option("--domain", type="string", metavar="DOMAIN", 50 help="set domain") 51parser.add_option("--domain-guid", type="string", metavar="GUID", 52 help="set domainguid (otherwise random)") 53parser.add_option("--domain-sid", type="string", metavar="SID", 54 help="set domainsid (otherwise random)") 55parser.add_option("--policy-guid", type="string", metavar="GUID", 56 help="set guid for domain policy") 57parser.add_option("--policy-guid-dc", type="string", metavar="GUID", 58 help="set guid for domain controller policy") 59parser.add_option("--invocationid", type="string", metavar="GUID", 60 help="set invocationid (otherwise random)") 61parser.add_option("--host-name", type="string", metavar="HOSTNAME", 62 help="set hostname") 63parser.add_option("--host-ip", type="string", metavar="IPADDRESS", 64 help="set IPv4 ipaddress") 65parser.add_option("--host-ip6", type="string", metavar="IP6ADDRESS", 66 help="set IPv6 ipaddress") 67parser.add_option("--adminpass", type="string", metavar="PASSWORD", 68 help="choose admin password (otherwise random)") 69parser.add_option("--krbtgtpass", type="string", metavar="PASSWORD", 70 help="choose krbtgt password (otherwise random)") 71parser.add_option("--machinepass", type="string", metavar="PASSWORD", 72 help="choose machine password (otherwise random)") 73parser.add_option("--dnspass", type="string", metavar="PASSWORD", 74 help="choose dns password (otherwise random)") 75parser.add_option("--ldapadminpass", type="string", metavar="PASSWORD", 76 help="choose password to set between Samba and it's LDAP backend (otherwise random)") 77parser.add_option("--root", type="string", metavar="USERNAME", 78 help="choose 'root' unix username") 79parser.add_option("--nobody", type="string", metavar="USERNAME", 80 help="choose 'nobody' user") 81parser.add_option("--wheel", type="string", metavar="GROUPNAME", 82 help="choose 'wheel' privileged group") 83parser.add_option("--users", type="string", metavar="GROUPNAME", 84 help="choose 'users' group") 85parser.add_option("--quiet", help="Be quiet", action="store_true") 86parser.add_option("--blank", action="store_true", 87 help="do not add users or groups, just the structure") 88parser.add_option("--ldap-backend-extra-port", type="int", metavar="LDAP-BACKEND-EXTRA-PORT", 89 help="Additional TCP port for LDAP backend server (to use for replication)") 90parser.add_option("--ldap-backend-type", type="choice", metavar="LDAP-BACKEND-TYPE", 91 help="LDAP backend type (fedora-ds or openldap)", 92 choices=["fedora-ds", "openldap"]) 93parser.add_option("--ldap-backend-nosync", help="Configure LDAP backend not to call fsync() (for performance in test environments)", action="store_true") 94parser.add_option("--server-role", type="choice", metavar="ROLE", 95 choices=["domain controller", "dc", "member server", "member", "standalone"], 96 help="Set server role to provision for (default standalone)") 97parser.add_option("--partitions-only", 98 help="Configure Samba's partitions, but do not modify them (ie, join a BDC)", action="store_true") 99parser.add_option("--targetdir", type="string", metavar="DIR", 100 help="Set target directory") 101parser.add_option("--ol-mmr-urls", type="string", metavar="LDAPSERVER", 102 help="List of LDAP-URLS [ ldap://<FQHN>:<PORT>/ (where <PORT> has to be different than 389!) ] separated with whitespaces for use with OpenLDAP-MMR (Multi-Master-Replication)") 103parser.add_option("--slapd-path", type="string", metavar="SLAPD-PATH", 104 help="Path to slapd for LDAP backend [e.g.:'/usr/local/libexec/slapd']. Required for Setup with LDAP-Backend. OpenLDAP Version >= 2.4.17 should be used.") 105parser.add_option("--setup-ds-path", type="string", metavar="SETUP_DS-PATH", 106 help="Path to setup-ds.pl script for Fedora DS LDAP backend [e.g.:'/usr/sbin/setup-ds.pl']. Required for Setup with Fedora DS backend.") 107parser.add_option("--nosync", help="Configure LDAP backend not to call fsync() (for performance in test environments)", action="store_true") 108parser.add_option("--ldap-dryrun-mode", help="Configure LDAP backend, but do not run any binaries and exit early. Used only for the test environment. DO NOT USE", action="store_true") 109 110opts = parser.parse_args()[0] 111 112def message(text): 113 """print a message if quiet is not set.""" 114 if not opts.quiet: 115 print text 116 117if len(sys.argv) == 1: 118 opts.interactive = True 119 120if not opts.interactive and (opts.realm is None or opts.domain is None): 121 if opts.realm is None: 122 print >>sys.stderr, "No realm set" 123 if opts.domain is None: 124 print >>sys.stderr, "No domain set" 125 parser.print_usage() 126 sys.exit(1) 127 128if opts.interactive: 129 from getpass import getpass 130 import socket 131 def ask(prompt, default=None): 132 if default is not None: 133 print "%s [%s]: " % (prompt,default), 134 else: 135 print "%s: " % (prompt,), 136 return sys.stdin.readline().rstrip("\n") or default 137 try: 138 opts.realm = ask("Realm", socket.getfqdn().split(".", 1)[1].upper()) 139 except IndexError: 140 print >>sys.stderr, "Cannot guess realm from %s" % ( socket.getfqdn()) 141 sys.exit(1) 142 143 try: 144 opts.domain = ask("Domain", opts.realm.split(".")[0]) 145 except IndexError: 146 print >>sys.stderr, "Cannot guess domain from %s" % ( opts.realm()) 147 sys.exit(1) 148 149 opts.server_role = ask("Server Role (dc, member, standalone)", "dc") 150 for i in range(3): 151 opts.adminpass = getpass("Administrator password: ") 152 if not opts.adminpass: 153 print >>sys.stderr, "Invalid administrator password." 154 else: 155 break 156 157lp = sambaopts.get_loadparm() 158smbconf = lp.configfile 159 160if opts.server_role == "dc": 161 server_role = "domain controller" 162elif opts.server_role == "member": 163 server_role = "member server" 164else: 165 server_role = opts.server_role 166 167creds = credopts.get_credentials(lp) 168 169creds.set_kerberos_state(DONT_USE_KERBEROS) 170 171setup_dir = opts.setupdir 172if setup_dir is None: 173 setup_dir = find_setup_dir() 174 175samdb_fill = FILL_FULL 176if opts.blank: 177 samdb_fill = FILL_NT4SYNC 178elif opts.partitions_only: 179 samdb_fill = FILL_DRS 180 181session = system_session() 182provision(setup_dir, message, 183 session, creds, smbconf=smbconf, targetdir=opts.targetdir, 184 samdb_fill=samdb_fill, realm=opts.realm, domain=opts.domain, 185 domainguid=opts.domain_guid, domainsid=opts.domain_sid, 186 policyguid=opts.policy_guid, policyguid_dc=opts.policy_guid_dc, 187 hostname=opts.host_name, 188 hostip=opts.host_ip, hostip6=opts.host_ip6, 189 invocationid=opts.invocationid, adminpass=opts.adminpass, 190 krbtgtpass=opts.krbtgtpass, machinepass=opts.machinepass, 191 dnspass=opts.dnspass, root=opts.root, nobody=opts.nobody, 192 wheel=opts.wheel, users=opts.users, 193 serverrole=server_role, 194 ldap_backend_extra_port=opts.ldap_backend_extra_port, 195 ldap_backend_type=opts.ldap_backend_type, 196 ldapadminpass=opts.ldapadminpass, 197 ol_mmr_urls=opts.ol_mmr_urls, 198 slapd_path=opts.slapd_path, 199 setup_ds_path=opts.setup_ds_path, 200 nosync=opts.nosync, 201 ldap_dryrun_mode=opts.ldap_dryrun_mode) 202