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
import provision
22 from samba
.samdb
import SamDB
23 from samba
.auth
import system_session
24 from samba
.netcmd
.common
import _get_user_realm_domain
25 from samba
.netcmd
import (
33 class cmd_spn_list(Command
):
34 """List spns of a given user."""
36 synopsis
= "%prog <user> [options]"
38 takes_optiongroups
= {
39 "sambaopts": options
.SambaOptions
,
40 "credopts": options
.CredentialsOptions
,
41 "versionopts": options
.VersionOptions
,
46 def run(self
, user
, credopts
=None, sambaopts
=None, versionopts
=None):
47 lp
= sambaopts
.get_loadparm()
48 creds
= credopts
.get_credentials(lp
)
49 paths
= provision
.provision_paths_from_lp(lp
, lp
.get("realm"))
50 sam
= SamDB(paths
.samdb
, session_info
=system_session(),
51 credentials
=creds
, lp
=lp
)
52 # TODO once I understand how, use the domain info to naildown
53 # to the correct domain
54 (cleaneduser
, realm
, domain
) = _get_user_realm_domain(user
)
55 self
.outf
.write(cleaneduser
+"\n")
57 expression
="samaccountname=%s" % ldb
.binary_encode(cleaneduser
),
58 scope
=ldb
.SCOPE_SUBTREE
, attrs
=["servicePrincipalName"])
60 spns
= res
[0].get("servicePrincipalName")
62 flag
= ldb
.FLAG_MOD_ADD
65 "User %s has the following servicePrincipalName: \n" %
68 self
.outf
.write("\t %s\n" % e
)
70 self
.outf
.write("User %s has no servicePrincipalName" %
73 raise CommandError("User %s not found" % user
)
76 class cmd_spn_add(Command
):
77 """Create a new spn."""
79 synopsis
= "%prog <name> <user> [options]"
81 takes_optiongroups
= {
82 "sambaopts": options
.SambaOptions
,
83 "credopts": options
.CredentialsOptions
,
84 "versionopts": options
.VersionOptions
,
87 Option("--force", help="Force the addition of the spn"
88 " even it exists already", action
="store_true"),
90 takes_args
= ["name", "user"]
92 def run(self
, name
, user
, force
=False, credopts
=None, sambaopts
=None,
94 lp
= sambaopts
.get_loadparm()
95 creds
= credopts
.get_credentials(lp
)
96 paths
= provision
.provision_paths_from_lp(lp
, lp
.get("realm"))
97 sam
= SamDB(paths
.samdb
, session_info
=system_session(),
98 credentials
=creds
, lp
=lp
)
100 expression
="servicePrincipalName=%s" % ldb
.binary_encode(name
),
101 scope
=ldb
.SCOPE_SUBTREE
)
102 if len(res
) != 0 and not force
:
103 raise CommandError("Service principal %s already"
104 " affected to another user" % name
)
106 (cleaneduser
, realm
, domain
) = _get_user_realm_domain(user
)
108 expression
="samaccountname=%s" % ldb
.binary_encode(cleaneduser
),
109 scope
=ldb
.SCOPE_SUBTREE
, attrs
=["servicePrincipalName"])
113 spns
= res
[0].get("servicePrincipalName")
116 flag
= ldb
.FLAG_MOD_ADD
122 flag
= ldb
.FLAG_MOD_REPLACE
125 msg
["servicePrincipalName"] = ldb
.MessageElement(tab
, flag
,
126 "servicePrincipalName")
130 raise CommandError("Service principal %s already"
131 " affected to %s" % (name
, user
))
133 raise CommandError("User %s not found" % user
)
136 class cmd_spn_delete(Command
):
139 synopsis
= "%prog <name> [user] [options]"
141 takes_optiongroups
= {
142 "sambaopts": options
.SambaOptions
,
143 "credopts": options
.CredentialsOptions
,
144 "versionopts": options
.VersionOptions
,
147 takes_args
= ["name", "user?"]
149 def run(self
, name
, user
=None, credopts
=None, sambaopts
=None,
151 lp
= sambaopts
.get_loadparm()
152 creds
= credopts
.get_credentials(lp
)
153 paths
= provision
.provision_paths_from_lp(lp
, lp
.get("realm"))
154 sam
= SamDB(paths
.samdb
, session_info
=system_session(),
155 credentials
=creds
, lp
=lp
)
157 expression
="servicePrincipalName=%s" % ldb
.binary_encode(name
),
158 scope
=ldb
.SCOPE_SUBTREE
,
159 attrs
=["servicePrincipalName", "samAccountName"])
163 (cleaneduser
, realm
, domain
) = _get_user_realm_domain(user
)
165 if str(elem
["samAccountName"]).lower() == cleaneduser
:
168 raise CommandError("Unable to find user %s with"
169 " spn %s" % (user
, name
))
174 listUser
= "%s\n%s" % (listUser
, str(r
.dn
))
175 raise CommandError("More than one user has the spn %s "
176 "and no specific user was specified, list of users"
177 " with this spn:%s" % (name
, listUser
))
183 spns
= result
.get("servicePrincipalName")
189 flag
= ldb
.FLAG_MOD_REPLACE
191 msg
["servicePrincipalName"] = ldb
.MessageElement(tab
, flag
,
192 "servicePrincipalName")
195 raise CommandError("Service principal %s not affected" % name
)
198 class cmd_spn(SuperCommand
):
199 """Service Principal Name (SPN) management."""
202 subcommands
["add"] = cmd_spn_add()
203 subcommands
["list"] = cmd_spn_list()
204 subcommands
["delete"] = cmd_spn_delete()