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
8 # Based on the original in EJS:
9 # Copyright (C) Andrew Tridgell 2005
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.
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.
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/>.
29 # Find right directory when running from source tree
30 sys.path.insert(0, "bin/python")
34 from samba.credentials import DONT_USE_KERBEROS
35 from samba.auth import system_session
36 import samba.getopt as options
37 from samba.provision import provision, FILL_FULL, FILL_NT4SYNC, FILL_DRS, find_setup_dir, ProvisioningError
38 from samba.dsdb import (
39 DS_DOMAIN_FUNCTION_2003,
40 DS_DOMAIN_FUNCTION_2008,
41 DS_DOMAIN_FUNCTION_2008_R2,
44 # how do we make this case insensitive??
46 parser = optparse.OptionParser("provision [options]")
47 sambaopts = options.SambaOptions(parser)
48 parser.add_option_group(sambaopts)
49 parser.add_option_group(options.VersionOptions(parser))
50 credopts = options.CredentialsOptions(parser)
51 parser.add_option_group(credopts)
52 parser.add_option("--interactive", help="Ask for names", action="store_true")
53 parser.add_option("--setupdir", type="string", metavar="DIR",
54 help="directory with setup files")
55 parser.add_option("--realm", type="string", metavar="REALM", help="set realm")
56 parser.add_option("--domain", type="string", metavar="DOMAIN",
58 parser.add_option("--domain-guid", type="string", metavar="GUID",
59 help="set domainguid (otherwise random)")
60 parser.add_option("--domain-sid", type="string", metavar="SID",
61 help="set domainsid (otherwise random)")
62 parser.add_option("--policy-guid", type="string", metavar="GUID",
63 help="set guid for domain policy")
64 parser.add_option("--policy-guid-dc", type="string", metavar="GUID",
65 help="set guid for domain controller policy")
66 parser.add_option("--ntds-guid", type="string", metavar="GUID",
67 help="set NTDS object GUID (otherwise random)")
68 parser.add_option("--invocationid", type="string", metavar="GUID",
69 help="set invocationid (otherwise random)")
70 parser.add_option("--host-name", type="string", metavar="HOSTNAME",
72 parser.add_option("--host-ip", type="string", metavar="IPADDRESS",
73 help="set IPv4 ipaddress")
74 parser.add_option("--host-ip6", type="string", metavar="IP6ADDRESS",
75 help="set IPv6 ipaddress")
76 parser.add_option("--adminpass", type="string", metavar="PASSWORD",
77 help="choose admin password (otherwise random)")
78 parser.add_option("--krbtgtpass", type="string", metavar="PASSWORD",
79 help="choose krbtgt password (otherwise random)")
80 parser.add_option("--machinepass", type="string", metavar="PASSWORD",
81 help="choose machine password (otherwise random)")
82 parser.add_option("--dnspass", type="string", metavar="PASSWORD",
83 help="choose dns password (otherwise random)")
84 parser.add_option("--ldapadminpass", type="string", metavar="PASSWORD",
85 help="choose password to set between Samba and it's LDAP backend (otherwise random)")
86 parser.add_option("--root", type="string", metavar="USERNAME",
87 help="choose 'root' unix username")
88 parser.add_option("--nobody", type="string", metavar="USERNAME",
89 help="choose 'nobody' user")
90 parser.add_option("--wheel", type="string", metavar="GROUPNAME",
91 help="choose 'wheel' privileged group")
92 parser.add_option("--users", type="string", metavar="GROUPNAME",
93 help="choose 'users' group")
94 parser.add_option("--quiet", help="Be quiet", action="store_true")
95 parser.add_option("--blank", action="store_true",
96 help="do not add users or groups, just the structure")
97 parser.add_option("--ldap-backend-extra-port", type="int", metavar="LDAP-BACKEND-EXTRA-PORT",
98 help="Additional TCP port for LDAP backend server (to use for replication)")
99 parser.add_option("--ldap-backend-type", type="choice", metavar="LDAP-BACKEND-TYPE",
100 help="LDAP backend type (fedora-ds or openldap)",
101 choices=["fedora-ds", "openldap"])
102 parser.add_option("--ldap-backend-nosync", help="Configure LDAP backend not to call fsync() (for performance in test environments)", action="store_true")
103 parser.add_option("--server-role", type="choice", metavar="ROLE",
104 choices=["domain controller", "dc", "member server", "member", "standalone"],
105 help="The server role (domain controller | dc | member server | member | standalone). Default is standalone.")
106 parser.add_option("--function-level", type="choice", metavar="FOR-FUN-LEVEL",
107 choices=["2003", "2008", "2008_R2"],
108 help="The domain and forest function level (2003 | 2008 | 2008_R2). Default is (Windows) 2003 (Native).")
109 parser.add_option("--partitions-only",
110 help="Configure Samba's partitions, but do not modify them (ie, join a BDC)", action="store_true")
111 parser.add_option("--targetdir", type="string", metavar="DIR",
112 help="Set target directory")
113 parser.add_option("--ol-mmr-urls", type="string", metavar="LDAPSERVER",
114 help="List of LDAP-URLS [ ldap://<FQHN>:<PORT>/ (where <PORT> has to be different than 389!) ] separated with comma (\",\") for use with OpenLDAP-MMR (Multi-Master-Replication), e.g.: \"ldap://s4dc1:9000,ldap://s4dc2:9000\"")
115 parser.add_option("--slapd-path", type="string", metavar="SLAPD-PATH",
116 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.")
117 parser.add_option("--setup-ds-path", type="string", metavar="SETUP_DS-PATH",
118 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.")
119 parser.add_option("--nosync", help="Configure LDAP backend not to call fsync() (for performance in test environments)", action="store_true")
120 parser.add_option("--use-xattrs", type="choice", choices=["yes","no","auto"], help="Define if we should use the native fs capabilities or a tdb file for storing attributes likes ntacl, auto tries to make an inteligent guess based on the user rights and system capabilities", default="auto")
121 parser.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")
123 opts = parser.parse_args()[0]
126 """print a message if quiet is not set."""
130 if len(sys.argv) == 1:
131 opts.interactive = True
134 from getpass import getpass
136 def ask(prompt, default=None):
137 if default is not None:
138 print "%s [%s]: " % (prompt,default),
140 print "%s: " % (prompt,),
141 return sys.stdin.readline().rstrip("\n") or default
143 default = socket.getfqdn().split(".", 1)[1].upper()
146 opts.realm = ask("Realm", default)
147 if opts.realm in (None, ""):
148 print >>sys.stderr, "No realm set!"
152 default = opts.realm.split(".")[0]
155 opts.domain = ask("Domain", default)
156 if opts.domain is None:
157 print >> sys.stderr, "No domain set!"
160 opts.server_role = ask("Server Role (dc, member, standalone)", "dc")
162 opts.adminpass = getpass("Administrator password: ")
163 if not opts.adminpass:
164 print >>sys.stderr, "Invalid administrator password."
168 if opts.realm is None or opts.domain is None:
169 if opts.realm is None:
170 print >>sys.stderr, "No realm set!"
171 if opts.domain is None:
172 print >> sys.stderr, "No domain set!"
176 if not opts.adminpass:
177 message("Administrator password will be set randomly!")
179 lp = sambaopts.get_loadparm()
180 smbconf = lp.configfile
182 if opts.server_role == "dc":
183 server_role = "domain controller"
184 elif opts.server_role == "member":
185 server_role = "member server"
187 server_role = opts.server_role
189 if opts.function_level is None:
190 dom_for_fun_level = None
191 elif opts.function_level == "2003":
192 dom_for_fun_level = DS_DOMAIN_FUNCTION_2003
193 elif opts.function_level == "2008":
194 dom_for_fun_level = DS_DOMAIN_FUNCTION_2008
195 elif opts.function_level == "2008_R2":
196 dom_for_fun_level = DS_DOMAIN_FUNCTION_2008_R2
198 creds = credopts.get_credentials(lp)
200 creds.set_kerberos_state(DONT_USE_KERBEROS)
202 setup_dir = opts.setupdir
203 if setup_dir is None:
204 setup_dir = find_setup_dir()
206 samdb_fill = FILL_FULL
208 samdb_fill = FILL_NT4SYNC
209 elif opts.partitions_only:
210 samdb_fill = FILL_DRS
213 if opts.use_xattrs == "yes":
215 elif opts.use_xattrs == "auto":
216 file = tempfile.NamedTemporaryFile()
218 samba.ntacls.setntacl(lp, file.name,
219 "O:S-1-5-32G:S-1-5-32", "S-1-5-32", "native")
222 if lp.get("posix:eadb") == None:
223 message("Notice: you are not root or your system do not support xattr, tdb backend for attributes has been selected")
224 message(" if you intend to use this provision in production you'd better rerun the script as root on a system supporting xattr")
228 session = system_session()
230 provision(setup_dir, message,
231 session, creds, smbconf=smbconf, targetdir=opts.targetdir,
232 samdb_fill=samdb_fill, realm=opts.realm, domain=opts.domain,
233 domainguid=opts.domain_guid, domainsid=opts.domain_sid,
234 policyguid=opts.policy_guid, policyguid_dc=opts.policy_guid_dc,
235 hostname=opts.host_name,
236 hostip=opts.host_ip, hostip6=opts.host_ip6,
237 ntdsguid=opts.ntds_guid,
238 invocationid=opts.invocationid, adminpass=opts.adminpass,
239 krbtgtpass=opts.krbtgtpass, machinepass=opts.machinepass,
240 dnspass=opts.dnspass, root=opts.root, nobody=opts.nobody,
241 wheel=opts.wheel, users=opts.users,
242 serverrole=server_role, dom_for_fun_level=dom_for_fun_level,
243 ldap_backend_extra_port=opts.ldap_backend_extra_port,
244 backend_type=opts.ldap_backend_type,
245 ldapadminpass=opts.ldapadminpass, ol_mmr_urls=opts.ol_mmr_urls,
246 slapd_path=opts.slapd_path, setup_ds_path=opts.setup_ds_path,
247 nosync=opts.nosync,ldap_dryrun_mode=opts.ldap_dryrun_mode,useeadb=eadb)
248 except ProvisioningError, e: