samba-tool: Unify usage messages.
[samba.git] / source4 / scripting / 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
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("--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         ]
61
62     takes_args = ["acl","file"]
63
64     def run(self, acl, file, use_ntvfs=False, use_s3fs=False,
65             quiet=False,xattr_backend=None,eadb_file=None,
66             credopts=None, sambaopts=None, versionopts=None):
67         logger = self.get_logger()
68         lp = sambaopts.get_loadparm()
69         try:
70             samdb = SamDB(session_info=system_session(),
71                           lp=lp)
72         except Exception, e:
73             raise CommandError("Unable to open samdb:", e)
74
75         if not use_ntvfs and not use_s3fs:
76             use_ntvfs = "smb" in lp.get("server services")
77         elif use_s3fs:
78             use_ntvfs = False
79
80         try:
81             domain_sid = security.dom_sid(samdb.domain_sid)
82         except:
83             raise CommandError("Unable to read domain SID from configuration files")
84
85         s3conf = s3param.get_context()
86         s3conf.load(lp.configfile)
87         # ensure we are using the right samba_dsdb passdb backend, no matter what
88         s3conf.set("passdb backend", "samba_dsdb:%s" % samdb.url)
89
90         setntacl(lp, file, acl, str(domain_sid), xattr_backend, eadb_file, use_ntvfs=use_ntvfs)
91
92         if use_ntvfs:
93             logger.warning("Please note that POSIX permissions have NOT been changed, only the stored NT ACL")
94
95
96 class cmd_ntacl_get(Command):
97     """Get ACLs of a file."""
98     synopsis = "%prog <file> [options]"
99
100     takes_optiongroups = {
101         "sambaopts": options.SambaOptions,
102         "credopts": options.CredentialsOptions,
103         "versionopts": options.VersionOptions,
104         }
105
106     takes_options = [
107         Option("--as-sddl", help="Output ACL in the SDDL format", action="store_true"),
108         Option("--xattr-backend", type="choice", help="xattr backend type (native fs or tdb)",
109                choices=["native","tdb"]),
110         Option("--eadb-file", help="Name of the tdb file where attributes are stored", type="string"),
111         Option("--use-ntvfs", help="Get the ACLs directly from the TDB or xattr used with the ntvfs file server", action="store_true"),
112         Option("--use-s3fs", help="Get the ACLs for use via the VFS layer used by the default s3fs file server", action="store_true")
113         ]
114
115     takes_args = ["file"]
116
117     def run(self, file, use_ntvfs=False, use_s3fs=False,
118             as_sddl=False, xattr_backend=None, eadb_file=None,
119             credopts=None, sambaopts=None, versionopts=None):
120         lp = sambaopts.get_loadparm()
121         try:
122             samdb = SamDB(session_info=system_session(),
123                           lp=lp)
124         except Exception, e:
125             raise CommandError("Unable to open samdb:", e)
126
127         if not use_ntvfs and not use_s3fs:
128             use_ntvfs = "smb" in lp.get("server services")
129         elif use_s3fs:
130             use_ntvfs = False
131
132
133         s3conf = s3param.get_context()
134         s3conf.load(lp.configfile)
135         # ensure we are using the right samba_dsdb passdb backend, no matter what
136         s3conf.set("passdb backend", "samba_dsdb:%s" % samdb.url)
137
138         acl = getntacl(lp, file, xattr_backend, eadb_file, direct_db_access=use_ntvfs)
139         if as_sddl:
140             try:
141                 domain_sid = security.dom_sid(samdb.domain_sid)
142             except:
143                 raise CommandError("Unable to read domain SID from configuration files")
144             self.outf.write(acl.as_sddl(domain_sid)+"\n")
145         else:
146             self.outf.write(ndr_print(acl))
147
148
149 class cmd_ntacl_sysvolreset(Command):
150     """Reset sysvol ACLs to defaults (including correct ACLs on GPOs)."""
151     synopsis = "%prog <file> [options]"
152
153     takes_optiongroups = {
154         "sambaopts": options.SambaOptions,
155         "credopts": options.CredentialsOptions,
156         "versionopts": options.VersionOptions,
157         }
158
159     takes_options = [
160         Option("--use-ntvfs", help="Set the ACLs for use with the ntvfs file server", action="store_true"),
161         Option("--use-s3fs", help="Set the ACLs for use with the default s3fs file server", action="store_true")
162         ]
163
164     def run(self, use_ntvfs=False, use_s3fs=False,
165             credopts=None, sambaopts=None, versionopts=None):
166         lp = sambaopts.get_loadparm()
167         path = lp.private_path("secrets.ldb")
168         creds = credopts.get_credentials(lp)
169         creds.set_kerberos_state(DONT_USE_KERBEROS)
170         logger = self.get_logger()
171
172         netlogon = lp.get("path", "netlogon")
173         sysvol = lp.get("path", "sysvol")
174         try:
175             samdb = SamDB(session_info=system_session(),
176                           lp=lp)
177         except Exception, e:
178             raise CommandError("Unable to open samdb:", e)
179
180         if not use_ntvfs and not use_s3fs:
181             use_ntvfs = "smb" in lp.get("server services")
182         elif use_s3fs:
183             use_ntvfs = False
184
185         domain_sid = security.dom_sid(samdb.domain_sid)
186
187         s3conf = s3param.get_context()
188         s3conf.load(lp.configfile)
189         # ensure we are using the right samba_dsdb passdb backend, no matter what
190         s3conf.set("passdb backend", "samba_dsdb:%s" % samdb.url)
191
192         LA_sid = security.dom_sid(str(domain_sid)
193                                   +"-"+str(security.DOMAIN_RID_ADMINISTRATOR))
194         BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS)
195
196         s4_passdb = passdb.PDB(s3conf.get("passdb backend"))
197
198         # These assertions correct for current plugin_s4_dc selftest
199         # configuration.  When other environments have a broad range of
200         # groups mapped via passdb, we can relax some of these checks
201         (LA_uid,LA_type) = s4_passdb.sid_to_id(LA_sid)
202         if (LA_type != idmap.ID_TYPE_UID and LA_type != idmap.ID_TYPE_BOTH):
203             raise CommandError("SID %s is not mapped to a UID" % LA_sid)
204         (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid)
205         if (BA_type != idmap.ID_TYPE_GID and BA_type != idmap.ID_TYPE_BOTH):
206             raise CommandError("SID %s is not mapped to a GID" % BA_sid)
207
208         if use_ntvfs:
209             logger.warning("Please note that POSIX permissions have NOT been changed, only the stored NT ACL")
210
211         provision.setsysvolacl(samdb, netlogon, sysvol,
212                                LA_uid, BA_gid, domain_sid,
213                                lp.get("realm").lower(), samdb.domain_dn(),
214                                lp, use_ntvfs=use_ntvfs)
215
216 class cmd_ntacl_sysvolcheck(Command):
217     """Check sysvol ACLs match defaults (including correct ACLs on GPOs)."""
218     synopsis = "%prog <file> [options]"
219
220     takes_optiongroups = {
221         "sambaopts": options.SambaOptions,
222         "credopts": options.CredentialsOptions,
223         "versionopts": options.VersionOptions,
224         }
225
226     def run(self, credopts=None, sambaopts=None, versionopts=None):
227         lp = sambaopts.get_loadparm()
228         path = lp.private_path("secrets.ldb")
229         creds = credopts.get_credentials(lp)
230         creds.set_kerberos_state(DONT_USE_KERBEROS)
231         logger = self.get_logger()
232
233         netlogon = lp.get("path", "netlogon")
234         sysvol = lp.get("path", "sysvol")
235         try:
236             samdb = SamDB(session_info=system_session(), lp=lp)
237         except Exception, e:
238             raise CommandError("Unable to open samdb:", e)
239
240         domain_sid = security.dom_sid(samdb.domain_sid)
241
242         provision.checksysvolacl(samdb, netlogon, sysvol,
243                                  domain_sid,
244                                  lp.get("realm").lower(), samdb.domain_dn(),
245                                  lp)
246
247
248 class cmd_ntacl(SuperCommand):
249     """NT ACLs manipulation"""
250
251     subcommands = {}
252     subcommands["set"] = cmd_ntacl_set()
253     subcommands["get"] = cmd_ntacl_get()
254     subcommands["sysvolreset"] = cmd_ntacl_sysvolreset()
255     subcommands["sysvolcheck"] = cmd_ntacl_sysvolcheck()
256