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))
119 class cmd_ntacl_get(Command):
120 """Get ACLs of a file."""
121 synopsis = "%prog <file> [options]"
123 takes_optiongroups = {
124 "sambaopts": options.SambaOptions,
125 "credopts": options.CredentialsOptions,
126 "versionopts": options.VersionOptions,
130 Option("--as-sddl", help="Output ACL in the SDDL format", action="store_true"),
131 Option("--xattr-backend", type="choice", help="xattr backend type (native fs or tdb)",
132 choices=["native","tdb"]),
133 Option("--eadb-file", help="Name of the tdb file where attributes are stored", type="string"),
134 Option("--use-ntvfs", help="Get the ACLs directly from the TDB or xattr used with the ntvfs file server", action="store_true"),
135 Option("--use-s3fs", help="Get the ACLs for use via the VFS layer used by the default s3fs file server", action="store_true"),
136 Option("--service", help="Name of the smb.conf service to use when getting the ACLs", type="string")
139 takes_args = ["file"]
141 def run(self, file, use_ntvfs=False, use_s3fs=False,
142 as_sddl=False, xattr_backend=None, eadb_file=None,
143 credopts=None, sambaopts=None, versionopts=None,
145 lp = sambaopts.get_loadparm()
147 samdb = SamDB(session_info=system_session(),
149 except Exception as e:
150 raise CommandError("Unable to open samdb:", e)
152 if not use_ntvfs and not use_s3fs:
153 use_ntvfs = "smb" in lp.get("server services")
158 s3conf = s3param.get_context()
159 s3conf.load(lp.configfile)
160 # ensure we are using the right samba_dsdb passdb backend, no matter what
161 s3conf.set("passdb backend", "samba_dsdb:%s" % samdb.url)
163 acl = getntacl(lp, file, xattr_backend, eadb_file, direct_db_access=use_ntvfs, service=service)
166 domain_sid = security.dom_sid(samdb.domain_sid)
168 raise CommandError("Unable to read domain SID from configuration files")
169 self.outf.write(acl.as_sddl(domain_sid) + "\n")
171 self.outf.write(ndr_print(acl))
174 class cmd_ntacl_sysvolreset(Command):
175 """Reset sysvol ACLs to defaults (including correct ACLs on GPOs)."""
176 synopsis = "%prog <file> [options]"
178 takes_optiongroups = {
179 "sambaopts": options.SambaOptions,
180 "credopts": options.CredentialsOptions,
181 "versionopts": options.VersionOptions,
185 Option("--use-ntvfs", help="Set the ACLs for use with the ntvfs file server", action="store_true"),
186 Option("--use-s3fs", help="Set the ACLs for use with the default s3fs file server", action="store_true")
189 def run(self, use_ntvfs=False, use_s3fs=False,
190 credopts=None, sambaopts=None, versionopts=None):
191 lp = sambaopts.get_loadparm()
192 path = lp.private_path("secrets.ldb")
193 creds = credopts.get_credentials(lp)
194 creds.set_kerberos_state(DONT_USE_KERBEROS)
195 logger = self.get_logger()
197 netlogon = lp.get("path", "netlogon")
198 sysvol = lp.get("path", "sysvol")
200 samdb = SamDB(session_info=system_session(),
202 except Exception as e:
203 raise CommandError("Unable to open samdb:", e)
205 if not use_ntvfs and not use_s3fs:
206 use_ntvfs = "smb" in lp.get("server services")
210 domain_sid = security.dom_sid(samdb.domain_sid)
212 s3conf = s3param.get_context()
213 s3conf.load(lp.configfile)
214 # ensure we are using the right samba_dsdb passdb backend, no matter what
215 s3conf.set("passdb backend", "samba_dsdb:%s" % samdb.url)
217 LA_sid = security.dom_sid(str(domain_sid)
218 + "-" +str(security.DOMAIN_RID_ADMINISTRATOR))
219 BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS)
221 s4_passdb = passdb.PDB(s3conf.get("passdb backend"))
223 # These assertions correct for current ad_dc selftest
224 # configuration. When other environments have a broad range of
225 # groups mapped via passdb, we can relax some of these checks
226 (LA_uid,LA_type) = s4_passdb.sid_to_id(LA_sid)
227 if (LA_type != idmap.ID_TYPE_UID and LA_type != idmap.ID_TYPE_BOTH):
228 raise CommandError("SID %s is not mapped to a UID" % LA_sid)
229 (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid)
230 if (BA_type != idmap.ID_TYPE_GID and BA_type != idmap.ID_TYPE_BOTH):
231 raise CommandError("SID %s is not mapped to a GID" % BA_sid)
234 logger.warning("Please note that POSIX permissions have NOT been changed, only the stored NT ACL")
236 provision.setsysvolacl(samdb, netlogon, sysvol,
237 LA_uid, BA_gid, domain_sid,
238 lp.get("realm").lower(), samdb.domain_dn(),
239 lp, use_ntvfs=use_ntvfs)
241 class cmd_ntacl_sysvolcheck(Command):
242 """Check sysvol ACLs match defaults (including correct ACLs on GPOs)."""
243 synopsis = "%prog <file> [options]"
245 takes_optiongroups = {
246 "sambaopts": options.SambaOptions,
247 "credopts": options.CredentialsOptions,
248 "versionopts": options.VersionOptions,
251 def run(self, credopts=None, sambaopts=None, versionopts=None):
252 lp = sambaopts.get_loadparm()
253 path = lp.private_path("secrets.ldb")
254 creds = credopts.get_credentials(lp)
255 creds.set_kerberos_state(DONT_USE_KERBEROS)
256 logger = self.get_logger()
258 netlogon = lp.get("path", "netlogon")
259 sysvol = lp.get("path", "sysvol")
261 samdb = SamDB(session_info=system_session(), lp=lp)
262 except Exception as e:
263 raise CommandError("Unable to open samdb:", e)
265 domain_sid = security.dom_sid(samdb.domain_sid)
267 provision.checksysvolacl(samdb, netlogon, sysvol,
269 lp.get("realm").lower(), samdb.domain_dn(),
273 class cmd_ntacl(SuperCommand):
274 """NT ACLs manipulation."""
277 subcommands["set"] = cmd_ntacl_set()
278 subcommands["get"] = cmd_ntacl_get()
279 subcommands["sysvolreset"] = cmd_ntacl_sysvolreset()
280 subcommands["sysvolcheck"] = cmd_ntacl_sysvolcheck()
281 subcommands["getdosinfo"] = cmd_dosinfo_get()