lib/async_req: remove the tevent_fd as early as possible via a wait_for_read_cleanup...
[Samba.git] / examples / logon / ntlogon / ntlogon.py
blobba46ba8ffcfe88f94a5172120cb9a2b6440deb49
1 #!/usr/bin/env python
2 """
3 ntlogon.py written by Timothy (rhacer) Grant
5 Copyright 1999 - 2002 by Timothy Grant
7 is distributed under the terms of the GNU Public License.
9 The format for the configuration file is as follows:
11 While there is some room for confusion, we attempt to process things in
12 order of specificity: Global first, Group second, User third, OS Type
13 forth. This order can be debated forever, but it seems to make the most
14 sense.
16 # Everything in the Global section applies to all users logging on to the
17 # network
18 [Global]
19 @ECHO "Welcome to our network!!!"
20 NET TIME \\\\servername /SET /YES
21 NET USE F: \\\\servername\\globalshare /YES
23 # Map the private user area in the global section so we don't have to
24 # create individual user entries for each user!
25 NET USE U: \\\\servername\\%U /YES
27 # Group entries, User entries and OS entries each start with the
28 # keyword followed by a dash followed by--appropriately enough the Group
29 # name, the User name, or the OS name.
30 [Group-admin]
31 @ECHO "Welcome administrators!"
32 NET USE G: \\\\servername\\adminshare1 /YES
33 NET USE I: \\\\servername\\adminshare2 /YES
35 [Group-peons]
36 @ECHO "Be grateful we let you use computers!"
37 NET USE G: \\\\servername\\peonshare1 /YES
39 [Group-hackers]
40 @ECHO "What can I do for you today great one?"
41 NET USE G: \\\\servername\\hackershare1 /YES
42 NET USE I: \\\\servername\\adminshare2 /YES
44 [User-fred]
45 @ECHO "Hello there Fred!"
46 NET USE F: \\\\servername\\fredsspecialshare /YES
48 [OS-WfWg]
49 @ECHO "Time to upgrade it?"
51 # End configuration file
53 usage: ntlogon [-g | --group=groupname]
54 [-u | --user=username]
55 [-o | --os=osname]
56 [-m | --machine=netbiosname]
57 [-f | --templatefile=filename]
58 [-d | --dir=netlogon directory]
59 [-v | --version]
60 [-h | --help]
61 [--pause]
62 [--debug]
63 """
65 #" This quote mark is an artifact of the inability of my editor to
66 # correctly colour code anything after the triple-quoted docstring.
67 # if your editor does not have this flaw, feel free to remove it.
70 import sys
71 import getopt
72 import re
73 import string
74 import os
76 version = "ntlogon.py v0.8"
78 def buildScript(buf, sections, group, user, ostype, machine, debug, pause):
79 """
80 buildScript() Takes the contents of the template file and builds
81 a DOS batch file to be executed as an NT logon script. It does this
82 by determining which sections of the configuration file should be included
83 and creating a list object that contains each line contained in each
84 included section. The list object is then returned to the calling
85 routine.
87 All comments (#) are removed. A REM is inserted to show
88 which section of the configuration file each line comes from.
89 We leave blanklines as they are sometimes useful for debugging
91 We also replace all of the Samba macros (e.g., %U, %G, %a, %m) with their
92 expanded versions which have been passed to us by smbd
93 """
94 hdrstring = ''
95 script = []
98 # These are the Samba macros that we currently know about.
99 # any user defined macros will also be added to this dictionary.
100 # We do not store the % sign as part of the macro name.
101 # The replace routine will prepend the % sign to all possible
102 # replacements.
104 macros = {
105 'U': user,
106 'G': group,
107 'a': ostype,
108 'm': machine
112 # Process each section defined in the list sections
114 for s in sections:
115 # print 'searching for: ' + s
117 idx = 0
119 while idx < len(buf):
120 ln = buf[idx]
123 # We need to set up a regex for each possible section we
124 # know about. This is slightly complicated due to the fact
125 # that section headers contain user defined text.
127 if s == 'Global':
128 hdrstring = '\[ *' + s + ' *\]'
129 elif s == 'Group':
130 hdrstring = '\[ *' + s + ' *- *' + group + ' *\]'
131 elif s == 'User':
132 hdrstring = '\[ *' + s + ' *- *' + user + ' *\]'
133 elif s == 'OS':
134 hdrstring = '\[ *' + s + ' *- *' + ostype + ' *\]'
135 elif s == 'Machine':
136 hdrstring = '\[ *' + s + ' *- *' + machine + ' *\]'
139 # See if we have found a section header
141 if re.search(r'(?i)' + hdrstring, ln):
142 idx = idx + 1 # increment the counter to move to the next
143 # line.
145 x = re.match(r'([^#\r\n]*)', ln) # Determine the section
146 # name and strip out CR/LF
147 # and comment information
149 if debug:
150 print 'rem ' + x.group(1) + ' commands'
151 else:
152 # create the rem at the beginning of each section of the
153 # logon script.
154 script.append('rem ' + x.group(1) + ' commands')
157 # process each line until we have found another section
158 # header
160 while not re.search(r'.*\[.*\].*', buf[idx]):
163 # strip comments and line endings
165 x = re.match(r'([^#\r\n]*)', buf[idx])
167 if string.strip(x.group(1)) != '' :
168 # if there is still content after stripping comments and
169 # line endings then this is a line to process
171 line = x.group(1)
174 # Check to see if this is a macro definition line
176 vardef = re.match(r'(.*)=(.*)', line)
178 if vardef:
179 varname = string.strip(vardef.group(1)) # Strip leading and
180 varsub = string.strip(vardef.group(2)) # and trailing spaces
182 if varname == '':
183 print "Error: No substition name specified line: %d" % idx
184 sys.exit(1)
186 if varsub == '':
187 print "Error: No substitution text provided line: %d" % idx
188 sys.exit(1)
190 if macros.has_key(varname):
191 print "Warning: macro %s redefined line: %d" % (varname, idx)
193 macros[varname] = varsub
194 idx = idx + 1
195 continue
198 # Replace all the macros that we currently
199 # know about.
201 # Iterate over the dictionary that contains all known
202 # macro substitutions.
204 # We test for a macro name by prepending % to each dictionary
205 # key.
207 for varname in macros.keys():
208 line = re.sub(r'%' + varname + r'(\W)',
209 macros[varname] + r'\1', line)
211 if debug:
212 print line
213 if pause:
214 print 'pause'
215 else:
216 script.append(line)
218 idx = idx + 1
220 if idx == len(buf):
221 break # if we have reached the end of the file
222 # stop processing.
224 idx = idx + 1 # increment the line counter
226 if debug:
227 print ''
228 else:
229 script.append('')
231 return script
233 # End buildScript()
235 def run():
237 run() everything starts here. The main routine reads the command line
238 arguments, opens and reads the configuration file.
240 configfile = '/etc/ntlogon.conf' # Default configuration file
241 group = '' # Default group
242 user = '' # Default user
243 ostype = '' # Default os
244 machine = '' # Default machine type
245 outfile = 'logon.bat' # Default batch file name
246 # this file name WILL take on the form
247 # username.bat if a username is specified
248 debug = 0 # Default debugging mode
249 pause = 0 # Default pause mode
250 outdir = '/usr/local/samba/netlogon/' # Default netlogon directory
252 sections = ['Global', 'Machine', 'OS', 'Group', 'User'] # Currently supported
253 # configuration file
254 # sections
256 options, args = getopt.getopt(sys.argv[1:], 'd:f:g:ho:u:m:v',
257 ['templatefile=',
258 'group=',
259 'help',
260 'os=',
261 'user=',
262 'machine=',
263 'dir=',
264 'version',
265 'pause',
266 'debug'])
269 # Process the command line arguments
271 for i in options:
272 # template file to process
273 if (i[0] == '-f') or (i[0] == '--templatefile'):
274 configfile = i[1]
275 # print 'configfile = ' + configfile
277 # define the group to be used
278 elif (i[0] == '-g') or (i[0] == '--group'):
279 group = i[1]
280 # print 'group = ' + group
282 # define the os type
283 elif (i[0] == '-o') or (i[0] == '--os'):
284 ostype = i[1]
285 # print 'os = ' + os
287 # define the user
288 elif (i[0] == '-u') or (i[0] == '--user'):
289 user = i[1]
290 outfile = user + '.bat' # Setup the output file name
291 # print 'user = ' + user
293 # define the machine
294 elif (i[0] == '-m') or (i[0] == '--machine'):
295 machine = i[1]
297 # define the netlogon directory
298 elif (i[0] == '-d') or (i[0] == '--dir'):
299 outdir = i[1]
300 # print 'outdir = ' + outdir
302 # if we are asked to turn on debug info, do so.
303 elif (i[0] == '--debug'):
304 debug = 1
305 # print 'debug = ' + debug
307 # if we are asked to turn on the automatic pause functionality, do so
308 elif (i[0] == '--pause'):
309 pause = 1
310 # print 'pause = ' + pause
312 # if we are asked for the version number, print it.
313 elif (i[0] == '-v') or (i[0] == '--version'):
314 print version
315 sys.exit(0)
317 # if we are asked for help print the docstring.
318 elif (i[0] == '-h') or (i[0] == '--help'):
319 print __doc__
320 sys.exit(0)
323 # open the configuration file
325 try:
326 iFile = open(configfile, 'r')
327 except IOError:
328 print 'Unable to open configuration file: ' + configfile
329 sys.exit(1)
333 # open the output file
335 if not debug:
336 try:
337 oFile = open(outdir + outfile, 'w')
338 except IOError:
339 print 'Unable to open logon script file: ' + outdir + outfile
340 sys.exit(1)
342 buf = iFile.readlines() # read in the entire configuration file
345 # call the script building routine
347 script = buildScript(buf, sections, group, user, ostype, machine, debug, pause)
350 # write out the script file
352 if not debug:
353 for ln in script:
354 oFile.write(ln + '\r\n')
355 if pause:
356 if string.strip(ln) != '': # Because whitespace
357 oFile.write('pause' + '\r\n') # is a useful tool, we
358 # don't put pauses after
359 # an empty line.
362 # End run()
365 # immediate-mode commands, for drag-and-drop or execfile() execution
367 if __name__ == '__main__':
368 run()
369 else:
370 print "Module ntlogon.py imported."
371 print "To run, type: ntlogon.run()"
372 print "To reload after changes to the source, type: reload(ntlogon)"
375 # End NTLogon.py