5
def ResizeBufferCall(fn, pipe, r):
12
if result['result'] == dcerpc.WERR_INSUFFICIENT_BUFFER or \
13
result['result'] == dcerpc.WERR_MORE_DATA:
14
r['buffer'] = result['buf_size'] * '\x00'
15
r['buf_size'] = result['buf_size']
22
def test_OpenPrinterEx(pipe, printer):
24
print 'spoolss_OpenPrinterEx(%s)' % printer
26
printername = '\\\\%s' % dcerpc.dcerpc_server_name(pipe)
28
if printer is not None:
29
printername = printername + '\\%s' % printer
32
r['printername'] = printername
35
r['devmode_ctr']['size'] = 0
36
r['devmode_ctr']['devmode'] = None
37
r['access_mask'] = 0x02000000
40
r['userlevel']['level1'] = {}
41
r['userlevel']['level1']['size'] = 0
42
r['userlevel']['level1']['client'] = None
43
r['userlevel']['level1']['user'] = None
44
r['userlevel']['level1']['build'] = 1381
45
r['userlevel']['level1']['major'] = 2
46
r['userlevel']['level1']['minor'] = 0
47
r['userlevel']['level1']['processor'] = 0
49
result = dcerpc.spoolss_OpenPrinterEx(pipe, r)
51
return result['handle']
54
def test_ClosePrinter(pipe, handle):
59
dcerpc.spoolss_ClosePrinter(pipe, r)
62
def test_GetPrinter(pipe, handle):
67
for level in [0, 1, 2, 3, 4, 5, 6, 7]:
69
print 'spoolss_GetPrinter(level = %d)' % level
75
result = ResizeBufferCall(dcerpc.spoolss_GetPrinter, pipe, r)
78
def test_EnumForms(pipe, handle):
80
print 'spoolss_EnumForms()'
88
result = ResizeBufferCall(dcerpc.spoolss_EnumForms, pipe, r)
90
forms = dcerpc.unmarshall_spoolss_FormInfo_array(
91
result['buffer'], r['level'], result['count'])
97
r['formname'] = form['info1']['formname']
100
result = ResizeBufferCall(dcerpc.spoolss_GetForm, pipe, r)
103
def test_EnumPorts(pipe, handle):
105
print 'spoolss_EnumPorts()'
111
r['servername'] = None
114
result = ResizeBufferCall(dcerpc.spoolss_EnumPorts, pipe, r)
116
ports = dcerpc.unmarshall_spoolss_PortInfo_array(
117
result['buffer'], r['level'], result['count'])
120
port_names = map(lambda x: x['info1']['port_name'], ports)
123
def test_DeleteForm(pipe, handle, formname):
127
r['formname'] = formname
129
dcerpc.spoolss_DeleteForm(pipe, r)
132
def test_GetForm(pipe, handle, formname):
136
r['formname'] = formname
139
result = ResizeBufferCall(dcerpc.spoolss_GetForm, pipe, r)
141
return result['info']['info1']
144
def test_SetForm(pipe, handle, form):
146
print 'spoolss_SetForm()'
151
r['formname'] = form['info1']['formname']
154
dcerpc.spoolss_SetForm(pipe, r)
156
newform = test_GetForm(pipe, handle, r['formname'])
158
if form['info1'] != newform:
159
print 'SetForm: mismatch: %s != %s' % \
160
(r['info']['info1'], f)
164
def test_AddForm(pipe, handle):
166
print 'spoolss_AddForm()'
168
formname = '__testform__'
174
r['info']['info1'] = {}
175
r['info']['info1']['formname'] = formname
176
r['info']['info1']['flags'] = 0x0002
177
r['info']['info1']['width'] = 100
178
r['info']['info1']['length'] = 100
179
r['info']['info1']['left'] = 0
180
r['info']['info1']['top'] = 1000
181
r['info']['info1']['right'] = 2000
182
r['info']['info1']['bottom'] = 3000
185
result = dcerpc.spoolss_AddForm(pipe, r)
186
except dcerpc.WERROR, arg:
187
if arg[0] == dcerpc.WERR_ALREADY_EXISTS:
188
test_DeleteForm(pipe, handle, formname)
189
result = dcerpc.spoolss_AddForm(pipe, r)
191
f = test_GetForm(pipe, handle, formname)
193
if r['info']['info1'] != f:
194
print 'AddForm: mismatch: %s != %s' % \
195
(r['info']['info1'], f)
198
r['formname'] = formname
200
test_SetForm(pipe, handle, r['info'])
202
test_DeleteForm(pipe, handle, formname)
205
def test_EnumJobs(pipe, handle):
207
print 'spoolss_EnumJobs()'
212
r['numjobs'] = 0xffffffff
215
result = ResizeBufferCall(dcerpc.spoolss_EnumJobs, pipe, r)
217
if result['buffer'] is None:
220
jobs = dcerpc.unmarshall_spoolss_JobInfo_array(
221
result['buffer'], r['level'], result['count'])
227
s['job_id'] = job['info1']['job_id']
230
result = ResizeBufferCall(dcerpc.spoolss_GetJob, pipe, s)
232
if result['info'] != job:
233
print 'EnumJobs: mismatch: %s != %s' % (result['info'], job)
237
# TODO: AddJob, DeleteJob, ScheduleJob
240
def test_EnumPrinterData(pipe, handle):
242
print 'test_EnumPrinterData()'
250
r['enum_index'] = enum_index
252
r['value_offered'] = 0
255
result = dcerpc.spoolss_EnumPrinterData(pipe, r)
257
r['value_offered'] = result['value_needed']
258
r['data_size'] = result['data_size']
260
result = dcerpc.spoolss_EnumPrinterData(pipe, r)
262
if result['result'] == dcerpc.WERR_NO_MORE_ITEMS:
267
s['value_name'] = result['value_name']
269
result2 = ResizeBufferCall(dcerpc.spoolss_GetPrinterData, pipe, s)
271
if result['buffer'][:result2['buf_size']] != result2['buffer']:
272
print 'EnumPrinterData/GetPrinterData mismatch'
278
def test_SetPrinterDataEx(pipe, handle):
280
valuename = '__printerdataextest__'
285
r['key_name'] = 'DsSpooler'
286
r['value_name'] = valuename
289
r['buf_size'] = len(data)
291
result = dcerpc.spoolss_SetPrinterDataEx(pipe, r)
294
def test_EnumPrinterDataEx(pipe, handle):
298
r['key_name'] = 'DsSpooler'
301
result = dcerpc.spoolss_EnumPrinterDataEx(pipe, r)
303
if result['result'] == dcerpc.WERR_MORE_DATA:
304
r['buf_size'] = result['buf_size']
306
result = dcerpc.spoolss_EnumPrinterDataEx(pipe, r)
308
# TODO: test spoolss_GetPrinterDataEx()
311
def test_SetPrinterData(pipe, handle):
313
print 'testing spoolss_SetPrinterData()'
315
valuename = '__printerdatatest__'
320
r['value_name'] = valuename
321
r['type'] = 3 # REG_BINARY
325
dcerpc.spoolss_SetPrinterData(pipe, r)
329
s['value_name'] = valuename
331
result = ResizeBufferCall(dcerpc.spoolss_GetPrinterData, pipe, r)
333
if result['buffer'] != data:
334
print 'SetPrinterData: mismatch'
337
dcerpc.spoolss_DeletePrinterData(pipe, r)
340
def test_EnumPrinters(pipe):
342
print 'testing spoolss_EnumPrinters()'
350
for level in [0, 1, 2, 4, 5]:
352
print 'test_EnumPrinters(level = %d)' % level
356
result = ResizeBufferCall(dcerpc.spoolss_EnumPrinters, pipe, r)
358
printers = dcerpc.unmarshall_spoolss_PrinterInfo_array(
359
result['buffer'], r['level'], result['count'])
364
# A nice check is for the specversion in the
365
# devicemode. This has always been observed to be
368
if p['info2']['devmode']['specversion'] != 1025:
369
print 'test_EnumPrinters: specversion != 1025'
373
result = ResizeBufferCall(dcerpc.spoolss_EnumPrinters, pipe, r)
375
for printer in dcerpc.unmarshall_spoolss_PrinterInfo_array(
376
result['buffer'], r['level'], result['count']):
378
if string.find(printer['info1']['name'], '\\\\') == 0:
379
print 'Skipping remote printer %s' % printer['info1']['name']
382
printername = string.split(printer['info1']['name'], ',')[0]
384
handle = test_OpenPrinterEx(pipe, printername)
386
test_GetPrinter(pipe, handle)
387
test_EnumPorts(pipe, handle)
388
test_EnumForms(pipe, handle)
389
test_AddForm(pipe, handle)
390
test_EnumJobs(pipe, handle)
391
test_EnumPrinterData(pipe, handle)
392
test_EnumPrinterDataEx(pipe, handle)
393
test_SetPrinterData(pipe, handle)
394
# test_SetPrinterDataEx(pipe, handle)
395
test_ClosePrinter(pipe, handle)
398
def test_EnumPrinterDrivers(pipe):
400
print 'test spoolss_EnumPrinterDrivers()'
402
for level in [1, 2, 3]:
406
r['environment'] = None
409
result = ResizeBufferCall(dcerpc.spoolss_EnumPrinterDrivers, pipe, r)
411
drivers = dcerpc.unmarshall_spoolss_DriverInfo_array(
412
result['buffer'], r['level'], result['count'])
415
driver_names = map(lambda x: x['info1']['driver_name'], drivers)
418
def test_PrintServer(pipe):
420
handle = test_OpenPrinterEx(pipe, None)
422
# EnumForms and AddForm tests return WERR_BADFID here (??)
424
test_ClosePrinter(pipe, handle)
427
def runtests(binding, domain, username, password):
429
print 'Testing SPOOLSS pipe'
431
pipe = dcerpc.pipe_connect(binding,
432
dcerpc.DCERPC_SPOOLSS_UUID, dcerpc.DCERPC_SPOOLSS_VERSION,
433
domain, username, password)
435
test_EnumPrinters(pipe)
436
test_EnumPrinterDrivers(pipe)
437
test_PrintServer(pipe)