s4 net: Add spn module to list/add/remove spn on objects
authorMatthieu Patou <mat@matws.net>
Mon, 28 Jun 2010 06:17:00 +0000 (10:17 +0400)
committerMatthieu Patou <mat@matws.net>
Mon, 28 Jun 2010 09:53:11 +0000 (13:53 +0400)
source4/scripting/python/samba/netcmd/__init__.py
source4/scripting/python/samba/netcmd/spn.py [new file with mode: 0644]
source4/selftest/tests.sh
source4/setup/tests/blackbox_spn.sh [new file with mode: 0755]

index 6fd72944ec8a9f0d76a073b9532cd4a776e409de..08ddcefe910adb2aa63e914880f5bfc4bcb2e9ea 100644 (file)
@@ -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 (file)
index 0000000..9ab5b1c
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+#
+
+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 <name> <user>"
+
+    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 <name> <user>"
+
+    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 <name>"
+
+    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()
+
index 4181d83ba2beccfa3f92f782751a42d41c694257..769cc95360b231b69b158983d4bbd4eca8b761ba 100755 (executable)
@@ -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 (executable)
index 0000000..ec19054
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+if [ $# -lt 1 ]; then
+cat <<EOF
+Usage: blackbox_group.sh PREFIX
+EOF
+exit 1;
+fi
+
+PREFIX="$1"
+shift 1
+
+. `dirname $0`/../../../testprogs/blackbox/subunit.sh
+
+
+net="./bin/net"
+
+CONFIG="--configfile=$PREFIX/etc/smb.conf"
+
+#creation of two test subjects
+testit "addspn" $net spn add FOO/bar Administrator $CONFIG
+testit "delspn" $net spn delete FOO/bar $CONFIG
+testit_expect_failure "faildelspn" $net spn delete FOO/bar $CONFIG
+testit_expect_failure "failaddspn" $net spn add FOO/bar nonexistinguser $CONFIG
+
+exit $failed