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
)