s4:scripting/python/modules.c - fix "asprintf" calls
[Samba/ekacnet.git] / source4 / scripting / bin / samba_spnupdate
blob1971ea1e869b5141ee81403da859698eccddfa16
1 #!/usr/bin/env python
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/>.
21 import os, sys
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")
30 import samba, ldb
31 import optparse
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")
42 creds = None
43 ccachename = None
45 opts, args = parser.parse_args()
47 if len(args) != 0:
48 parser.print_usage()
49 sys.exit(1)
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):
59 global lp
60 vars = {}
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
70 return vars
72 try:
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)
76 sys.exit(1)
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")
86 spn_list = []
88 # build the spn list
89 for line in file:
90 line = line.strip()
91 if line == '' or line[0] == "#":
92 continue
93 line = samba.substitute_var(line, sub_vars)
94 spn_list.append(line)
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'])
102 sys.exit(1)
104 old_spns = []
105 for s in res[0]['servicePrincipalName']:
106 old_spns.append(s)
108 if opts.verbose:
109 print("Existing SPNs: %s" % old_spns)
111 add_list = []
113 # work out what needs to be added
114 for s in spn_list:
115 in_list = False
116 for s2 in old_spns:
117 if s2.upper() == s.upper():
118 in_list = True
119 break
120 if not in_list:
121 add_list.append(s)
123 if opts.verbose:
124 print("New SPNs: %s" % add_list)
126 if add_list == []:
127 if opts.verbose:
128 print("Nothing to add")
129 sys.exit(0)
131 # build the modify request
132 msg = ldb.Message()
133 msg.dn = res[0]['dn']
134 msg[""] = ldb.MessageElement(add_list,
135 ldb.FLAG_MOD_ADD, "servicePrincipalName")
136 res = samdb.modify(msg)
137 sys.exit(0)