From: Matthieu Patou Date: Mon, 28 Jun 2010 06:17:00 +0000 (+0400) Subject: s4 net: Add spn module to list/add/remove spn on objects X-Git-Url: http://git.samba.org/?p=mat%2Fsamba.git;a=commitdiff_plain;h=78d909072a0127c853078c11867f77074a8f9321;hp=e3b34e6f93fe160781e7b34ae08a9676516984ae s4 net: Add spn module to list/add/remove spn on objects --- diff --git a/source4/scripting/python/samba/netcmd/__init__.py b/source4/scripting/python/samba/netcmd/__init__.py index 6fd72944ec..08ddcefe91 100644 --- a/source4/scripting/python/samba/netcmd/__init__.py +++ b/source4/scripting/python/samba/netcmd/__init__.py @@ -160,5 +160,7 @@ from samba.netcmd.vampire import cmd_vampire commands["vampire"] = cmd_vampire() from samba.netcmd.machinepw import cmd_machinepw commands["machinepw"] = cmd_machinepw() +from samba.netcmd.spn import cmd_spn +commands["spn"] = cmd_spn() from samba.netcmd.group import cmd_group commands["group"] = cmd_group() diff --git a/source4/scripting/python/samba/netcmd/spn.py b/source4/scripting/python/samba/netcmd/spn.py new file mode 100644 index 0000000000..9ab5b1ccb1 --- /dev/null +++ b/source4/scripting/python/samba/netcmd/spn.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python +# +# spn management +# +# Copyright Matthieu Patou mat@samba.org 2010 +# +# 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 . +# + +import samba.getopt as options +import ldb +import re +import sys +from samba import provision +from samba.samdb import SamDB +from samba.auth import system_session +from samba.netcmd import ( + Command, + SuperCommand, + ) + +class cmd_spn_list(Command): + """Create a new spn.""" + synopsis = "%prog spn add " + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "credopts": options.CredentialsOptions, + "versionopts": options.VersionOptions, + } + + takes_args = ["user"] + + def run(self, user, 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 + m = re.match(r"\w+\\(\w+$)", user) + if m: + user = m.group(1) + m = re.match(r"(\w+)@(\w+)", user) + if m: + user = m.group(1) + res = sam.search(expression="samaccountname=%s" % user, + scope=ldb.SCOPE_SUBTREE, + attrs=["servicePrincipalName"]) + if len(res) >0: + spns = res[0].get("servicePrincipalName") + tab = [] + found = False + flag = ldb.FLAG_MOD_ADD + if spns != None: + print "User %s has the following servicePrincipalName: " % str(res[0].dn) + for e in spns: + print "\t %s" % (str(e)) + + else: + print "User %s has no servicePrincipalName" % str(res[0].dn) + else: + print "User %s not found" % user + sys.exit(1) + +class cmd_spn_add(Command): + """Create a new spn.""" + synopsis = "%prog spn add " + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "credopts": options.CredentialsOptions, + "versionopts": options.VersionOptions, + } + + takes_args = ["name", "user"] + + def run(self, name, user, 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) + m = re.match(r"\w+\\(\w+$)", user) + if m: + user = m.group(1) + m = re.match(r"(\w+)@(\w+)", user) + if m: + user = m.group(1) + res = sam.search(expression="samaccountname=%s" % user, + scope=ldb.SCOPE_SUBTREE, + attrs=["servicePrincipalName"]) + if len(res) >0: + res[0].dn + msg = ldb.Message() + spns = res[0].get("servicePrincipalName") + tab = [] + found = False + flag = ldb.FLAG_MOD_ADD + if spns != None: + for e in spns: + if str(e) == name: + found = True + tab.append(str(e)) + flag = ldb.FLAG_MOD_REPLACE + tab.append(name) + msg.dn = res[0].dn + msg["servicePrincipalName"] = ldb.MessageElement(tab, flag, + "servicePrincipalName") + if not found: + sam.modify(msg) + else: + print "Service principal %s already affected to %s" % (name, user) + else: + print "User %s not found" % user + sys.exit(1) + + +class cmd_spn_delete(Command): + """Delete a spn.""" + synopsis = "%prog spn delete " + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "credopts": options.CredentialsOptions, + "versionopts": options.VersionOptions, + } + + takes_args = ["name"] + + def run(self, name, 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) + res = sam.search(expression="servicePrincipalName=%s" % name, + scope=ldb.SCOPE_SUBTREE, + attrs=["servicePrincipalName"]) + if len(res) >0: + res[0].dn + msg = ldb.Message() + spns = res[0].get("servicePrincipalName") + tab = [] + if spns != None: + for e in spns: + if str(e) != name: + tab.append(str(e)) + flag = ldb.FLAG_MOD_REPLACE + msg.dn = res[0].dn + msg["servicePrincipalName"] = ldb.MessageElement(tab, flag, + "servicePrincipalName") + sam.modify(msg) + else: + print "Service principal %s not affected" % name + sys.exit(1) + +class cmd_spn(SuperCommand): + """User management [server connection needed]""" + + subcommands = {} + subcommands["add"] = cmd_spn_add() + subcommands["list"] = cmd_spn_list() + subcommands["delete"] = cmd_spn_delete() + diff --git a/source4/selftest/tests.sh b/source4/selftest/tests.sh index 4181d83ba2..769cc95360 100755 --- a/source4/selftest/tests.sh +++ b/source4/selftest/tests.sh @@ -517,4 +517,5 @@ plantestsuite "blackbox.upgradeprovision.py" none PYTHON="$PYTHON" $samba4srcdir plantestsuite "blackbox.setpassword.py" none PYTHON="$PYTHON" $samba4srcdir/setup/tests/blackbox_setpassword.sh "$PREFIX/provision" plantestsuite "blackbox.newuser.py" none PYTHON="$PYTHON" $samba4srcdir/setup/tests/blackbox_newuser.sh "$PREFIX/provision" plantestsuite "blackbox.group.py" none PYTHON="$PYTHON" $samba4srcdir/setup/tests/blackbox_group.sh "$PREFIX/provision" +plantestsuite "blackbox.spn.py" dc:local PYTHON="$PYTHON" $samba4srcdir/setup/tests/blackbox_spn.sh "$PREFIX/dc" plantestsuite_loadlist "blaat" none PYTHON="$PYTHON" "$samba4srcdir/record.py" diff --git a/source4/setup/tests/blackbox_spn.sh b/source4/setup/tests/blackbox_spn.sh new file mode 100755 index 0000000000..ec190542f4 --- /dev/null +++ b/source4/setup/tests/blackbox_spn.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +if [ $# -lt 1 ]; then +cat <