3 # update our servicePrincipalName names from spn_update_list
5 # Copyright (C) Andrew Tridgell 2010
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.
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.
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/>.
23 # ensure we get messages out immediately, so they get in the samba logs,
24 # and don't get swallowed by a timeout
25 os
.putenv('PYTHONUNBUFFERED', '1')
27 # Find right directory when running from source tree
28 sys
.path
.insert(0, "bin/python")
32 from samba
import getopt
as options
33 from samba
.auth
import system_session
34 from samba
.samdb
import SamDB
36 parser
= optparse
.OptionParser("samba_spnupdate")
37 sambaopts
= options
.SambaOptions(parser
)
38 parser
.add_option_group(sambaopts
)
39 parser
.add_option_group(options
.VersionOptions(parser
))
40 parser
.add_option("--verbose", action
="store_true")
45 opts
, args
= parser
.parse_args()
51 lp
= sambaopts
.get_loadparm()
53 domain
= lp
.get("realm")
54 host
= lp
.get("netbios name")
57 # get the list of substitution vars
58 def get_subst_vars(samdb
):
62 vars['DNSDOMAIN'] = lp
.get('realm').lower()
63 vars['HOSTNAME'] = lp
.get('netbios name').lower() + "." + vars['DNSDOMAIN']
64 vars['NETBIOSNAME'] = lp
.get('netbios name').upper()
65 vars['WORKGROUP'] = lp
.get('workgroup')
66 vars['NTDSGUID'] = samdb
.get_ntds_GUID()
67 res
= samdb
.search(base
=None, scope
=ldb
.SCOPE_BASE
, attrs
=["objectGUID"])
68 guid
= samdb
.schema_format_value("objectGUID", res
[0]['objectGUID'][0])
69 vars['DOMAINGUID'] = guid
73 samdb
= SamDB(url
=lp
.get("sam database"), session_info
=system_session(), lp
=lp
)
74 except ldb
.LdbError
, (num
, msg
):
75 print("Unable to open sam database %s : %s" % (lp
.get("sam database")), msg
)
78 # get the substitution dictionary
79 sub_vars
= get_subst_vars(samdb
)
81 # get the list of SPN entries we should have
82 spn_update_list
= lp
.private_path('spn_update_list')
84 file = open(spn_update_list
, "r")
91 if line
== '' or line
[0] == "#":
93 line
= samba
.substitute_var(line
, sub_vars
)
96 # get the current list of SPNs in our sam
97 res
= samdb
.search(base
="",
98 expression
='(&(objectClass=computer)(samaccountname=%s$))' % sub_vars
['NETBIOSNAME'],
99 attrs
=["servicePrincipalName"])
100 if not res
or len(res
) != 1:
101 print("Failed to find computer object for %s$" % sub_vars
['NETBIOSNAME'])
105 for s
in res
[0]['servicePrincipalName']:
109 print("Existing SPNs: %s" % old_spns
)
113 # work out what needs to be added
117 if s2
.upper() == s
.upper():
124 print("New SPNs: %s" % add_list
)
128 print("Nothing to add")
131 # build the modify request
133 msg
.dn
= res
[0]['dn']
134 msg
[""] = ldb
.MessageElement(add_list
,
135 ldb
.FLAG_MOD_ADD
, "servicePrincipalName")
136 res
= samdb
.modify(msg
)