3 # Copyright Matthieu Patou mat@samba.org 2010
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 import samba
.getopt
as options
21 from samba
.samdb
import SamDB
22 from samba
.auth
import system_session
23 from samba
.netcmd
.common
import _get_user_realm_domain
24 from samba
.netcmd
import (
32 class cmd_spn_list(Command
):
33 """List spns of a given user."""
35 synopsis
= "%prog <user> [options]"
37 takes_optiongroups
= {
38 "sambaopts": options
.SambaOptions
,
39 "credopts": options
.CredentialsOptions
,
40 "versionopts": options
.VersionOptions
,
43 Option("-H", "--URL", help="LDB URL for database or target server",
44 type=str, metavar
="URL", dest
="H"),
49 def run(self
, user
, H
=None,
53 lp
= sambaopts
.get_loadparm()
54 creds
= credopts
.get_credentials(lp
)
55 sam
= SamDB(H
, session_info
=system_session(),
56 credentials
=creds
, lp
=lp
)
57 # TODO once I understand how, use the domain info to naildown
58 # to the correct domain
59 (cleaneduser
, realm
, domain
) = _get_user_realm_domain(user
, sam
)
60 self
.outf
.write(cleaneduser
+ "\n")
62 expression
="samaccountname=%s" % ldb
.binary_encode(cleaneduser
),
63 scope
=ldb
.SCOPE_SUBTREE
, attrs
=["servicePrincipalName"])
65 spns
= res
[0].get("servicePrincipalName")
68 "User %s has the following servicePrincipalName: \n" %
71 self
.outf
.write("\t %s\n" % e
)
73 self
.outf
.write("User %s has no servicePrincipalName\n" %
76 raise CommandError("User %s not found" % user
)
79 class cmd_spn_add(Command
):
80 """Create a new spn."""
82 synopsis
= "%prog <name> <user> [options]"
84 takes_optiongroups
= {
85 "sambaopts": options
.SambaOptions
,
86 "credopts": options
.CredentialsOptions
,
87 "versionopts": options
.VersionOptions
,
90 Option("-H", "--URL", help="LDB URL for database or target server",
91 type=str, metavar
="URL", dest
="H"),
93 takes_args
= ["name", "user"]
95 def run(self
, name
, user
, H
=None,
99 lp
= sambaopts
.get_loadparm()
100 creds
= credopts
.get_credentials(lp
)
101 sam
= SamDB(H
, session_info
=system_session(),
102 credentials
=creds
, lp
=lp
)
104 expression
="servicePrincipalName=%s" % ldb
.binary_encode(name
),
105 scope
=ldb
.SCOPE_SUBTREE
)
107 raise CommandError("Service principal %s already"
108 " affected to another user" % name
)
110 (cleaneduser
, realm
, domain
) = _get_user_realm_domain(user
, sam
)
112 expression
="samaccountname=%s" % ldb
.binary_encode(cleaneduser
),
113 scope
=ldb
.SCOPE_SUBTREE
, attrs
=["servicePrincipalName"])
117 spns
= res
[0].get("servicePrincipalName")
120 flag
= ldb
.FLAG_MOD_ADD
126 flag
= ldb
.FLAG_MOD_REPLACE
129 msg
["servicePrincipalName"] = ldb
.MessageElement(tab
, flag
,
130 "servicePrincipalName")
134 raise CommandError("Service principal %s already"
135 " affected to %s" % (name
, user
))
137 raise CommandError("User %s not found" % user
)
140 class cmd_spn_delete(Command
):
143 synopsis
= "%prog <name> [user] [options]"
145 takes_optiongroups
= {
146 "sambaopts": options
.SambaOptions
,
147 "credopts": options
.CredentialsOptions
,
148 "versionopts": options
.VersionOptions
,
151 Option("-H", "--URL", help="LDB URL for database or target server",
152 type=str, metavar
="URL", dest
="H"),
155 takes_args
= ["name", "user?"]
157 def run(self
, name
, user
=None, H
=None, credopts
=None, sambaopts
=None,
159 lp
= sambaopts
.get_loadparm()
160 creds
= credopts
.get_credentials(lp
)
161 sam
= SamDB(H
, session_info
=system_session(),
162 credentials
=creds
, lp
=lp
)
164 expression
="servicePrincipalName=%s" % ldb
.binary_encode(name
),
165 scope
=ldb
.SCOPE_SUBTREE
,
166 attrs
=["servicePrincipalName", "samAccountName"])
170 (cleaneduser
, realm
, domain
) = _get_user_realm_domain(user
)
172 if str(elem
["samAccountName"]).lower() == cleaneduser
:
175 raise CommandError("Unable to find user %s with"
176 " spn %s" % (user
, name
))
181 listUser
= "%s\n%s" % (listUser
, str(r
.dn
))
182 raise CommandError("More than one user has the spn %s "
183 "and no specific user was specified, list of users"
184 " with this spn:%s" % (name
, listUser
))
189 spns
= result
.get("servicePrincipalName")
195 flag
= ldb
.FLAG_MOD_REPLACE
197 msg
["servicePrincipalName"] = ldb
.MessageElement(tab
, flag
,
198 "servicePrincipalName")
201 raise CommandError("Service principal %s not affected" % name
)
204 class cmd_spn(SuperCommand
):
205 """Service Principal Name (SPN) management."""
208 subcommands
["add"] = cmd_spn_add()
209 subcommands
["list"] = cmd_spn_list()
210 subcommands
["delete"] = cmd_spn_delete()