1 # domain management - domain join
3 # Copyright Matthias Dieter Wallnoefer 2009
4 # Copyright Andrew Kroeger 2009
5 # Copyright Jelmer Vernooij 2007-2012
6 # Copyright Giampaolo Lauria 2011
7 # Copyright Matthieu Patou <mat@matws.net> 2011
8 # Copyright Andrew Bartlett 2008-2015
9 # Copyright Stefan Metzmacher 2012
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 import samba
.getopt
as options
30 from samba
import is_ad_dc_built
31 from samba
.dcerpc
import nbt
32 from samba
.join
import join_DC
, join_RODC
33 from samba
.net
import LIBNET_JOIN_AUTOMATIC
, Net
34 from samba
.net_s3
import Net
as s3_Net
35 from samba
.netcmd
import Command
, CommandError
, Option
36 from samba
.param
import default_path
37 from samba
.samba3
import param
as s3param
39 from .common
import common_join_options
, common_provision_join_options
42 class cmd_domain_join(Command
):
43 """Join domain as either member or backup domain controller."""
45 synopsis
= "%prog <dnsdomain> [DC|RODC|MEMBER] [options]"
47 takes_optiongroups
= {
48 "sambaopts": options
.SambaOptions
,
49 "versionopts": options
.VersionOptions
,
50 "credopts": options
.CredentialsOptions
,
55 "--use-ntvfs", help="Use NTVFS for the fileserver (default = no)",
60 Option("--experimental-s4-member", action
="store_true",
61 help="Perform member joins using the s4 Net join_member. "
62 "Don't choose this unless you know what you're doing")
66 Option("--no-dns-updates", action
="store_true",
67 help="Disable DNS updates")
69 takes_options
.extend(common_join_options
)
70 takes_options
.extend(common_provision_join_options
)
72 if samba
.is_ntvfs_fileserver_built():
73 takes_options
.extend(ntvfs_options
)
75 if samba
.is_selftest_enabled():
76 takes_options
.extend(selftest_options
)
78 takes_args
= ["domain", "role?"]
80 def run(self
, domain
, role
=None, sambaopts
=None, credopts
=None,
81 versionopts
=None, server
=None, site
=None, targetdir
=None,
82 domain_critical_only
=False, machinepass
=None,
83 use_ntvfs
=False, experimental_s4_member
=False, dns_backend
=None,
84 quiet
=False, verbose
=False, no_dns_updates
=False,
85 plaintext_secrets
=False,
86 backend_store
=None, backend_store_size
=None):
87 lp
= sambaopts
.get_loadparm()
88 creds
= credopts
.get_credentials(lp
)
89 net
= Net(creds
, lp
, server
=credopts
.ipaddress
)
91 logger
= self
.get_logger(verbose
=verbose
, quiet
=quiet
)
93 netbios_name
= lp
.get("netbios name")
98 if role
is None or role
== "MEMBER":
99 if experimental_s4_member
:
100 (join_password
, sid
, domain_name
) = net
.join_member(
101 domain
, netbios_name
, LIBNET_JOIN_AUTOMATIC
,
102 machinepass
=machinepass
)
104 lp
.set('realm', domain
)
105 if lp
.get('workgroup') == 'WORKGROUP':
106 lp
.set('workgroup', net
.finddc(domain
=domain
,
107 flags
=(nbt
.NBT_SERVER_LDAP |
108 nbt
.NBT_SERVER_DS
)).domain_name
)
109 lp
.set('server role', 'member server')
110 smb_conf
= lp
.configfile
if lp
.configfile
else default_path()
111 with tempfile
.NamedTemporaryFile(delete
=False,
112 dir=os
.path
.dirname(smb_conf
)) as f
:
113 lp
.dump(False, f
.name
)
114 if os
.path
.exists(smb_conf
):
115 mode
= os
.stat(smb_conf
).st_mode
116 os
.chmod(f
.name
, mode
)
117 os
.rename(f
.name
, smb_conf
)
118 s3_lp
= s3param
.get_context()
120 s3_net
= s3_Net(creds
, s3_lp
, server
=server
)
121 (sid
, domain_name
) = s3_net
.join_member(netbios_name
,
122 machinepass
=machinepass
,
124 noDnsUpdates
=no_dns_updates
)
126 self
.errf
.write("Joined domain %s (%s)\n" % (domain_name
, sid
))
127 elif role
== "DC" and is_ad_dc_built():
128 join_DC(logger
=logger
, server
=server
, creds
=creds
, lp
=lp
, domain
=domain
,
129 site
=site
, netbios_name
=netbios_name
, targetdir
=targetdir
,
130 domain_critical_only
=domain_critical_only
,
131 machinepass
=machinepass
, use_ntvfs
=use_ntvfs
,
132 dns_backend
=dns_backend
,
133 plaintext_secrets
=plaintext_secrets
,
134 backend_store
=backend_store
,
135 backend_store_size
=backend_store_size
)
136 elif role
== "RODC" and is_ad_dc_built():
137 join_RODC(logger
=logger
, server
=server
, creds
=creds
, lp
=lp
, domain
=domain
,
138 site
=site
, netbios_name
=netbios_name
, targetdir
=targetdir
,
139 domain_critical_only
=domain_critical_only
,
140 machinepass
=machinepass
, use_ntvfs
=use_ntvfs
,
141 dns_backend
=dns_backend
,
142 plaintext_secrets
=plaintext_secrets
,
143 backend_store
=backend_store
,
144 backend_store_size
=backend_store_size
)
146 raise CommandError("Invalid role '%s' (possible values: MEMBER, DC, RODC)" % role
)