3 # delegation management
5 # Copyright Matthieu Patou mat@samba.org 2010
6 # Copyright Stefan Metzmacher metze@samba.org 2011
7 # Copyright Bjoern Baumbach bb@sernet.de 2011
8 # Copyright Giampaolo Lauria 2011 <lauria2@yahoo.com>
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 3 of the License, or
13 # (at your option) any later version.
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 import samba.getopt as options
26 from samba import provision
27 from samba import dsdb
28 from samba.samdb import SamDB
29 from samba.auth import system_session
30 from samba.netcmd.common import _get_user_realm_domain
31 from samba.netcmd import (
40 class cmd_delegation_show(Command):
41 """Show the delegation setting of an account."""
43 synopsis = "%prog delegation show <accountname> [options]"
45 takes_args = ["accountname"]
47 def run(self, accountname, credopts=None, sambaopts=None, versionopts=None):
48 lp = sambaopts.get_loadparm()
49 creds = credopts.get_credentials(lp)
50 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
51 sam = SamDB(paths.samdb, session_info=system_session(),
52 credentials=creds, lp=lp)
53 # TODO once I understand how, use the domain info to naildown
54 # to the correct domain
55 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
56 self.outf.write("Searching for: %s\n" % (cleanedaccount))
57 res = sam.search(expression="sAMAccountName=%s" % ldb.binary_encode(cleanedaccount),
58 scope=ldb.SCOPE_SUBTREE,
59 attrs=["userAccountControl", "msDS-AllowedToDelegateTo"])
61 raise CommandError("Account %s found %d times" % (accountname, len(res)))
63 uac = int(res[0].get("userAccountControl")[0])
64 allowed = res[0].get("msDS-AllowedToDelegateTo")
66 self.outf.write("Account-DN: %s\n" % str(res[0].dn))
67 self.outf.write("UF_TRUSTED_FOR_DELEGATION: %s\n"
68 % bool(uac & dsdb.UF_TRUSTED_FOR_DELEGATION))
69 self.outf.write("UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION: %s\n" %
70 bool(uac & dsdb.UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION))
72 if allowed is not None:
74 self.outf.write("msDS-AllowedToDelegateTo: %s\n" % a)
78 class cmd_delegation_for_any_service(Command):
79 """Set/unset UF_TRUSTED_FOR_DELEGATION for an account."""
81 synopsis = "%prog delegation for-any-service <accountname> [(on|off)] [options]"
83 takes_args = ["accountname", "onoff"]
85 def run(self, accountname, onoff, credopts=None, sambaopts=None, versionopts=None):
93 raise CommandError("Invalid argument [%s]" % onoff)
95 lp = sambaopts.get_loadparm()
96 creds = credopts.get_credentials(lp)
97 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
98 sam = SamDB(paths.samdb, session_info=system_session(),
99 credentials=creds, lp=lp)
100 # TODO once I understand how, use the domain info to naildown
101 # to the correct domain
102 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
104 search_filter = "sAMAccountName=%s" % ldb.binary_encode(cleanedaccount)
105 flag = dsdb.UF_TRUSTED_FOR_DELEGATION
107 sam.toggle_userAccountFlags(search_filter, flag, on=on, strict=True)
108 except Exception, err:
109 raise CommandError(err)
113 class cmd_delegation_for_any_protocol(Command):
114 """Set/unset UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION (S4U2Proxy) for an account."""
116 synopsis = "%prog delegation for-any-protocol <accountname> [(on|off)] [options]"
118 takes_args = ["accountname", "onoff"]
120 def run(self, accountname, onoff, credopts=None, sambaopts=None, versionopts=None):
128 raise CommandError("Invalid argument [%s]" % onoff)
130 lp = sambaopts.get_loadparm()
131 creds = credopts.get_credentials(lp)
132 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
133 sam = SamDB(paths.samdb, session_info=system_session(),
134 credentials=creds, lp=lp)
135 # TODO once I understand how, use the domain info to naildown
136 # to the correct domain
137 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
139 search_filter = "sAMAccountName=%s" % ldb.binary_encode(cleanedaccount)
140 flag = dsdb.UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
142 sam.toggle_userAccountFlags(search_filter, flag, on=on, strict=True)
143 except Exception, err:
144 raise CommandError(err)
148 class cmd_delegation_add_service(Command):
149 """Add a service principal as msDS-AllowedToDelegateTo"""
151 synopsis = "%prog delegation add-service <accountname> <principal> [options]"
153 takes_args = ["accountname", "principal"]
155 def run(self, accountname, principal, credopts=None, sambaopts=None, versionopts=None):
157 lp = sambaopts.get_loadparm()
158 creds = credopts.get_credentials(lp)
159 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
160 sam = SamDB(paths.samdb, session_info=system_session(),
161 credentials=creds, lp=lp)
162 # TODO once I understand how, use the domain info to naildown
163 # to the correct domain
164 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
166 res = sam.search(expression="sAMAccountName=%s" % ldb.binary_encode(cleanedaccount),
167 scope=ldb.SCOPE_SUBTREE,
168 attrs=["msDS-AllowedToDelegateTo"])
170 raise CommandError("Account %s found %d times" % (accountname, len(res)))
174 msg["msDS-AllowedToDelegateTo"] = ldb.MessageElement([principal],
176 "msDS-AllowedToDelegateTo")
179 except Exception, err:
180 raise CommandError(err)
184 class cmd_delegation_del_service(Command):
185 """Delete a service principal as msDS-AllowedToDelegateTo"""
187 synopsis = "%prog delegation del-service <accountname> <principal> [options]"
189 takes_args = ["accountname", "principal"]
191 def run(self, accountname, principal, credopts=None, sambaopts=None, versionopts=None):
193 lp = sambaopts.get_loadparm()
194 creds = credopts.get_credentials(lp)
195 paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
196 sam = SamDB(paths.samdb, session_info=system_session(),
197 credentials=creds, lp=lp)
198 # TODO once I understand how, use the domain info to naildown
199 # to the correct domain
200 (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
202 res = sam.search(expression="sAMAccountName=%s" % ldb.binary_encode(cleanedaccount),
203 scope=ldb.SCOPE_SUBTREE,
204 attrs=["msDS-AllowedToDelegateTo"])
206 raise CommandError("Account %s found %d times" % (accountname, len(res)))
210 msg["msDS-AllowedToDelegateTo"] = ldb.MessageElement([principal],
212 "msDS-AllowedToDelegateTo")
215 except Exception, err:
216 raise CommandError(err)
220 class cmd_delegation(SuperCommand):
221 """Delegation management"""
224 subcommands["show"] = cmd_delegation_show()
225 subcommands["for-any-service"] = cmd_delegation_for_any_service()
226 subcommands["for-any-protocol"] = cmd_delegation_for_any_protocol()
227 subcommands["add-service"] = cmd_delegation_add_service()
228 subcommands["del-service"] = cmd_delegation_del_service()