Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/par.py: 68%

# Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/par.py : 68%

## 256 statements

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1# Impacket - Collection of Python classes for working with network protocols.

2#

3# SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved.

4#

5# This software is provided under a slightly modified version

6# of the Apache Software License. See the accompanying LICENSE file

7# for more information.

8#

9# Description:

10# [MS-PAR] Interface implementation

11# https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-par

12#

13# Best way to learn how to use these calls is to grab the protocol standard

14# so you understand what the call does, and then read the test case located

15# at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC

16#

17# Some calls have helper functions, which makes it even easier to use.

18# They are located at the end of this file.

19# Helper functions start with "h"<name of the call>.

20# There are test cases for them too.

21#

22# Author:

23# Adam (@cube0x0)

24#

25 from impacket import system_errors

26 from impacket.dcerpc.v5.dtypes import ULONGLONG, UINT, USHORT, LPWSTR, DWORD, ULONG, NULL

27 from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRUNION, NDRPOINTER, NDRUniConformantArray

28 from impacket.dcerpc.v5.rpcrt import DCERPCException

29 from impacket.uuid import uuidtup_to_bin, string_to_bin

30

31 MSRPC_UUID_PAR = uuidtup_to_bin(('76F03F96-CDFD-44FC-A22C-64950A001209', '1.0'))

32 MSRPC_UUID_WINSPOOL = string_to_bin('9940CA8E-512F-4C58-88A9-61098D6896BD')

33

34 class DCERPCSessionError(DCERPCException):

35 def __init__(self, error_string=None, error_code=None, packet=None):

36 DCERPCException.__init__(self, error_string, error_code, packet)

37

38 def __str__( self ):

39 key = self.error_code

40 if key in system_errors.ERROR_MESSAGES:

41 error_msg_short = system_errors.ERROR_MESSAGES[key][0]

42 error_msg_verbose = system_errors.ERROR_MESSAGES[key][1]

43 return 'RPRN SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)

44 else:

45 return 'RPRN SessionError: unknown error code: 0x%x' % self.error_code

46

47################################################################################

48# CONSTANTS

49################################################################################

50# 2.2.1.1.7 STRING_HANDLE

51 STRING_HANDLE = LPWSTR

52 class PSTRING_HANDLE(NDRPOINTER):

53 referent = (

54 ('Data', STRING_HANDLE),

55 )

56

57# 2.2.3.1 Access Values

58 JOB_ACCESS_ADMINISTER = 0x00000010

59 JOB_ACCESS_READ = 0x00000020

60 JOB_EXECUTE = 0x00020010

61 JOB_READ = 0x00020020

62 JOB_WRITE = 0x00020010

63 JOB_ALL_ACCESS = 0x000F0030

64 PRINTER_ACCESS_ADMINISTER = 0x00000004

65 PRINTER_ACCESS_USE = 0x00000008

66 PRINTER_ACCESS_MANAGE_LIMITED = 0x00000040

67 PRINTER_ALL_ACCESS = 0x000F000C

68 PRINTER_EXECUTE = 0x00020008

69 PRINTER_READ = 0x00020008

70 PRINTER_WRITE = 0x00020008

71 SERVER_ACCESS_ADMINISTER = 0x00000001

72 SERVER_ACCESS_ENUMERATE = 0x00000002

73 SERVER_ALL_ACCESS = 0x000F0003

74 SERVER_EXECUTE = 0x00020002

75 SERVER_READ = 0x00020002

76 SERVER_WRITE = 0x00020003

77 SPECIFIC_RIGHTS_ALL = 0x0000FFFF

78 STANDARD_RIGHTS_ALL = 0x001F0000

79 STANDARD_RIGHTS_EXECUTE = 0x00020000

80 STANDARD_RIGHTS_READ = 0x00020000

81 STANDARD_RIGHTS_REQUIRED = 0x000F0000

82 STANDARD_RIGHTS_WRITE = 0x00020000

83 SYNCHRONIZE = 0x00100000

84 DELETE = 0x00010000

85 READ_CONTROL = 0x00020000

86 WRITE_DAC = 0x00040000

87 WRITE_OWNER = 0x00080000

88 GENERIC_READ = 0x80000000

89 GENERIC_WRITE = 0x40000000

90 GENERIC_EXECUTE = 0x20000000

91 GENERIC_ALL = 0x10000000

92

93# 2.2.3.6.1 Printer Change Flags for Use with a Printer Handle

94 PRINTER_CHANGE_SET_PRINTER = 0x00000002

95 PRINTER_CHANGE_DELETE_PRINTER = 0x00000004

96 PRINTER_CHANGE_PRINTER = 0x000000FF

97 PRINTER_CHANGE_ADD_JOB = 0x00000100

98 PRINTER_CHANGE_SET_JOB = 0x00000200

99 PRINTER_CHANGE_DELETE_JOB = 0x00000400

100 PRINTER_CHANGE_WRITE_JOB = 0x00000800

101 PRINTER_CHANGE_JOB = 0x0000FF00

102 PRINTER_CHANGE_SET_PRINTER_DRIVER = 0x20000000

103 PRINTER_CHANGE_TIMEOUT = 0x80000000

104 PRINTER_CHANGE_ALL = 0x7777FFFF

105 PRINTER_CHANGE_ALL_2 = 0x7F77FFFF

106

107# 2.2.3.6.2 Printer Change Flags for Use with a Server Handle

108 PRINTER_CHANGE_ADD_PRINTER_DRIVER = 0x10000000

109 PRINTER_CHANGE_DELETE_PRINTER_DRIVER = 0x40000000

110 PRINTER_CHANGE_PRINTER_DRIVER = 0x70000000

111 PRINTER_CHANGE_ADD_FORM = 0x00010000

112 PRINTER_CHANGE_DELETE_FORM = 0x00040000

113 PRINTER_CHANGE_SET_FORM = 0x00020000

114 PRINTER_CHANGE_FORM = 0x00070000

115 PRINTER_CHANGE_ADD_PORT = 0x00100000

116 PRINTER_CHANGE_CONFIGURE_PORT = 0x00200000

117 PRINTER_CHANGE_DELETE_PORT = 0x00400000

118 PRINTER_CHANGE_PORT = 0x00700000

119 PRINTER_CHANGE_ADD_PRINT_PROCESSOR = 0x01000000

120 PRINTER_CHANGE_DELETE_PRINT_PROCESSOR = 0x04000000

121 PRINTER_CHANGE_PRINT_PROCESSOR = 0x07000000

122 PRINTER_CHANGE_ADD_PRINTER = 0x00000001

123 PRINTER_CHANGE_FAILED_CONNECTION_PRINTER = 0x00000008

124 PRINTER_CHANGE_SERVER = 0x08000000

125

126# 2.2.3.7 Printer Enumeration Flags

127 PRINTER_ENUM_LOCAL = 0x00000002

128 PRINTER_ENUM_CONNECTIONS = 0x00000004

129 PRINTER_ENUM_NAME = 0x00000008

130 PRINTER_ENUM_REMOTE = 0x00000010

131 PRINTER_ENUM_SHARED = 0x00000020

132 PRINTER_ENUM_NETWORK = 0x00000040

133 PRINTER_ENUM_EXPAND = 0x00004000

134 PRINTER_ENUM_CONTAINER = 0x00008000

135 PRINTER_ENUM_ICON1 = 0x00010000

136 PRINTER_ENUM_ICON2 = 0x00020000

137 PRINTER_ENUM_ICON3 = 0x00040000

138 PRINTER_ENUM_ICON8 = 0x00800000

139 PRINTER_ENUM_HIDE = 0x01000000

140

141

142# 2.2.3.8 Printer Notification Values

143 PRINTER_NOTIFY_CATEGORY_2D = 0x00000000

144 PRINTER_NOTIFY_CATEGORY_ALL = 0x00010000

145 PRINTER_NOTIFY_CATEGORY_3D = 0x00020000

146

147

148# 3.1.4.4.8 RpcAddPrinterDriverEx Values

149 APD_STRICT_UPGRADE = 0x00000001

150 APD_STRICT_DOWNGRADE = 0x00000002

151 APD_COPY_ALL_FILES = 0x00000004

152 APD_COPY_NEW_FILES = 0x00000008

153 APD_COPY_FROM_DIRECTORY = 0x00000010

154 APD_DONT_COPY_FILES_TO_CLUSTER = 0x00001000

155 APD_COPY_TO_ALL_SPOOLERS = 0x00002000

156 APD_INSTALL_WARNED_DRIVER = 0x00008000

157 APD_RETURN_BLOCKING_STATUS_CODE = 0x00010000

158

159################################################################################

160# STRUCTURES

161################################################################################

162# 2.2.1.1.4 PRINTER_HANDLE

163 class PRINTER_HANDLE(NDRSTRUCT):

164 structure = (

165 ('Data','20s=b""'),

166 )

167 def getAlignment(self):

168 if self._isNDR64 is True:

169 return 8

170 else:

171 return 4

172

173# 2.2.1.2.1 DEVMODE_CONTAINER

174 class BYTE_ARRAY(NDRUniConformantArray):

175 item = 'c'

176

177 class PBYTE_ARRAY(NDRPOINTER):

178 referent = (

179 ('Data', BYTE_ARRAY),

180 )

181

182 class DEVMODE_CONTAINER(NDRSTRUCT):

183 structure = (

184 ('cbBuf',DWORD),

185 ('pDevMode',PBYTE_ARRAY),

186 )

187

188# 2.2.1.11.1 SPLCLIENT_INFO_1

189 class SPLCLIENT_INFO_1(NDRSTRUCT):

190 structure = (

191 ('dwSize',DWORD),

192 ('pMachineName',LPWSTR),

193 ('pUserName',LPWSTR),

194 ('dwBuildNum',DWORD),

195 ('dwMajorVersion',DWORD),

196 ('dwMinorVersion',DWORD),

197 ('wProcessorArchitecture',USHORT),

198 )

199

200 class PSPLCLIENT_INFO_1(NDRPOINTER):

201 referent = (

202 ('Data', SPLCLIENT_INFO_1),

203 )

204

205# 2.2.1.11.2 SPLCLIENT_INFO_2

206 class SPLCLIENT_INFO_2(NDRSTRUCT):

207 structure = (

208 ('notUsed',ULONGLONG),

209 )

210

211 class PSPLCLIENT_INFO_2(NDRPOINTER):

212 referent = (

213 ('Data', SPLCLIENT_INFO_2),

214 )

215# 2.2.1.11.3 SPLCLIENT_INFO_3

216 class SPLCLIENT_INFO_3(NDRSTRUCT):

217 structure = (

218 ('cbSize',UINT),

219 ('dwFlags',DWORD),

220 ('dwFlags',DWORD),

221 ('pMachineName',LPWSTR),

222 ('pUserName',LPWSTR),

223 ('dwBuildNum',DWORD),

224 ('dwMajorVersion',DWORD),

225 ('dwMinorVersion',DWORD),

226 ('wProcessorArchitecture',USHORT),

227 ('hSplPrinter',ULONGLONG),

228 )

229

230 class PSPLCLIENT_INFO_3(NDRPOINTER):

231 referent = (

232 ('Data', SPLCLIENT_INFO_3),

233 )

234

235# 2.2.1.5.1 DRIVER_INFO_1

236 class DRIVER_INFO_1(NDRSTRUCT):

237 structure = (

238 ('pName', STRING_HANDLE ),

239 )

240 class PDRIVER_INFO_1(NDRPOINTER):

241 referent = (

242 ('Data', DRIVER_INFO_1),

243 )

244

245# 2.2.1.5.2 DRIVER_INFO_2

246 class DRIVER_INFO_2(NDRSTRUCT):

247 structure = (

248 ('cVersion',DWORD),

249 ('pName', LPWSTR),

250 ('pEnvironment', LPWSTR),

251 ('pDriverPath', LPWSTR),

252 ('pDataFile', LPWSTR),

253 ('pConfigFile', LPWSTR),

254 )

255 class PDRIVER_INFO_2(NDRPOINTER):

256 referent = (

257 ('Data', DRIVER_INFO_2),

258 )

259

260# 2.2.1.2.3 DRIVER_CONTAINER

261 class DRIVER_INFO_UNION(NDRUNION):

262 commonHdr = (

263 ('tag', ULONG),

264 )

265 union = {

266 1 : ('pNotUsed', PDRIVER_INFO_1),

267 2 : ('Level2', PDRIVER_INFO_2),

268 }

269

270 class DRIVER_CONTAINER(NDRSTRUCT):

271 structure = (

272 ('Level', DWORD),

273 ('DriverInfo', DRIVER_INFO_UNION),

274 )

275

276# 2.2.1.2.14 SPLCLIENT_CONTAINER

277 class CLIENT_INFO_UNION(NDRUNION):

278 commonHdr = (

279 ('tag', ULONG),

280 )

281 union = {

282 1 : ('pClientInfo1', PSPLCLIENT_INFO_1),

283 2 : ('pNotUsed1', PSPLCLIENT_INFO_2),

284 3 : ('pNotUsed2', PSPLCLIENT_INFO_3),

285 }

286

287 class SPLCLIENT_CONTAINER(NDRSTRUCT):

288 structure = (

289 ('Level',DWORD),

290 ('ClientInfo',CLIENT_INFO_UNION),

291 )

292

293# 2.2.1.13.2 RPC_V2_NOTIFY_OPTIONS_TYPE

294 class USHORT_ARRAY(NDRUniConformantArray):

295 item = '<H'

296

297 class PUSHORT_ARRAY(NDRPOINTER):

298 referent = (

299 ('Data', USHORT_ARRAY),

300 )

301

302 class RpcAsync_V2_NOTIFY_OPTIONS_TYPE(NDRSTRUCT):

303 structure = (

304 ('Type',USHORT),

305 ('Reserved0',USHORT),

306 ('Reserved1',DWORD),

307 ('Reserved2',DWORD),

308 ('Count',DWORD),

309 ('pFields',PUSHORT_ARRAY),

310 )

311

312 class PRPC_V2_NOTIFY_OPTIONS_TYPE_ARRAY(NDRPOINTER):

313 referent = (

314 ('Data', RpcAsync_V2_NOTIFY_OPTIONS_TYPE),

315 )

316

317# 2.2.1.13.1 RPC_V2_NOTIFY_OPTIONS

318 class RpcAsync_V2_NOTIFY_OPTIONS(NDRSTRUCT):

319 structure = (

320 ('Version',DWORD),

321 ('Reserved',DWORD),

322 ('Count',DWORD),

323 ('pTypes',PRPC_V2_NOTIFY_OPTIONS_TYPE_ARRAY),

324 )

325

326 class PRPC_V2_NOTIFY_OPTIONS(NDRPOINTER):

327 referent = (

328 ('Data', RpcAsync_V2_NOTIFY_OPTIONS),

329 )

330

331

332################################################################################

333# RPC CALLS

334################################################################################

335# 3.1.4.1.21 RpcAsyncEnumPrinters (Opnum 38)

336 class RpcAsyncEnumPrinters(NDRCALL):

337 opnum = 38

338 structure = (

339 ('Flags', DWORD),

340 ('Name', STRING_HANDLE),

341 ('Level', DWORD),

342 ('pPrinterEnum', PBYTE_ARRAY),

343 ('cbBuf', DWORD),

344 )

345

346 class RpcAsyncEnumPrintersResponse(NDRCALL):

347 structure = (

348 ('pPrinterEnum', PBYTE_ARRAY),

349 ('pcbNeeded', DWORD),

350 ('pcReturned', DWORD),

351 ('ErrorCode', ULONG),

352 )

353

354# 3.1.4.1.1 RpcAsyncOpenPrinter (Opnum 0)

355 class RpcAsyncOpenPrinter(NDRCALL):

356 opnum = 0

357 structure = (

358 ('pPrinterName', STRING_HANDLE),

359 ('pDatatype', LPWSTR),

360 ('pDevModeContainer', DEVMODE_CONTAINER),

361 ('AccessRequired', DWORD),

362 ('pClientInfo', SPLCLIENT_CONTAINER),

363 )

364

365 class RpcAsyncOpenPrinterResponse(NDRCALL):

366 structure = (

367 ('pHandle', PRINTER_HANDLE),

368 ('ErrorCode', ULONG),

369 )

370

371# 3.1.4.1.10 RpcAsyncClosePrinter (Opnum 20)

372 class RpcAsyncClosePrinter(NDRCALL):

373 opnum = 20

374 structure = (

375 ('phPrinter', PRINTER_HANDLE),

376 )

377

378 class RpcAsyncClosePrinterResponse(NDRCALL):

379 structure = (

380 ('phPrinter', PRINTER_HANDLE),

381 ('ErrorCode', ULONG),

382 )

383

384# 3.1.4.2.3 RpcAsyncEnumPrinterDrivers (Opnum 40)

385 class RpcAsyncEnumPrinterDrivers(NDRCALL):

386 opnum = 40

387 structure = (

388 ('pName', STRING_HANDLE),

389 ('pEnvironment', LPWSTR),

390 ('Level', DWORD),

391 ('pDrivers', PBYTE_ARRAY),

392 ('cbBuf', DWORD),

393 )

394

395 class RpcAsyncEnumPrinterDriversResponse(NDRCALL):

396 structure = (

397 ('pDrivers', PBYTE_ARRAY),

398 ('pcbNeeded', DWORD),

399 ('pcReturned', DWORD),

400 ('ErrorCode', ULONG),

401 )

402

403# 3.1.4.2.2 RpcAsyncAddPrinterDriver (Opnum 39)

404 class RpcAsyncAddPrinterDriver(NDRCALL):

405 opnum = 39

406 structure = (

407 ('pName', STRING_HANDLE),

408 ('pDriverContainer', DRIVER_CONTAINER),

409 ('dwFileCopyFlags', DWORD),

410 )

411

412 class RpcAsyncAddPrinterDriverResponse(NDRCALL):

413 structure = (

414 ('ErrorCode', ULONG),

415 )

416

417################################################################################

418# OPNUMs and their corresponding structures

419################################################################################

420 OPNUMS = {

421 0 : (RpcAsyncOpenPrinter, RpcAsyncOpenPrinterResponse),

422 #1 : (RpcAsyncAddPrinter, RpcAsyncAddPrinterResponse),

423 20 : (RpcAsyncClosePrinter, RpcAsyncClosePrinterResponse),

424 38 : (RpcAsyncEnumPrinters, RpcAsyncEnumPrintersResponse),

425 39 : (RpcAsyncAddPrinterDriver, RpcAsyncAddPrinterDriver),

426 40 : (RpcAsyncEnumPrinterDrivers, RpcAsyncEnumPrinterDriversResponse),

427}

428

429################################################################################

430# HELPER FUNCTIONS

431################################################################################

432 def checkNullString(string):

433 if string == NULL:

434 return string

435

436 if string[-1:] != '\x00':

437 return string + '\x00'

438 else:

439 return string

440

441 def hRpcAsyncClosePrinter(dce, phPrinter):

442 """

443 RpcClosePrinter closes a handle to a printer object, server object, job object, or port object.

444 Full Documentation: https://msdn.microsoft.com/en-us/library/cc244768.aspx

445

446 :param DCERPC_v5 dce: a connected DCE instance.

447 :param PRINTER_HANDLE phPrinter: A handle to a printer object, server object, job object, or port object.

448

449 :return: a RpcClosePrinterResponse instance, raises DCERPCSessionError on error.

450 """

451 request = RpcAsyncClosePrinter()

452 request['phPrinter'] = phPrinter

453 return dce.request(request, MSRPC_UUID_WINSPOOL)

454

455

456 def hRpcAsyncOpenPrinter(dce, printerName, pDatatype=NULL, pDevModeContainer=NULL, accessRequired=SERVER_READ,

457 pClientInfo=NULL):

458 """

459 RpcOpenPrinterEx retrieves a handle for a printer, port, port monitor, print job, or print server

460 Full Documentation: https://msdn.microsoft.com/en-us/library/cc244809.aspx

461

462 :param DCERPC_v5 dce: a connected DCE instance.

463 :param string printerName: A string for a printer connection, printer object, server object, job object, port

464 object, or port monitor object. This MUST be a Domain Name System (DNS), NetBIOS, Internet Protocol version 4

465 (IPv4), Internet Protocol version 6 (IPv6), or Universal Naming Convention (UNC) name that remote procedure

466 call (RpcAsync) binds to, and it MUST uniquely identify a print server on the network.

467 :param string pDatatype: A string that specifies the data type to be associated with the printer handle.

468 :param DEVMODE_CONTAINER pDevModeContainer: A DEVMODE_CONTAINER structure. This parameter MUST adhere to the specification in

469 DEVMODE_CONTAINER Parameters (section 3.1.4.1.8.1).

470 :param int accessRequired: The access level that the client requires for interacting with the object to which a

471 handle is being opened.

472 :param SPLCLIENT_CONTAINER pClientInfo: This parameter MUST adhere to the specification in SPLCLIENT_CONTAINER Parameters.

473

474 :return: a RpcOpenPrinterExResponse instance, raises DCERPCSessionError on error.

475 """

476 request = RpcAsyncOpenPrinter()

477 request['pPrinterName'] = checkNullString(printerName)

478 request['pDatatype'] = pDatatype

479 if pDevModeContainer is NULL:

480 request['pDevModeContainer']['pDevMode'] = NULL

481 else:

482 request['pDevModeContainer'] = pDevModeContainer

483

484 request['AccessRequired'] = accessRequired

485 if pClientInfo is NULL:

486 raise Exception('pClientInfo cannot be NULL')

487

488 request['pClientInfo'] = pClientInfo

489 return dce.request(request, MSRPC_UUID_WINSPOOL)

490

491

492 def hRpcAsyncEnumPrinters(dce, flags, name = NULL, level = 1):

493 """

494 RpcEnumPrinters enumerates available printers, print servers, domains, or print providers.

495 Full Documentation: https://msdn.microsoft.com/en-us/library/cc244794.aspx

496

497 :param DCERPC_v5 dce: a connected DCE instance.

498 :param int flags: The types of print objects that this method enumerates. The value of this parameter is the

499 result of a bitwise OR of one or more of the Printer Enumeration Flags (section 2.2.3.7).

500 :param string name: NULL or a server name parameter as specified in Printer Server Name Parameters (section 3.1.4.1.4).

501 :param level: The level of printer information structure.

502

503 :return: a RpcEnumPrintersResponse instance, raises DCERPCSessionError on error.

504 """

505 request = RpcAsyncEnumPrinters()

506 request['Flags'] = flags

507 request['Name'] = name

508 request['pPrinterEnum'] = NULL

509 request['Level'] = level

510 bytesNeeded = 0

511 try:

512 dce.request(request, MSRPC_UUID_WINSPOOL)

513 except DCERPCSessionError as e:

514 if str(e).find('ERROR_INSUFFICIENT_BUFFER') < 0:

515 raise

516 bytesNeeded = e.get_packet()['pcbNeeded']

517

518 request = RpcAsyncEnumPrinters()

519 request['Flags'] = flags

520 request['Name'] = name

521 request['Level'] = level

522

523 request['cbBuf'] = bytesNeeded

524 request['pPrinterEnum'] = b'a' * bytesNeeded

525 return dce.request(request, MSRPC_UUID_WINSPOOL)

526

527

528 def hRpcAsyncAddPrinterDriver(dce, pName, pDriverContainer, dwFileCopyFlags):

529 """

530 RpcAddPrinterDriverEx installs a printer driver on the print server

531 Full Documentation: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/b96cc497-59e5-4510-ab04-5484993b259b

532

533 :param DCERPC_v5 dce: a connected DCE instance.

534 :param pName

535 :param pDriverContainer

536 :param dwFileCopyFlags

537

538 :return: raises DCERPCSessionError on error.

539 """

540 request = RpcAsyncAddPrinterDriver()

541 request['pName'] = checkNullString(pName)

542 request['pDriverContainer'] = pDriverContainer

543 request['dwFileCopyFlags'] = dwFileCopyFlags

544

545 #return request

546 return dce.request(request, MSRPC_UUID_WINSPOOL)

547

548

549 def hRpcAsyncEnumPrinterDrivers(dce, pName, pEnvironment, Level):

550 """

551 RpcEnumPrinterDrivers enumerates the printer drivers installed on a specified print server.

552 Full Documentation: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/857d00ac-3682-4a0d-86ca-3d3c372e5e4a

553

554 :param DCERPC_v5 dce: a connected DCE instance.

555 :param pName

556 :param pEnvironment

557 :param Level

558 :param pDrivers

559 :param cbBuf

560 :param pcbNeeded

561 :param pcReturned

562

563 :return: raises DCERPCSessionError on error.

564 """

565 # get value for cbBuf

566 request = RpcAsyncEnumPrinterDrivers()

567 request['pName'] = checkNullString(pName)

568 request['pEnvironment'] = pEnvironment

569 request['Level'] = Level

570 request['pDrivers'] = NULL

571 request['cbBuf'] = 0

572 try:

573 dce.request(request, MSRPC_UUID_WINSPOOL)

574 except DCERPCSessionError as e:

575 if str(e).find('ERROR_INSUFFICIENT_BUFFER') < 0:

576 raise

577 bytesNeeded = e.get_packet()['pcbNeeded']

578

579 # now do RpcEnumPrinterDrivers again

580 request = RpcAsyncEnumPrinterDrivers()

581 request['pName'] = checkNullString(pName)

582 request['pEnvironment'] = pEnvironment

583 request['Level'] = Level

584 request['pDrivers'] = b'a' * bytesNeeded

585 request['cbBuf'] = bytesNeeded

586

587 #return request

588 return dce.request(request, MSRPC_UUID_WINSPOOL)