1 # Manipulate file NT ACLs
3 # Copyright Matthieu Patou 2010 <mat@matws.net>
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.
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.
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/>.
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
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
29 from ldb import SCOPE_BASE
32 from samba.auth import system_session
33 from samba.netcmd import (
42 class cmd_ntacl_set(Command):
43 """Set ACLs on a file."""
45 synopsis = "%prog <acl> <file> [options]"
47 takes_optiongroups = {
48 "sambaopts": options.SambaOptions,
49 "credopts": options.CredentialsOptions,
50 "versionopts": options.VersionOptions,
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")
63 takes_args = ["acl", "file"]
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,
69 logger = self.get_logger()
70 lp = sambaopts.get_loadparm()
72 samdb = SamDB(session_info=system_session(),
74 except Exception as e:
75 raise CommandError("Unable to open samdb:", e)
77 if not use_ntvfs and not use_s3fs:
78 use_ntvfs = "smb" in lp.get("server services")
83 domain_sid = security.dom_sid(samdb.domain_sid)
85 raise CommandError("Unable to read domain SID from configuration files")
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)
92 setntacl(lp, file, acl, str(domain_sid), xattr_backend, eadb_file, use_ntvfs=use_ntvfs, service=service)
95 logger.warning("Please note that POSIX permissions have NOT been changed, only the stored NT ACL")
98 class cmd_dosinfo_get(Command):
99 """Get DOS info of a file from xattr."""
100 synopsis = "%prog <file> [options]"
102 takes_optiongroups = {
103 "sambaopts": options.SambaOptions,
104 "credopts": options.CredentialsOptions,
105 "versionopts": options.VersionOptions,
108 takes_args = ["file"]
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)
115 dosinfo = getdosinfo(lp, file)
117 self.outf.write(ndr_print(dosinfo))
120 class cmd_ntacl_get(Command):
121 """Get ACLs of a file."""
122 synopsis = "%prog <file> [options]"
124 takes_optiongroups = {
125 "sambaopts": options.SambaOptions,
126 "credopts": options.CredentialsOptions,
127 "versionopts": options.VersionOptions,
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")
140 takes_args = ["file"]
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,
146 lp = sambaopts.get_loadparm()
148 samdb = SamDB(session_info=system_session(),
150 except Exception as e:
151 raise CommandError("Unable to open samdb:", e)
153 if not use_ntvfs and not use_s3fs:
154 use_ntvfs = "smb" in lp.get("server services")
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)
164 acl = getntacl(lp, file, xattr_backend, eadb_file, direct_db_access=use_ntvfs, service=service)
167 domain_sid = security.dom_sid(samdb.domain_sid)
169 raise CommandError("Unable to read domain SID from configuration files")
170 self.outf.write(acl.as_sddl(domain_sid) + "\n")
172 self.outf.write(ndr_print(acl))
175 class cmd_ntacl_sysvolreset(Command):
176 """Reset sysvol ACLs to defaults (including correct ACLs on GPOs)."""
177 synopsis = "%prog <file> [options]"
179 takes_optiongroups = {
180 "sambaopts": options.SambaOptions,
181 "credopts": options.CredentialsOptions,
182 "versionopts": options.VersionOptions,
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")
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()
198 netlogon = lp.get("path", "netlogon")
199 sysvol = lp.get("path", "sysvol")
201 samdb = SamDB(session_info=system_session(),
203 except Exception as e:
204 raise CommandError("Unable to open samdb:", e)
206 if not use_ntvfs and not use_s3fs:
207 use_ntvfs = "smb" in lp.get("server services")
211 domain_sid = security.dom_sid(samdb.domain_sid)
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)
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)
222 s4_passdb = passdb.PDB(s3conf.get("passdb backend"))
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)
235 logger.warning("Please note that POSIX permissions have NOT been changed, only the stored NT ACL")
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)
243 class cmd_ntacl_sysvolcheck(Command):
244 """Check sysvol ACLs match defaults (including correct ACLs on GPOs)."""
245 synopsis = "%prog <file> [options]"
247 takes_optiongroups = {
248 "sambaopts": options.SambaOptions,
249 "credopts": options.CredentialsOptions,
250 "versionopts": options.VersionOptions,
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()
260 netlogon = lp.get("path", "netlogon")
261 sysvol = lp.get("path", "sysvol")
263 samdb = SamDB(session_info=system_session(), lp=lp)
264 except Exception as e:
265 raise CommandError("Unable to open samdb:", e)
267 domain_sid = security.dom_sid(samdb.domain_sid)
269 provision.checksysvolacl(samdb, netlogon, sysvol,
271 lp.get("realm").lower(), samdb.domain_dn(),
275 class cmd_ntacl(SuperCommand):
276 """NT ACLs manipulation."""
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()