dbcheck: Add explict tests for unknown and unsorted attributeID values
[Samba.git] / python / samba / netcmd / delegation.py
blob39397bbcc754e3cb7fc5f9857de975aa43674a6c
1 # delegation management
3 # Copyright Matthieu Patou mat@samba.org 2010
4 # Copyright Stefan Metzmacher metze@samba.org 2011
5 # Copyright Bjoern Baumbach bb@sernet.de 2011
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 import samba.getopt as options
22 import ldb
23 from samba import provision
24 from samba import dsdb
25 from samba.samdb import SamDB
26 from samba.auth import system_session
27 from samba.netcmd.common import _get_user_realm_domain
28 from samba.netcmd import (
29 Command,
30 CommandError,
31 SuperCommand,
32 Option
36 class cmd_delegation_show(Command):
37 """Show the delegation setting of an account."""
39 synopsis = "%prog <accountname> [options]"
41 takes_optiongroups = {
42 "sambaopts": options.SambaOptions,
43 "credopts": options.CredentialsOptions,
44 "versionopts": options.VersionOptions,
47 takes_options = [
48 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
49 metavar="URL", dest="H"),
52 takes_args = ["accountname"]
54 def run(self, accountname, H=None, credopts=None, sambaopts=None, versionopts=None):
55 lp = sambaopts.get_loadparm()
56 creds = credopts.get_credentials(lp)
57 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
59 if H == None:
60 path = paths.samdb
61 else:
62 path = H
64 sam = SamDB(path, session_info=system_session(),
65 credentials=creds, lp=lp)
66 # TODO once I understand how, use the domain info to naildown
67 # to the correct domain
68 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
70 res = sam.search(expression="sAMAccountName=%s" %
71 ldb.binary_encode(cleanedaccount),
72 scope=ldb.SCOPE_SUBTREE,
73 attrs=["userAccountControl", "msDS-AllowedToDelegateTo"])
74 if len(res) == 0:
75 raise CommandError("Unable to find account name '%s'" % accountname)
76 assert(len(res) == 1)
78 uac = int(res[0].get("userAccountControl")[0])
79 allowed = res[0].get("msDS-AllowedToDelegateTo")
81 self.outf.write("Account-DN: %s\n" % str(res[0].dn))
82 self.outf.write("UF_TRUSTED_FOR_DELEGATION: %s\n"
83 % bool(uac & dsdb.UF_TRUSTED_FOR_DELEGATION))
84 self.outf.write("UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION: %s\n" %
85 bool(uac & dsdb.UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION))
87 if allowed is not None:
88 for a in allowed:
89 self.outf.write("msDS-AllowedToDelegateTo: %s\n" % a)
92 class cmd_delegation_for_any_service(Command):
93 """Set/unset UF_TRUSTED_FOR_DELEGATION for an account."""
95 synopsis = "%prog <accountname> [(on|off)] [options]"
97 takes_optiongroups = {
98 "sambaopts": options.SambaOptions,
99 "credopts": options.CredentialsOptions,
100 "versionopts": options.VersionOptions,
103 takes_options = [
104 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
105 metavar="URL", dest="H"),
108 takes_args = ["accountname", "onoff"]
110 def run(self, accountname, onoff, H=None, credopts=None, sambaopts=None,
111 versionopts=None):
113 on = False
114 if onoff == "on":
115 on = True
116 elif onoff == "off":
117 on = False
118 else:
119 raise CommandError("invalid argument: '%s' (choose from 'on', 'off')" % onoff)
121 lp = sambaopts.get_loadparm()
122 creds = credopts.get_credentials(lp)
123 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
124 if H == None:
125 path = paths.samdb
126 else:
127 path = H
129 sam = SamDB(path, session_info=system_session(),
130 credentials=creds, lp=lp)
131 # TODO once I understand how, use the domain info to naildown
132 # to the correct domain
133 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
135 search_filter = "sAMAccountName=%s" % ldb.binary_encode(cleanedaccount)
136 flag = dsdb.UF_TRUSTED_FOR_DELEGATION
137 try:
138 sam.toggle_userAccountFlags(search_filter, flag,
139 flags_str="Trusted-for-Delegation",
140 on=on, strict=True)
141 except Exception, err:
142 raise CommandError(err)
145 class cmd_delegation_for_any_protocol(Command):
146 """Set/unset UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION (S4U2Proxy) for an account."""
148 synopsis = "%prog <accountname> [(on|off)] [options]"
150 takes_optiongroups = {
151 "sambaopts": options.SambaOptions,
152 "credopts": options.CredentialsOptions,
153 "versionopts": options.VersionOptions,
156 takes_options = [
157 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
158 metavar="URL", dest="H"),
162 takes_args = ["accountname", "onoff"]
164 def run(self, accountname, onoff, H=None, credopts=None, sambaopts=None,
165 versionopts=None):
167 on = False
168 if onoff == "on":
169 on = True
170 elif onoff == "off":
171 on = False
172 else:
173 raise CommandError("invalid argument: '%s' (choose from 'on', 'off')" % onoff)
175 lp = sambaopts.get_loadparm()
176 creds = credopts.get_credentials(lp, fallback_machine=True)
177 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
178 if H == None:
179 path = paths.samdb
180 else:
181 path = H
183 sam = SamDB(path, session_info=system_session(),
184 credentials=creds, lp=lp)
185 # TODO once I understand how, use the domain info to naildown
186 # to the correct domain
187 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
189 search_filter = "sAMAccountName=%s" % ldb.binary_encode(cleanedaccount)
190 flag = dsdb.UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
191 try:
192 sam.toggle_userAccountFlags(search_filter, flag,
193 flags_str="Trusted-to-Authenticate-for-Delegation",
194 on=on, strict=True)
195 except Exception, err:
196 raise CommandError(err)
199 class cmd_delegation_add_service(Command):
200 """Add a service principal as msDS-AllowedToDelegateTo."""
202 synopsis = "%prog <accountname> <principal> [options]"
204 takes_optiongroups = {
205 "sambaopts": options.SambaOptions,
206 "credopts": options.CredentialsOptions,
207 "versionopts": options.VersionOptions,
210 takes_options = [
211 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
212 metavar="URL", dest="H"),
215 takes_args = ["accountname", "principal"]
217 def run(self, accountname, principal, H=None, credopts=None, sambaopts=None,
218 versionopts=None):
220 lp = sambaopts.get_loadparm()
221 creds = credopts.get_credentials(lp)
222 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
223 if H == None:
224 path = paths.samdb
225 else:
226 path = H
228 sam = SamDB(path, session_info=system_session(),
229 credentials=creds, lp=lp)
230 # TODO once I understand how, use the domain info to naildown
231 # to the correct domain
232 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
234 res = sam.search(expression="sAMAccountName=%s" %
235 ldb.binary_encode(cleanedaccount),
236 scope=ldb.SCOPE_SUBTREE,
237 attrs=["msDS-AllowedToDelegateTo"])
238 if len(res) == 0:
239 raise CommandError("Unable to find account name '%s'" % accountname)
240 assert(len(res) == 1)
242 msg = ldb.Message()
243 msg.dn = res[0].dn
244 msg["msDS-AllowedToDelegateTo"] = ldb.MessageElement([principal],
245 ldb.FLAG_MOD_ADD,
246 "msDS-AllowedToDelegateTo")
247 try:
248 sam.modify(msg)
249 except Exception, err:
250 raise CommandError(err)
253 class cmd_delegation_del_service(Command):
254 """Delete a service principal as msDS-AllowedToDelegateTo."""
256 synopsis = "%prog <accountname> <principal> [options]"
258 takes_optiongroups = {
259 "sambaopts": options.SambaOptions,
260 "credopts": options.CredentialsOptions,
261 "versionopts": options.VersionOptions,
264 takes_options = [
265 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
266 metavar="URL", dest="H"),
269 takes_args = ["accountname", "principal"]
271 def run(self, accountname, principal, H=None, credopts=None, sambaopts=None,
272 versionopts=None):
274 lp = sambaopts.get_loadparm()
275 creds = credopts.get_credentials(lp)
276 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
277 if H == None:
278 path = paths.samdb
279 else:
280 path = H
282 sam = SamDB(path, session_info=system_session(),
283 credentials=creds, lp=lp)
284 # TODO once I understand how, use the domain info to naildown
285 # to the correct domain
286 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
288 res = sam.search(expression="sAMAccountName=%s" %
289 ldb.binary_encode(cleanedaccount),
290 scope=ldb.SCOPE_SUBTREE,
291 attrs=["msDS-AllowedToDelegateTo"])
292 if len(res) == 0:
293 raise CommandError("Unable to find account name '%s'" % accountname)
294 assert(len(res) == 1)
296 msg = ldb.Message()
297 msg.dn = res[0].dn
298 msg["msDS-AllowedToDelegateTo"] = ldb.MessageElement([principal],
299 ldb.FLAG_MOD_DELETE,
300 "msDS-AllowedToDelegateTo")
301 try:
302 sam.modify(msg)
303 except Exception, err:
304 raise CommandError(err)
307 class cmd_delegation(SuperCommand):
308 """Delegation management."""
310 subcommands = {}
311 subcommands["show"] = cmd_delegation_show()
312 subcommands["for-any-service"] = cmd_delegation_for_any_service()
313 subcommands["for-any-protocol"] = cmd_delegation_for_any_protocol()
314 subcommands["add-service"] = cmd_delegation_add_service()
315 subcommands["del-service"] = cmd_delegation_del_service()