s4 net: Add spn module to list/add/remove spn on objects
[mat/samba.git] / source4 / scripting / python / samba / netcmd / spn.py
1 #!/usr/bin/env python
2 #
3 # spn management
4 #
5 # Copyright Matthieu Patou mat@samba.org 2010
6 #
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.
11 #
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.
16 #
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/>.
19 #
20
21 import samba.getopt as options
22 import ldb
23 import re
24 import sys
25 from samba import provision
26 from samba.samdb import SamDB
27 from samba.auth import system_session
28 from samba.netcmd import (
29     Command,
30     SuperCommand,
31     )
32
33 class cmd_spn_list(Command):
34     """Create a new spn."""
35     synopsis = "%prog spn add <name> <user>"
36
37     takes_optiongroups = {
38         "sambaopts": options.SambaOptions,
39         "credopts": options.CredentialsOptions,
40         "versionopts": options.VersionOptions,
41         }
42
43     takes_args = ["user"]
44
45     def run(self, user, credopts=None, sambaopts=None, versionopts=None):
46         lp = sambaopts.get_loadparm()
47         creds = credopts.get_credentials(lp)
48         paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
49         sam = SamDB(paths.samdb, session_info=system_session(),
50                     credentials=creds, lp=lp)
51         # TODO once I understand how, use the domain info to naildown
52         # to the correct domain
53         m = re.match(r"\w+\\(\w+$)", user)
54         if m:
55             user = m.group(1)
56         m = re.match(r"(\w+)@(\w+)", user)
57         if m:
58             user = m.group(1)
59         res = sam.search(expression="samaccountname=%s" % user,
60                             scope=ldb.SCOPE_SUBTREE,
61                             attrs=["servicePrincipalName"])
62         if len(res) >0:
63             spns = res[0].get("servicePrincipalName")
64             tab = []
65             found = False
66             flag = ldb.FLAG_MOD_ADD
67             if spns != None:
68                 print "User %s has the following servicePrincipalName: " %  str(res[0].dn)
69                 for e in spns:
70                     print "\t %s" % (str(e))
71
72             else:
73                 print "User %s has no servicePrincipalName" % str(res[0].dn)
74         else:
75             print "User %s not found" % user
76             sys.exit(1)
77
78 class cmd_spn_add(Command):
79     """Create a new spn."""
80     synopsis = "%prog spn add <name> <user>"
81
82     takes_optiongroups = {
83         "sambaopts": options.SambaOptions,
84         "credopts": options.CredentialsOptions,
85         "versionopts": options.VersionOptions,
86         }
87
88     takes_args = ["name", "user"]
89
90     def run(self, name, user, credopts=None, sambaopts=None, versionopts=None):
91         lp = sambaopts.get_loadparm()
92         creds = credopts.get_credentials(lp)
93         paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
94         sam = SamDB(paths.samdb, session_info=system_session(),
95                     credentials=creds, lp=lp)
96         m = re.match(r"\w+\\(\w+$)", user)
97         if m:
98             user = m.group(1)
99         m = re.match(r"(\w+)@(\w+)", user)
100         if m:
101             user = m.group(1)
102         res = sam.search(expression="samaccountname=%s" % user,
103                             scope=ldb.SCOPE_SUBTREE,
104                             attrs=["servicePrincipalName"])
105         if len(res) >0:
106             res[0].dn
107             msg = ldb.Message()
108             spns = res[0].get("servicePrincipalName")
109             tab = []
110             found = False
111             flag = ldb.FLAG_MOD_ADD
112             if spns != None:
113                 for e in spns:
114                     if str(e) == name:
115                         found = True
116                     tab.append(str(e))
117                 flag = ldb.FLAG_MOD_REPLACE
118             tab.append(name)
119             msg.dn = res[0].dn
120             msg["servicePrincipalName"] = ldb.MessageElement(tab, flag,
121                                                 "servicePrincipalName")
122             if not found:
123                 sam.modify(msg)
124             else:
125                 print "Service principal %s already affected to %s" % (name, user)
126         else:
127             print "User %s not found" % user
128             sys.exit(1)
129
130
131 class cmd_spn_delete(Command):
132     """Delete a spn."""
133     synopsis = "%prog spn delete <name>"
134
135     takes_optiongroups = {
136         "sambaopts": options.SambaOptions,
137         "credopts": options.CredentialsOptions,
138         "versionopts": options.VersionOptions,
139         }
140
141     takes_args = ["name"]
142
143     def run(self, name, credopts=None, sambaopts=None, versionopts=None):
144         lp = sambaopts.get_loadparm()
145         creds = credopts.get_credentials(lp)
146         paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
147         sam = SamDB(paths.samdb, session_info=system_session(),
148                     credentials=creds, lp=lp)
149         res = sam.search(expression="servicePrincipalName=%s" % name,
150                             scope=ldb.SCOPE_SUBTREE,
151                             attrs=["servicePrincipalName"])
152         if len(res) >0:
153             res[0].dn
154             msg = ldb.Message()
155             spns = res[0].get("servicePrincipalName")
156             tab = []
157             if spns != None:
158                 for e in spns:
159                     if str(e) != name:
160                         tab.append(str(e))
161                 flag = ldb.FLAG_MOD_REPLACE
162             msg.dn = res[0].dn
163             msg["servicePrincipalName"] = ldb.MessageElement(tab, flag,
164                                             "servicePrincipalName")
165             sam.modify(msg)
166         else:
167             print "Service principal %s not affected" % name
168             sys.exit(1)
169
170 class cmd_spn(SuperCommand):
171     """User management [server connection needed]"""
172
173     subcommands = {}
174     subcommands["add"] = cmd_spn_add()
175     subcommands["list"] = cmd_spn_list()
176     subcommands["delete"] = cmd_spn_delete()
177