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
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 (
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,
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"))
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"])
75 raise CommandError("Unable to find account name '%s'" % accountname)
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:
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,
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,
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"))
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
138 sam.toggle_userAccountFlags(search_filter, flag,
139 flags_str="Trusted-for-Delegation",
141 except Exception as 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,
157 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
158 metavar="URL", dest="H"),
161 takes_args = ["accountname", "onoff"]
163 def run(self, accountname, onoff, H=None, credopts=None, sambaopts=None,
172 raise CommandError("invalid argument: '%s' (choose from 'on', 'off')" % onoff)
174 lp = sambaopts.get_loadparm()
175 creds = credopts.get_credentials(lp, fallback_machine=True)
176 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
182 sam = SamDB(path, session_info=system_session(),
183 credentials=creds, lp=lp)
184 # TODO once I understand how, use the domain info to naildown
185 # to the correct domain
186 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
188 search_filter = "sAMAccountName=%s" % ldb.binary_encode(cleanedaccount)
189 flag = dsdb.UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
191 sam.toggle_userAccountFlags(search_filter, flag,
192 flags_str="Trusted-to-Authenticate-for-Delegation",
194 except Exception as err:
195 raise CommandError(err)
198 class cmd_delegation_add_service(Command):
199 """Add a service principal as msDS-AllowedToDelegateTo."""
201 synopsis = "%prog <accountname> <principal> [options]"
203 takes_optiongroups = {
204 "sambaopts": options.SambaOptions,
205 "credopts": options.CredentialsOptions,
206 "versionopts": options.VersionOptions,
210 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
211 metavar="URL", dest="H"),
214 takes_args = ["accountname", "principal"]
216 def run(self, accountname, principal, H=None, credopts=None, sambaopts=None,
219 lp = sambaopts.get_loadparm()
220 creds = credopts.get_credentials(lp)
221 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
227 sam = SamDB(path, session_info=system_session(),
228 credentials=creds, lp=lp)
229 # TODO once I understand how, use the domain info to naildown
230 # to the correct domain
231 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
233 res = sam.search(expression="sAMAccountName=%s" %
234 ldb.binary_encode(cleanedaccount),
235 scope=ldb.SCOPE_SUBTREE,
236 attrs=["msDS-AllowedToDelegateTo"])
238 raise CommandError("Unable to find account name '%s'" % accountname)
239 assert(len(res) == 1)
243 msg["msDS-AllowedToDelegateTo"] = ldb.MessageElement([principal],
245 "msDS-AllowedToDelegateTo")
248 except Exception as err:
249 raise CommandError(err)
252 class cmd_delegation_del_service(Command):
253 """Delete a service principal as msDS-AllowedToDelegateTo."""
255 synopsis = "%prog <accountname> <principal> [options]"
257 takes_optiongroups = {
258 "sambaopts": options.SambaOptions,
259 "credopts": options.CredentialsOptions,
260 "versionopts": options.VersionOptions,
264 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
265 metavar="URL", dest="H"),
268 takes_args = ["accountname", "principal"]
270 def run(self, accountname, principal, H=None, credopts=None, sambaopts=None,
273 lp = sambaopts.get_loadparm()
274 creds = credopts.get_credentials(lp)
275 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
281 sam = SamDB(path, session_info=system_session(),
282 credentials=creds, lp=lp)
283 # TODO once I understand how, use the domain info to naildown
284 # to the correct domain
285 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
287 res = sam.search(expression="sAMAccountName=%s" %
288 ldb.binary_encode(cleanedaccount),
289 scope=ldb.SCOPE_SUBTREE,
290 attrs=["msDS-AllowedToDelegateTo"])
292 raise CommandError("Unable to find account name '%s'" % accountname)
293 assert(len(res) == 1)
297 msg["msDS-AllowedToDelegateTo"] = ldb.MessageElement([principal],
299 "msDS-AllowedToDelegateTo")
302 except Exception as err:
303 raise CommandError(err)
306 class cmd_delegation(SuperCommand):
307 """Delegation management."""
310 subcommands["show"] = cmd_delegation_show()
311 subcommands["for-any-service"] = cmd_delegation_for_any_service()
312 subcommands["for-any-protocol"] = cmd_delegation_for_any_protocol()
313 subcommands["add-service"] = cmd_delegation_add_service()
314 subcommands["del-service"] = cmd_delegation_del_service()