PEP8: fix E302: expected 2 blank lines, found 1
[bbaumbach/samba-autobuild/.git] / python / samba / netcmd / ntacl.py
1 # Manipulate file NT ACLs
2 #
3 # Copyright Matthieu Patou 2010 <mat@matws.net>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 #
18
19 from samba.credentials import DONT_USE_KERBEROS
20 import samba.getopt as options
21 from samba.dcerpc import security, idmap
22 from samba.ntacls import setntacl, getntacl, getdosinfo
23 from samba import Ldb
24 from samba.ndr import ndr_unpack, ndr_print
25 from samba.samdb import SamDB
26 from samba.samba3 import param as s3param, passdb, smbd
27 from samba import provision
28
29 from ldb import SCOPE_BASE
30 import os
31
32 from samba.auth import system_session
33 from samba.netcmd import (
34     Command,
35     CommandError,
36     SuperCommand,
37     Option,
38 )
39
40
41
42 class cmd_ntacl_set(Command):
43     """Set ACLs on a file."""
44
45     synopsis = "%prog <acl> <file> [options]"
46
47     takes_optiongroups = {
48         "sambaopts": options.SambaOptions,
49         "credopts": options.CredentialsOptions,
50         "versionopts": options.VersionOptions,
51     }
52
53     takes_options = [
54         Option("-q", "--quiet", help="Be quiet", action="store_true"),
55         Option("--xattr-backend", type="choice", help="xattr backend type (native fs or tdb)",
56                choices=["native", "tdb"]),
57         Option("--eadb-file", help="Name of the tdb file where attributes are stored", type="string"),
58         Option("--use-ntvfs", help="Set the ACLs directly to the TDB or xattr for use with the ntvfs file server", action="store_true"),
59         Option("--use-s3fs", help="Set the ACLs for use with the default s3fs file server via the VFS layer", action="store_true"),
60         Option("--service", help="Name of the smb.conf service to use when applying the ACLs", type="string")
61     ]
62
63     takes_args = ["acl", "file"]
64
65     def run(self, acl, file, use_ntvfs=False, use_s3fs=False,
66             quiet=False, xattr_backend=None, eadb_file=None,
67             credopts=None, sambaopts=None, versionopts=None,
68             service=None):
69         logger = self.get_logger()
70         lp = sambaopts.get_loadparm()
71         try:
72             samdb = SamDB(session_info=system_session(),
73                           lp=lp)
74         except Exception as e:
75             raise CommandError("Unable to open samdb:", e)
76
77         if not use_ntvfs and not use_s3fs:
78             use_ntvfs = "smb" in lp.get("server services")
79         elif use_s3fs:
80             use_ntvfs = False
81
82         try:
83             domain_sid = security.dom_sid(samdb.domain_sid)
84         except:
85             raise CommandError("Unable to read domain SID from configuration files")
86
87         s3conf = s3param.get_context()
88         s3conf.load(lp.configfile)
89         # ensure we are using the right samba_dsdb passdb backend, no matter what
90         s3conf.set("passdb backend", "samba_dsdb:%s" % samdb.url)
91
92         setntacl(lp, file, acl, str(domain_sid), xattr_backend, eadb_file, use_ntvfs=use_ntvfs, service=service)
93
94         if use_ntvfs:
95             logger.warning("Please note that POSIX permissions have NOT been changed, only the stored NT ACL")
96
97
98 class cmd_dosinfo_get(Command):
99     """Get DOS info of a file from xattr."""
100     synopsis = "%prog <file> [options]"
101
102     takes_optiongroups = {
103         "sambaopts": options.SambaOptions,
104         "credopts": options.CredentialsOptions,
105         "versionopts": options.VersionOptions,
106     }
107
108     takes_args = ["file"]
109
110     def run(self, file, credopts=None, sambaopts=None, versionopts=None):
111         lp = sambaopts.get_loadparm()
112         s3conf = s3param.get_context()
113         s3conf.load(lp.configfile)
114
115         dosinfo = getdosinfo(lp, file)
116         if dosinfo:
117             self.outf.write(ndr_print(dosinfo))
118
119
120 class cmd_ntacl_get(Command):
121     """Get ACLs of a file."""
122     synopsis = "%prog <file> [options]"
123
124     takes_optiongroups = {
125         "sambaopts": options.SambaOptions,
126         "credopts": options.CredentialsOptions,
127         "versionopts": options.VersionOptions,
128     }
129
130     takes_options = [
131         Option("--as-sddl", help="Output ACL in the SDDL format", action="store_true"),
132         Option("--xattr-backend", type="choice", help="xattr backend type (native fs or tdb)",
133                choices=["native", "tdb"]),
134         Option("--eadb-file", help="Name of the tdb file where attributes are stored", type="string"),
135         Option("--use-ntvfs", help="Get the ACLs directly from the TDB or xattr used with the ntvfs file server", action="store_true"),
136         Option("--use-s3fs", help="Get the ACLs for use via the VFS layer used by the default s3fs file server", action="store_true"),
137         Option("--service", help="Name of the smb.conf service to use when getting the ACLs", type="string")
138     ]
139
140     takes_args = ["file"]
141
142     def run(self, file, use_ntvfs=False, use_s3fs=False,
143             as_sddl=False, xattr_backend=None, eadb_file=None,
144             credopts=None, sambaopts=None, versionopts=None,
145             service=None):
146         lp = sambaopts.get_loadparm()
147         try:
148             samdb = SamDB(session_info=system_session(),
149                           lp=lp)
150         except Exception as e:
151             raise CommandError("Unable to open samdb:", e)
152
153         if not use_ntvfs and not use_s3fs:
154             use_ntvfs = "smb" in lp.get("server services")
155         elif use_s3fs:
156             use_ntvfs = False
157
158
159         s3conf = s3param.get_context()
160         s3conf.load(lp.configfile)
161         # ensure we are using the right samba_dsdb passdb backend, no matter what
162         s3conf.set("passdb backend", "samba_dsdb:%s" % samdb.url)
163
164         acl = getntacl(lp, file, xattr_backend, eadb_file, direct_db_access=use_ntvfs, service=service)
165         if as_sddl:
166             try:
167                 domain_sid = security.dom_sid(samdb.domain_sid)
168             except:
169                 raise CommandError("Unable to read domain SID from configuration files")
170             self.outf.write(acl.as_sddl(domain_sid) + "\n")
171         else:
172             self.outf.write(ndr_print(acl))
173
174
175 class cmd_ntacl_sysvolreset(Command):
176     """Reset sysvol ACLs to defaults (including correct ACLs on GPOs)."""
177     synopsis = "%prog <file> [options]"
178
179     takes_optiongroups = {
180         "sambaopts": options.SambaOptions,
181         "credopts": options.CredentialsOptions,
182         "versionopts": options.VersionOptions,
183     }
184
185     takes_options = [
186         Option("--use-ntvfs", help="Set the ACLs for use with the ntvfs file server", action="store_true"),
187         Option("--use-s3fs", help="Set the ACLs for use with the default s3fs file server", action="store_true")
188     ]
189
190     def run(self, use_ntvfs=False, use_s3fs=False,
191             credopts=None, sambaopts=None, versionopts=None):
192         lp = sambaopts.get_loadparm()
193         path = lp.private_path("secrets.ldb")
194         creds = credopts.get_credentials(lp)
195         creds.set_kerberos_state(DONT_USE_KERBEROS)
196         logger = self.get_logger()
197
198         netlogon = lp.get("path", "netlogon")
199         sysvol = lp.get("path", "sysvol")
200         try:
201             samdb = SamDB(session_info=system_session(),
202                           lp=lp)
203         except Exception as e:
204             raise CommandError("Unable to open samdb:", e)
205
206         if not use_ntvfs and not use_s3fs:
207             use_ntvfs = "smb" in lp.get("server services")
208         elif use_s3fs:
209             use_ntvfs = False
210
211         domain_sid = security.dom_sid(samdb.domain_sid)
212
213         s3conf = s3param.get_context()
214         s3conf.load(lp.configfile)
215         # ensure we are using the right samba_dsdb passdb backend, no matter what
216         s3conf.set("passdb backend", "samba_dsdb:%s" % samdb.url)
217
218         LA_sid = security.dom_sid(str(domain_sid)
219                                   + "-" +str(security.DOMAIN_RID_ADMINISTRATOR))
220         BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS)
221
222         s4_passdb = passdb.PDB(s3conf.get("passdb backend"))
223
224         # These assertions correct for current ad_dc selftest
225         # configuration.  When other environments have a broad range of
226         # groups mapped via passdb, we can relax some of these checks
227         (LA_uid, LA_type) = s4_passdb.sid_to_id(LA_sid)
228         if (LA_type != idmap.ID_TYPE_UID and LA_type != idmap.ID_TYPE_BOTH):
229             raise CommandError("SID %s is not mapped to a UID" % LA_sid)
230         (BA_gid, BA_type) = s4_passdb.sid_to_id(BA_sid)
231         if (BA_type != idmap.ID_TYPE_GID and BA_type != idmap.ID_TYPE_BOTH):
232             raise CommandError("SID %s is not mapped to a GID" % BA_sid)
233
234         if use_ntvfs:
235             logger.warning("Please note that POSIX permissions have NOT been changed, only the stored NT ACL")
236
237         provision.setsysvolacl(samdb, netlogon, sysvol,
238                                LA_uid, BA_gid, domain_sid,
239                                lp.get("realm").lower(), samdb.domain_dn(),
240                                lp, use_ntvfs=use_ntvfs)
241
242
243 class cmd_ntacl_sysvolcheck(Command):
244     """Check sysvol ACLs match defaults (including correct ACLs on GPOs)."""
245     synopsis = "%prog <file> [options]"
246
247     takes_optiongroups = {
248         "sambaopts": options.SambaOptions,
249         "credopts": options.CredentialsOptions,
250         "versionopts": options.VersionOptions,
251     }
252
253     def run(self, credopts=None, sambaopts=None, versionopts=None):
254         lp = sambaopts.get_loadparm()
255         path = lp.private_path("secrets.ldb")
256         creds = credopts.get_credentials(lp)
257         creds.set_kerberos_state(DONT_USE_KERBEROS)
258         logger = self.get_logger()
259
260         netlogon = lp.get("path", "netlogon")
261         sysvol = lp.get("path", "sysvol")
262         try:
263             samdb = SamDB(session_info=system_session(), lp=lp)
264         except Exception as e:
265             raise CommandError("Unable to open samdb:", e)
266
267         domain_sid = security.dom_sid(samdb.domain_sid)
268
269         provision.checksysvolacl(samdb, netlogon, sysvol,
270                                  domain_sid,
271                                  lp.get("realm").lower(), samdb.domain_dn(),
272                                  lp)
273
274
275 class cmd_ntacl(SuperCommand):
276     """NT ACLs manipulation."""
277
278     subcommands = {}
279     subcommands["set"] = cmd_ntacl_set()
280     subcommands["get"] = cmd_ntacl_get()
281     subcommands["sysvolreset"] = cmd_ntacl_sysvolreset()
282     subcommands["sysvolcheck"] = cmd_ntacl_sysvolcheck()
283     subcommands["getdosinfo"] = cmd_dosinfo_get()
284