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
24 from samba
.ndr
import ndr_unpack
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("--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"),
60 takes_args
= ["acl","file"]
62 def run(self
, acl
, file, quiet
=False,xattr_backend
=None,eadb_file
=None,
63 credopts
=None, sambaopts
=None, versionopts
=None):
64 lp
= sambaopts
.get_loadparm()
65 path
= lp
.private_path("secrets.ldb")
66 creds
= credopts
.get_credentials(lp
)
67 creds
.set_kerberos_state(DONT_USE_KERBEROS
)
69 ldb
= Ldb(path
, session_info
=system_session(), credentials
=creds
,
72 raise CommandError("Unable to read domain SID from configuration files", e
)
74 res
= ldb
.search(expression
="(objectClass=*)",
75 base
="flatname=%s,cn=Primary Domains" % lp
.get("workgroup"),
76 scope
=SCOPE_BASE
, attrs
=attrs
)
78 domainsid
= ndr_unpack(security
.dom_sid
, res
[0]["objectSid"][0])
79 setntacl(lp
, file, acl
, str(domainsid
), xattr_backend
, eadb_file
)
81 raise CommandError("Unable to read domain SID from configuration files")
85 class cmd_ntacl_get(Command
):
86 """Set ACLs on a file"""
87 synopsis
= "%prog <file> [options]"
89 takes_optiongroups
= {
90 "sambaopts": options
.SambaOptions
,
91 "credopts": options
.CredentialsOptions
,
92 "versionopts": options
.VersionOptions
,
96 Option("--as-sddl", help="Output ACL in the SDDL format", action
="store_true"),
97 Option("--xattr-backend", type="choice", help="xattr backend type (native fs or tdb)",
98 choices
=["native","tdb"]),
99 Option("--eadb-file", help="Name of the tdb file where attributes are stored", type="string"),
102 takes_args
= ["file"]
104 def run(self
, file, as_sddl
=False, xattr_backend
=None, eadb_file
=None,
105 credopts
=None, sambaopts
=None, versionopts
=None):
106 lp
= sambaopts
.get_loadparm()
107 acl
= getntacl(lp
, file, xattr_backend
, eadb_file
)
109 anysid
= security
.dom_sid(security
.SID_NT_SELF
)
110 self
.outf
.write(acl
.info
.as_sddl(anysid
)+"\n")
115 class cmd_ntacl_sysvolreset(Command
):
116 """Reset sysvol ACLs to defaults (including correct ACLs on GPOs)"""
117 synopsis
= "%prog <file> [options]"
119 takes_optiongroups
= {
120 "sambaopts": options
.SambaOptions
,
121 "credopts": options
.CredentialsOptions
,
122 "versionopts": options
.VersionOptions
,
126 Option("--use-ntvfs", help="Set the ACLs for use with the ntvfs file server", action
="store_true"),
127 Option("--use-s3fs", help="Set the ACLs for use with the default s3fs file server", action
="store_true")
130 def run(self
, use_ntvfs
=False, use_s3fs
=False,
131 credopts
=None, sambaopts
=None, versionopts
=None):
132 lp
= sambaopts
.get_loadparm()
133 path
= lp
.private_path("secrets.ldb")
134 creds
= credopts
.get_credentials(lp
)
135 creds
.set_kerberos_state(DONT_USE_KERBEROS
)
136 logger
= self
.get_logger()
138 netlogon
= lp
.get("path", "netlogon")
139 sysvol
= lp
.get("path", "sysvol")
141 samdb
= SamDB(session_info
=system_session(),
144 raise CommandError("Unable to open samdb:", e
)
146 if not use_ntvfs
and not use_s3fs
:
147 use_ntvfs
= "smb" in lp
.get("server services")
151 domain_sid
= security
.dom_sid(samdb
.domain_sid
)
153 s3conf
= s3param
.get_context()
154 s3conf
.load(lp
.configfile
)
155 # ensure we are using the right samba4 passdb backend, no matter what
156 s3conf
.set("passdb backend", "samba4:%s" % samdb
.url
)
158 LA_sid
= security
.dom_sid(str(domain_sid
)
159 +"-"+str(security
.DOMAIN_RID_ADMINISTRATOR
))
160 BA_sid
= security
.dom_sid(security
.SID_BUILTIN_ADMINISTRATORS
)
162 s4_passdb
= passdb
.PDB(s3conf
.get("passdb backend"))
164 # These assertions correct for current plugin_s4_dc selftest
165 # configuration. When other environments have a broad range of
166 # groups mapped via passdb, we can relax some of these checks
167 (LA_uid
,LA_type
) = s4_passdb
.sid_to_id(LA_sid
)
168 if (LA_type
!= idmap
.ID_TYPE_UID
and LA_type
!= idmap
.ID_TYPE_BOTH
):
169 raise CommandError("SID %s is not mapped to a UID" % LA_sid
)
170 (BA_gid
,BA_type
) = s4_passdb
.sid_to_id(BA_sid
)
171 if (BA_type
!= idmap
.ID_TYPE_GID
and BA_type
!= idmap
.ID_TYPE_BOTH
):
172 raise CommandError("SID %s is not mapped to a GID" % BA_sid
)
175 logger
.warning("Please note that POSIX permissions have NOT been changed, only the stored NT ACL")
177 provision
.setsysvolacl(samdb
, netlogon
, sysvol
,
178 LA_uid
, BA_gid
, domain_sid
,
179 lp
.get("realm").lower(), samdb
.domain_dn(),
180 lp
, use_ntvfs
=use_ntvfs
)
182 class cmd_ntacl_sysvolcheck(Command
):
183 """Check sysvol ACLs match defaults (including correct ACLs on GPOs)"""
184 synopsis
= "%prog <file> [options]"
186 takes_optiongroups
= {
187 "sambaopts": options
.SambaOptions
,
188 "credopts": options
.CredentialsOptions
,
189 "versionopts": options
.VersionOptions
,
193 credopts
=None, sambaopts
=None, versionopts
=None):
194 lp
= sambaopts
.get_loadparm()
195 path
= lp
.private_path("secrets.ldb")
196 creds
= credopts
.get_credentials(lp
)
197 creds
.set_kerberos_state(DONT_USE_KERBEROS
)
198 logger
= self
.get_logger()
200 netlogon
= lp
.get("path", "netlogon")
201 sysvol
= lp
.get("path", "sysvol")
203 samdb
= SamDB(session_info
=system_session(),
206 raise CommandError("Unable to open samdb:", e
)
208 domain_sid
= security
.dom_sid(samdb
.domain_sid
)
210 provision
.checksysvolacl(samdb
, netlogon
, sysvol
,
212 lp
.get("realm").lower(), samdb
.domain_dn(),
216 class cmd_ntacl(SuperCommand
):
217 """NT ACLs manipulation"""
220 subcommands
["set"] = cmd_ntacl_set()
221 subcommands
["get"] = cmd_ntacl_get()
222 subcommands
["sysvolreset"] = cmd_ntacl_sysvolreset()
223 subcommands
["sysvolcheck"] = cmd_ntacl_sysvolcheck()