diff options
Diffstat (limited to 'python/samba/netcmd/delegation.py')
-rw-r--r-- | python/samba/netcmd/delegation.py | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/python/samba/netcmd/delegation.py b/python/samba/netcmd/delegation.py new file mode 100644 index 0000000000..47dffb07d5 --- /dev/null +++ b/python/samba/netcmd/delegation.py @@ -0,0 +1,263 @@ +# delegation management +# +# Copyright Matthieu Patou mat@samba.org 2010 +# Copyright Stefan Metzmacher metze@samba.org 2011 +# Copyright Bjoern Baumbach bb@sernet.de 2011 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import samba.getopt as options +import ldb +from samba import provision +from samba import dsdb +from samba.samdb import SamDB +from samba.auth import system_session +from samba.netcmd.common import _get_user_realm_domain +from samba.netcmd import ( + Command, + CommandError, + SuperCommand, + Option + ) + + +class cmd_delegation_show(Command): + """Show the delegation setting of an account.""" + + synopsis = "%prog <accountname> [options]" + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "credopts": options.CredentialsOptions, + "versionopts": options.VersionOptions, + } + + takes_args = ["accountname"] + + def run(self, accountname, credopts=None, sambaopts=None, versionopts=None): + lp = sambaopts.get_loadparm() + creds = credopts.get_credentials(lp) + paths = provision.provision_paths_from_lp(lp, lp.get("realm")) + sam = SamDB(paths.samdb, session_info=system_session(), + credentials=creds, lp=lp) + # TODO once I understand how, use the domain info to naildown + # to the correct domain + (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname) + + res = sam.search(expression="sAMAccountName=%s" % + ldb.binary_encode(cleanedaccount), + scope=ldb.SCOPE_SUBTREE, + attrs=["userAccountControl", "msDS-AllowedToDelegateTo"]) + if len(res) == 0: + raise CommandError("Unable to find account name '%s'" % accountname) + assert(len(res) == 1) + + uac = int(res[0].get("userAccountControl")[0]) + allowed = res[0].get("msDS-AllowedToDelegateTo") + + self.outf.write("Account-DN: %s\n" % str(res[0].dn)) + self.outf.write("UF_TRUSTED_FOR_DELEGATION: %s\n" + % bool(uac & dsdb.UF_TRUSTED_FOR_DELEGATION)) + self.outf.write("UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION: %s\n" % + bool(uac & dsdb.UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION)) + + if allowed is not None: + for a in allowed: + self.outf.write("msDS-AllowedToDelegateTo: %s\n" % a) + + +class cmd_delegation_for_any_service(Command): + """Set/unset UF_TRUSTED_FOR_DELEGATION for an account.""" + + synopsis = "%prog <accountname> [(on|off)] [options]" + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "credopts": options.CredentialsOptions, + "versionopts": options.VersionOptions, + } + + takes_args = ["accountname", "onoff"] + + def run(self, accountname, onoff, credopts=None, sambaopts=None, + versionopts=None): + + on = False + if onoff == "on": + on = True + elif onoff == "off": + on = False + else: + raise CommandError("invalid argument: '%s' (choose from 'on', 'off')" % onoff) + + lp = sambaopts.get_loadparm() + creds = credopts.get_credentials(lp) + paths = provision.provision_paths_from_lp(lp, lp.get("realm")) + sam = SamDB(paths.samdb, session_info=system_session(), + credentials=creds, lp=lp) + # TODO once I understand how, use the domain info to naildown + # to the correct domain + (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname) + + search_filter = "sAMAccountName=%s" % ldb.binary_encode(cleanedaccount) + flag = dsdb.UF_TRUSTED_FOR_DELEGATION + try: + sam.toggle_userAccountFlags(search_filter, flag, + flags_str="Trusted-for-Delegation", + on=on, strict=True) + except Exception, err: + raise CommandError(err) + + +class cmd_delegation_for_any_protocol(Command): + """Set/unset UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION (S4U2Proxy) for an account.""" + + synopsis = "%prog <accountname> [(on|off)] [options]" + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "credopts": options.CredentialsOptions, + "versionopts": options.VersionOptions, + } + + takes_args = ["accountname", "onoff"] + + def run(self, accountname, onoff, credopts=None, sambaopts=None, + versionopts=None): + + on = False + if onoff == "on": + on = True + elif onoff == "off": + on = False + else: + raise CommandError("invalid argument: '%s' (choose from 'on', 'off')" % onoff) + + lp = sambaopts.get_loadparm() + creds = credopts.get_credentials(lp) + paths = provision.provision_paths_from_lp(lp, lp.get("realm")) + sam = SamDB(paths.samdb, session_info=system_session(), + credentials=creds, lp=lp) + # TODO once I understand how, use the domain info to naildown + # to the correct domain + (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname) + + search_filter = "sAMAccountName=%s" % ldb.binary_encode(cleanedaccount) + flag = dsdb.UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION + try: + sam.toggle_userAccountFlags(search_filter, flag, + flags_str="Trusted-to-Authenticate-for-Delegation", + on=on, strict=True) + except Exception, err: + raise CommandError(err) + + +class cmd_delegation_add_service(Command): + """Add a service principal as msDS-AllowedToDelegateTo.""" + + synopsis = "%prog <accountname> <principal> [options]" + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "credopts": options.CredentialsOptions, + "versionopts": options.VersionOptions, + } + + takes_args = ["accountname", "principal"] + + def run(self, accountname, principal, credopts=None, sambaopts=None, + versionopts=None): + + lp = sambaopts.get_loadparm() + creds = credopts.get_credentials(lp) + paths = provision.provision_paths_from_lp(lp, lp.get("realm")) + sam = SamDB(paths.samdb, session_info=system_session(), + credentials=creds, lp=lp) + # TODO once I understand how, use the domain info to naildown + # to the correct domain + (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname) + + res = sam.search(expression="sAMAccountName=%s" % + ldb.binary_encode(cleanedaccount), + scope=ldb.SCOPE_SUBTREE, + attrs=["msDS-AllowedToDelegateTo"]) + if len(res) == 0: + raise CommandError("Unable to find account name '%s'" % accountname) + assert(len(res) == 1) + + msg = ldb.Message() + msg.dn = res[0].dn + msg["msDS-AllowedToDelegateTo"] = ldb.MessageElement([principal], + ldb.FLAG_MOD_ADD, + "msDS-AllowedToDelegateTo") + try: + sam.modify(msg) + except Exception, err: + raise CommandError(err) + + +class cmd_delegation_del_service(Command): + """Delete a service principal as msDS-AllowedToDelegateTo.""" + + synopsis = "%prog <accountname> <principal> [options]" + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "credopts": options.CredentialsOptions, + "versionopts": options.VersionOptions, + } + + takes_args = ["accountname", "principal"] + + def run(self, accountname, principal, credopts=None, sambaopts=None, + versionopts=None): + + lp = sambaopts.get_loadparm() + creds = credopts.get_credentials(lp) + paths = provision.provision_paths_from_lp(lp, lp.get("realm")) + sam = SamDB(paths.samdb, session_info=system_session(), + credentials=creds, lp=lp) + # TODO once I understand how, use the domain info to naildown + # to the correct domain + (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname) + + res = sam.search(expression="sAMAccountName=%s" % + ldb.binary_encode(cleanedaccount), + scope=ldb.SCOPE_SUBTREE, + attrs=["msDS-AllowedToDelegateTo"]) + if len(res) == 0: + raise CommandError("Unable to find account name '%s'" % accountname) + assert(len(res) == 1) + + msg = ldb.Message() + msg.dn = res[0].dn + msg["msDS-AllowedToDelegateTo"] = ldb.MessageElement([principal], + ldb.FLAG_MOD_DELETE, + "msDS-AllowedToDelegateTo") + try: + sam.modify(msg) + except Exception, err: + raise CommandError(err) + + +class cmd_delegation(SuperCommand): + """Delegation management.""" + + subcommands = {} + subcommands["show"] = cmd_delegation_show() + subcommands["for-any-service"] = cmd_delegation_for_any_service() + subcommands["for-any-protocol"] = cmd_delegation_for_any_protocol() + subcommands["add-service"] = cmd_delegation_add_service() + subcommands["del-service"] = cmd_delegation_del_service() |