5 # Copyright Matthieu Patou mat@samba.org 2010
6 # Copyright Giampaolo Lauria 2011 <lauria2@yahoo.com>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 import samba
.getopt
as options
24 from samba
import provision
25 from samba
.samdb
import SamDB
26 from samba
.auth
import system_session
27 from samba
.netcmd
.common
import _get_user_realm_domain
28 from samba
.netcmd
import (
36 class cmd_spn_list(Command
):
37 """List spns of a given user."""
39 synopsis
= "%prog <user> [options]"
43 def run(self
, user
, credopts
=None, sambaopts
=None, versionopts
=None):
44 lp
= sambaopts
.get_loadparm()
45 creds
= credopts
.get_credentials(lp
)
46 paths
= provision
.provision_paths_from_lp(lp
, lp
.get("realm"))
47 sam
= SamDB(paths
.samdb
, session_info
=system_session(),
48 credentials
=creds
, lp
=lp
)
49 # TODO once I understand how, use the domain info to naildown
50 # to the correct domain
51 (cleaneduser
, realm
, domain
) = _get_user_realm_domain(user
)
52 self
.outf
.write(cleaneduser
+"\n")
53 res
= sam
.search(expression
="samaccountname=%s" % ldb
.binary_encode(cleaneduser
),
54 scope
=ldb
.SCOPE_SUBTREE
,
55 attrs
=["servicePrincipalName"])
57 spns
= res
[0].get("servicePrincipalName")
59 flag
= ldb
.FLAG_MOD_ADD
62 "User %s has the following servicePrincipalName: \n" %
65 self
.outf
.write("\t %s\n" % e
)
67 self
.outf
.write("User %s has no servicePrincipalName" %
70 raise CommandError("User %s not found" % user
)
73 class cmd_spn_add(Command
):
74 """Create a new spn."""
76 synopsis
= "%prog <name> <user> [options]"
79 Option("--force", help="Force the addition of the spn"\
80 " even it exists already", action
="store_true"),
82 takes_args
= ["name", "user"]
84 def run(self
, name
, user
, force
=False, credopts
=None, sambaopts
=None, versionopts
=None):
85 lp
= sambaopts
.get_loadparm()
86 creds
= credopts
.get_credentials(lp
)
87 paths
= provision
.provision_paths_from_lp(lp
, lp
.get("realm"))
88 sam
= SamDB(paths
.samdb
, session_info
=system_session(),
89 credentials
=creds
, lp
=lp
)
90 res
= sam
.search(expression
="servicePrincipalName=%s" % ldb
.binary_encode(name
),
91 scope
=ldb
.SCOPE_SUBTREE
,
93 if len(res
) != 0 and not force
:
94 raise CommandError("Service principal %s already"
95 " affected to another user" % name
)
97 (cleaneduser
, realm
, domain
) = _get_user_realm_domain(user
)
98 res
= sam
.search(expression
="samaccountname=%s" % ldb
.binary_encode(cleaneduser
),
99 scope
=ldb
.SCOPE_SUBTREE
,
100 attrs
=["servicePrincipalName"])
104 spns
= res
[0].get("servicePrincipalName")
107 flag
= ldb
.FLAG_MOD_ADD
113 flag
= ldb
.FLAG_MOD_REPLACE
116 msg
["servicePrincipalName"] = ldb
.MessageElement(tab
, flag
,
117 "servicePrincipalName")
121 raise CommandError("Service principal %s already"
122 " affected to %s" % (name
, user
))
124 raise CommandError("User %s not found" % user
)
127 class cmd_spn_delete(Command
):
130 synopsis
= "%prog <name> [user] [options]"
132 takes_args
= ["name", "user?"]
134 def run(self
, name
, user
=None, credopts
=None, sambaopts
=None, versionopts
=None):
135 lp
= sambaopts
.get_loadparm()
136 creds
= credopts
.get_credentials(lp
)
137 paths
= provision
.provision_paths_from_lp(lp
, lp
.get("realm"))
138 sam
= SamDB(paths
.samdb
, session_info
=system_session(),
139 credentials
=creds
, lp
=lp
)
140 res
= sam
.search(expression
="servicePrincipalName=%s" % ldb
.binary_encode(name
),
141 scope
=ldb
.SCOPE_SUBTREE
,
142 attrs
=["servicePrincipalName", "samAccountName"])
146 (cleaneduser
, realm
, domain
) = _get_user_realm_domain(user
)
148 if str(elem
["samAccountName"]).lower() == cleaneduser
:
151 raise CommandError("Unable to find user %s with"
152 " spn %s" % (user
, name
))
157 listUser
= "%s\n%s" % (listUser
, str(r
.dn
))
158 raise CommandError("More than one user has the spn %s "\
159 "and no specific user was specified, list of users"\
160 " with this spn:%s" % (name
, listUser
))
166 spns
= result
.get("servicePrincipalName")
172 flag
= ldb
.FLAG_MOD_REPLACE
174 msg
["servicePrincipalName"] = ldb
.MessageElement(tab
, flag
,
175 "servicePrincipalName")
178 raise CommandError("Service principal %s not affected" % name
)
181 class cmd_spn(SuperCommand
):
182 """Service Principal Name (SPN) management"""
185 subcommands
["add"] = cmd_spn_add()
186 subcommands
["list"] = cmd_spn_list()
187 subcommands
["delete"] = cmd_spn_delete()