Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/rprn.py: 86%

# Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/rprn.py : 86%

## 285 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-RPRN] Interface implementation

11#

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

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

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

15#

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

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

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

19# There are test cases for them too.

20#

21# Author:

22# Alberto Solino (@agsolino)

23#

24 from impacket import system_errors

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

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

27 from impacket.dcerpc.v5.rpcrt import DCERPCException

28 from impacket.uuid import uuidtup_to_bin

29

30 MSRPC_UUID_RPRN = uuidtup_to_bin(('12345678-1234-ABCD-EF00-0123456789AB', '1.0'))

31

32 class DCERPCSessionError(DCERPCException):

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

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

35

36 def __str__( self ):

37 key = self.error_code

38 if key in system_errors.ERROR_MESSAGES: 38 ↛ 43line 38 didn't jump to line 43, because the condition on line 38 was never false

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

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

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

42 else:

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

44

45################################################################################

46# CONSTANTS

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

48# 2.2.1.1.7 STRING_HANDLE

49 STRING_HANDLE = LPWSTR

50 class PSTRING_HANDLE(NDRPOINTER):

51 referent = (

52 ('Data', STRING_HANDLE),

53 )

54

55# 2.2.3.1 Access Values

56 JOB_ACCESS_ADMINISTER = 0x00000010

57 JOB_ACCESS_READ = 0x00000020

58 JOB_EXECUTE = 0x00020010

59 JOB_READ = 0x00020020

60 JOB_WRITE = 0x00020010

61 JOB_ALL_ACCESS = 0x000F0030

62 PRINTER_ACCESS_ADMINISTER = 0x00000004

63 PRINTER_ACCESS_USE = 0x00000008

64 PRINTER_ACCESS_MANAGE_LIMITED = 0x00000040

65 PRINTER_ALL_ACCESS = 0x000F000C

66 PRINTER_EXECUTE = 0x00020008

67 PRINTER_READ = 0x00020008

68 PRINTER_WRITE = 0x00020008

69 SERVER_ACCESS_ADMINISTER = 0x00000001

70 SERVER_ACCESS_ENUMERATE = 0x00000002

71 SERVER_ALL_ACCESS = 0x000F0003

72 SERVER_EXECUTE = 0x00020002

73 SERVER_READ = 0x00020002

74 SERVER_WRITE = 0x00020003

75 SPECIFIC_RIGHTS_ALL = 0x0000FFFF

76 STANDARD_RIGHTS_ALL = 0x001F0000

77 STANDARD_RIGHTS_EXECUTE = 0x00020000

78 STANDARD_RIGHTS_READ = 0x00020000

79 STANDARD_RIGHTS_REQUIRED = 0x000F0000

80 STANDARD_RIGHTS_WRITE = 0x00020000

81 SYNCHRONIZE = 0x00100000

82 DELETE = 0x00010000

83 READ_CONTROL = 0x00020000

84 WRITE_DAC = 0x00040000

85 WRITE_OWNER = 0x00080000

86 GENERIC_READ = 0x80000000

87 GENERIC_WRITE = 0x40000000

88 GENERIC_EXECUTE = 0x20000000

89 GENERIC_ALL = 0x10000000

90

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

92 PRINTER_CHANGE_SET_PRINTER = 0x00000002

93 PRINTER_CHANGE_DELETE_PRINTER = 0x00000004

94 PRINTER_CHANGE_PRINTER = 0x000000FF

95 PRINTER_CHANGE_ADD_JOB = 0x00000100

96 PRINTER_CHANGE_SET_JOB = 0x00000200

97 PRINTER_CHANGE_DELETE_JOB = 0x00000400

98 PRINTER_CHANGE_WRITE_JOB = 0x00000800

99 PRINTER_CHANGE_JOB = 0x0000FF00

100 PRINTER_CHANGE_SET_PRINTER_DRIVER = 0x20000000

101 PRINTER_CHANGE_TIMEOUT = 0x80000000

102 PRINTER_CHANGE_ALL = 0x7777FFFF

103 PRINTER_CHANGE_ALL_2 = 0x7F77FFFF

104

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

106 PRINTER_CHANGE_ADD_PRINTER_DRIVER = 0x10000000

107 PRINTER_CHANGE_DELETE_PRINTER_DRIVER = 0x40000000

108 PRINTER_CHANGE_PRINTER_DRIVER = 0x70000000

109 PRINTER_CHANGE_ADD_FORM = 0x00010000

110 PRINTER_CHANGE_DELETE_FORM = 0x00040000

111 PRINTER_CHANGE_SET_FORM = 0x00020000

112 PRINTER_CHANGE_FORM = 0x00070000

113 PRINTER_CHANGE_ADD_PORT = 0x00100000

114 PRINTER_CHANGE_CONFIGURE_PORT = 0x00200000

115 PRINTER_CHANGE_DELETE_PORT = 0x00400000

116 PRINTER_CHANGE_PORT = 0x00700000

117 PRINTER_CHANGE_ADD_PRINT_PROCESSOR = 0x01000000

118 PRINTER_CHANGE_DELETE_PRINT_PROCESSOR = 0x04000000

119 PRINTER_CHANGE_PRINT_PROCESSOR = 0x07000000

120 PRINTER_CHANGE_ADD_PRINTER = 0x00000001

121 PRINTER_CHANGE_FAILED_CONNECTION_PRINTER = 0x00000008

122 PRINTER_CHANGE_SERVER = 0x08000000

123

124# 2.2.3.7 Printer Enumeration Flags

125 PRINTER_ENUM_LOCAL = 0x00000002

126 PRINTER_ENUM_CONNECTIONS = 0x00000004

127 PRINTER_ENUM_NAME = 0x00000008

128 PRINTER_ENUM_REMOTE = 0x00000010

129 PRINTER_ENUM_SHARED = 0x00000020

130 PRINTER_ENUM_NETWORK = 0x00000040

131 PRINTER_ENUM_EXPAND = 0x00004000

132 PRINTER_ENUM_CONTAINER = 0x00008000

133 PRINTER_ENUM_ICON1 = 0x00010000

134 PRINTER_ENUM_ICON2 = 0x00020000

135 PRINTER_ENUM_ICON3 = 0x00040000

136 PRINTER_ENUM_ICON8 = 0x00800000

137 PRINTER_ENUM_HIDE = 0x01000000

138

139

140# 2.2.3.8 Printer Notification Values

141 PRINTER_NOTIFY_CATEGORY_2D = 0x00000000

142 PRINTER_NOTIFY_CATEGORY_ALL = 0x00010000

143 PRINTER_NOTIFY_CATEGORY_3D = 0x00020000

144

145

146# 3.1.4.4.8 RpcAddPrinterDriverEx Values

147 APD_STRICT_UPGRADE = 0x00000001

148 APD_STRICT_DOWNGRADE = 0x00000002

149 APD_COPY_ALL_FILES = 0x00000004

150 APD_COPY_NEW_FILES = 0x00000008

151 APD_COPY_FROM_DIRECTORY = 0x00000010

152 APD_DONT_COPY_FILES_TO_CLUSTER = 0x00001000

153 APD_COPY_TO_ALL_SPOOLERS = 0x00002000

154 APD_INSTALL_WARNED_DRIVER = 0x00008000

155 APD_RETURN_BLOCKING_STATUS_CODE = 0x00010000

156

157################################################################################

158# STRUCTURES

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

160# 2.2.1.1.4 PRINTER_HANDLE

161 class PRINTER_HANDLE(NDRSTRUCT):

162 structure = (

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

164 )

165 def getAlignment(self):

166 if self._isNDR64 is True:

167 return 8

168 else:

169 return 4

170

171# 2.2.1.2.1 DEVMODE_CONTAINER

172 class BYTE_ARRAY(NDRUniConformantArray):

173 item = 'c'

174

175 class PBYTE_ARRAY(NDRPOINTER):

176 referent = (

177 ('Data', BYTE_ARRAY),

178 )

179

180 class DEVMODE_CONTAINER(NDRSTRUCT):

181 structure = (

182 ('cbBuf',DWORD),

183 ('pDevMode',PBYTE_ARRAY),

184 )

185

186# 2.2.1.11.1 SPLCLIENT_INFO_1

187 class SPLCLIENT_INFO_1(NDRSTRUCT):

188 structure = (

189 ('dwSize',DWORD),

190 ('pMachineName',LPWSTR),

191 ('pUserName',LPWSTR),

192 ('dwBuildNum',DWORD),

193 ('dwMajorVersion',DWORD),

194 ('dwMinorVersion',DWORD),

195 ('wProcessorArchitecture',USHORT),

196 )

197

198 class PSPLCLIENT_INFO_1(NDRPOINTER):

199 referent = (

200 ('Data', SPLCLIENT_INFO_1),

201 )

202

203# 2.2.1.11.2 SPLCLIENT_INFO_2

204 class SPLCLIENT_INFO_2(NDRSTRUCT):

205 structure = (

206 ('notUsed',ULONGLONG),

207 )

208

209 class PSPLCLIENT_INFO_2(NDRPOINTER):

210 referent = (

211 ('Data', SPLCLIENT_INFO_2),

212 )

213# 2.2.1.11.3 SPLCLIENT_INFO_3

214 class SPLCLIENT_INFO_3(NDRSTRUCT):

215 structure = (

216 ('cbSize',UINT),

217 ('dwFlags',DWORD),

218 ('dwFlags',DWORD),

219 ('pMachineName',LPWSTR),

220 ('pUserName',LPWSTR),

221 ('dwBuildNum',DWORD),

222 ('dwMajorVersion',DWORD),

223 ('dwMinorVersion',DWORD),

224 ('wProcessorArchitecture',USHORT),

225 ('hSplPrinter',ULONGLONG),

226 )

227

228 class PSPLCLIENT_INFO_3(NDRPOINTER):

229 referent = (

230 ('Data', SPLCLIENT_INFO_3),

231 )

232

233# 2.2.1.5.1 DRIVER_INFO_1

234 class DRIVER_INFO_1(NDRSTRUCT):

235 structure = (

236 ('pName', STRING_HANDLE ),

237 )

238 class PDRIVER_INFO_1(NDRPOINTER):

239 referent = (

240 ('Data', DRIVER_INFO_1),

241 )

242

243# 2.2.1.5.2 DRIVER_INFO_2

244 class DRIVER_INFO_2(NDRSTRUCT):

245 structure = (

246 ('cVersion',DWORD),

247 ('pName', LPWSTR),

248 ('pEnvironment', LPWSTR),

249 ('pDriverPath', LPWSTR),

250 ('pDataFile', LPWSTR),

251 ('pConfigFile', LPWSTR),

252 )

253 class PDRIVER_INFO_2(NDRPOINTER):

254 referent = (

255 ('Data', DRIVER_INFO_2),

256 )

257

258# 2.2.1.2.3 DRIVER_CONTAINER

259 class DRIVER_INFO_UNION(NDRUNION):

260 commonHdr = (

261 ('tag', ULONG),

262 )

263 union = {

264 1 : ('pNotUsed', PDRIVER_INFO_1),

265 2 : ('Level2', PDRIVER_INFO_2),

266 }

267

268 class DRIVER_CONTAINER(NDRSTRUCT):

269 structure = (

270 ('Level', DWORD),

271 ('DriverInfo', DRIVER_INFO_UNION),

272 )

273

274# 2.2.1.2.14 SPLCLIENT_CONTAINER

275 class CLIENT_INFO_UNION(NDRUNION):

276 commonHdr = (

277 ('tag', ULONG),

278 )

279 union = {

280 1 : ('pClientInfo1', PSPLCLIENT_INFO_1),

281 2 : ('pNotUsed1', PSPLCLIENT_INFO_2),

282 3 : ('pNotUsed2', PSPLCLIENT_INFO_3),

283 }

284

285 class SPLCLIENT_CONTAINER(NDRSTRUCT):

286 structure = (

287 ('Level',DWORD),

288 ('ClientInfo',CLIENT_INFO_UNION),

289 )

290

291# 2.2.1.13.2 RPC_V2_NOTIFY_OPTIONS_TYPE

292 class USHORT_ARRAY(NDRUniConformantArray):

293 item = '<H'

294

295 class PUSHORT_ARRAY(NDRPOINTER):

296 referent = (

297 ('Data', USHORT_ARRAY),

298 )

299

300 class RPC_V2_NOTIFY_OPTIONS_TYPE(NDRSTRUCT):

301 structure = (

302 ('Type',USHORT),

303 ('Reserved0',USHORT),

304 ('Reserved1',DWORD),

305 ('Reserved2',DWORD),

306 ('Count',DWORD),

307 ('pFields',PUSHORT_ARRAY),

308 )

309

310 class PRPC_V2_NOTIFY_OPTIONS_TYPE_ARRAY(NDRPOINTER):

311 referent = (

312 ('Data', RPC_V2_NOTIFY_OPTIONS_TYPE),

313 )

314

315# 2.2.1.13.1 RPC_V2_NOTIFY_OPTIONS

316 class RPC_V2_NOTIFY_OPTIONS(NDRSTRUCT):

317 structure = (

318 ('Version',DWORD),

319 ('Reserved',DWORD),

320 ('Count',DWORD),

321 ('pTypes',PRPC_V2_NOTIFY_OPTIONS_TYPE_ARRAY),

322 )

323

324 class PRPC_V2_NOTIFY_OPTIONS(NDRPOINTER):

325 referent = (

326 ('Data', RPC_V2_NOTIFY_OPTIONS),

327 )

328

329

330################################################################################

331# RPC CALLS

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

333# 3.1.4.2.1 RpcEnumPrinters (Opnum 0)

334 class RpcEnumPrinters(NDRCALL):

335 opnum = 0

336 structure = (

337 ('Flags', DWORD),

338 ('Name', STRING_HANDLE),

339 ('Level', DWORD),

340 ('pPrinterEnum', PBYTE_ARRAY),

341 ('cbBuf', DWORD),

342 )

343

344 class RpcEnumPrintersResponse(NDRCALL):

345 structure = (

346 ('pPrinterEnum', PBYTE_ARRAY),

347 ('pcbNeeded', DWORD),

348 ('pcReturned', DWORD),

349 ('ErrorCode', ULONG),

350 )

351# 3.1.4.2.2 RpcOpenPrinter (Opnum 1)

352 class RpcOpenPrinter(NDRCALL):

353 opnum = 1

354 structure = (

355 ('pPrinterName', STRING_HANDLE),

356 ('pDatatype', LPWSTR),

357 ('pDevModeContainer', DEVMODE_CONTAINER),

358 ('AccessRequired', DWORD),

359 )

360

361 class RpcOpenPrinterResponse(NDRCALL):

362 structure = (

363 ('pHandle', PRINTER_HANDLE),

364 ('ErrorCode', ULONG),

365 )

366

367# 3.1.4.2.9 RpcClosePrinter (Opnum 29)

368 class RpcClosePrinter(NDRCALL):

369 opnum = 29

370 structure = (

371 ('phPrinter', PRINTER_HANDLE),

372 )

373

374 class RpcClosePrinterResponse(NDRCALL):

375 structure = (

376 ('phPrinter', PRINTER_HANDLE),

377 ('ErrorCode', ULONG),

378 )

379

380# 3.1.4.10.4 RpcRemoteFindFirstPrinterChangeNotificationEx (Opnum 65)

381 class RpcRemoteFindFirstPrinterChangeNotificationEx(NDRCALL):

382 opnum = 65

383 structure = (

384 ('hPrinter', PRINTER_HANDLE),

385 ('fdwFlags', DWORD),

386 ('fdwOptions', DWORD),

387 ('pszLocalMachine', LPWSTR),

388 ('dwPrinterLocal', DWORD),

389 ('pOptions', PRPC_V2_NOTIFY_OPTIONS),

390 )

391

392 class RpcRemoteFindFirstPrinterChangeNotificationExResponse(NDRCALL):

393 structure = (

394 ('ErrorCode', ULONG),

395 )

396

397# 3.1.4.2.14 RpcOpenPrinterEx (Opnum 69)

398 class RpcOpenPrinterEx(NDRCALL):

399 opnum = 69

400 structure = (

401 ('pPrinterName', STRING_HANDLE),

402 ('pDatatype', LPWSTR),

403 ('pDevModeContainer', DEVMODE_CONTAINER),

404 ('AccessRequired', DWORD),

405 ('pClientInfo', SPLCLIENT_CONTAINER),

406 )

407

408 class RpcOpenPrinterExResponse(NDRCALL):

409 structure = (

410 ('pHandle', PRINTER_HANDLE),

411 ('ErrorCode', ULONG),

412 )

413

414# 3.1.4.4.2 RpcEnumPrinterDrivers (Opnum 10)

415 class RpcEnumPrinterDrivers(NDRCALL):

416 opnum = 10

417 structure = (

418 ('pName', STRING_HANDLE),

419 ('pEnvironment', LPWSTR),

420 ('Level', DWORD),

421 ('pDrivers', PBYTE_ARRAY),

422 ('cbBuf', DWORD),

423 )

424

425 class RpcEnumPrinterDriversResponse(NDRCALL):

426 structure = (

427 ('pDrivers', PBYTE_ARRAY),

428 ('pcbNeeded', DWORD),

429 ('pcReturned', DWORD),

430 ('ErrorCode', ULONG),

431 )

432

433# 3.1.4.4.8 RpcAddPrinterDriverEx (Opnum 89)

434 class RpcAddPrinterDriverEx(NDRCALL):

435 opnum = 89

436 structure = (

437 ('pName', STRING_HANDLE),

438 ('pDriverContainer', DRIVER_CONTAINER),

439 ('dwFileCopyFlags', DWORD),

440 )

441

442 class RpcAddPrinterDriverExResponse(NDRCALL):

443 structure = (

444 ('ErrorCode', ULONG),

445 )

446

447################################################################################

448# OPNUMs and their corresponding structures

449################################################################################

450 OPNUMS = {

451 0 : (RpcEnumPrinters, RpcEnumPrintersResponse),

452 1 : (RpcOpenPrinter, RpcOpenPrinterResponse),

453 10 : (RpcEnumPrinterDrivers, RpcEnumPrinterDriversResponse),

454 29 : (RpcClosePrinter, RpcClosePrinterResponse),

455 65 : (RpcRemoteFindFirstPrinterChangeNotificationEx, RpcRemoteFindFirstPrinterChangeNotificationExResponse),

456 69 : (RpcOpenPrinterEx, RpcOpenPrinterExResponse),

457 89 : (RpcAddPrinterDriverEx, RpcAddPrinterDriverExResponse),

458}

459

460################################################################################

461# HELPER FUNCTIONS

462################################################################################

463 def checkNullString(string):

464 if string == NULL: 464 ↛ 465line 464 didn't jump to line 465, because the condition on line 464 was never true

465 return string

466

467 if string[-1:] != '\x00': 467 ↛ 468line 467 didn't jump to line 468, because the condition on line 467 was never true

468 return string + '\x00'

469 else:

470 return string

471

472 def hRpcOpenPrinter(dce, printerName, pDatatype = NULL, pDevModeContainer = NULL, accessRequired = SERVER_READ):

473 """

474 RpcOpenPrinter retrieves a handle for a printer, port, port monitor, print job, or print server.

475 Full Documentation: https://msdn.microsoft.com/en-us/library/cc244808.aspx

476

477 :param DCERPC_v5 dce: a connected DCE instance.

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

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

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

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

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

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

484 DEVMODE_CONTAINER Parameters (section 3.1.4.1.8.1).

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

486 handle is being opened.

487

488 :return: a RpcOpenPrinterResponse instance, raises DCERPCSessionError on error.

489 """

490 request = RpcOpenPrinter()

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

492 request['pDatatype'] = pDatatype

493 if pDevModeContainer is NULL: 493 ↛ 496line 493 didn't jump to line 496, because the condition on line 493 was never false

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

495 else:

496 request['pDevModeContainer'] = pDevModeContainer

497

498 request['AccessRequired'] = accessRequired

499 return dce.request(request)

500

501 def hRpcClosePrinter(dce, phPrinter):

502 """

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

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

505

506 :param DCERPC_v5 dce: a connected DCE instance.

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

508

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

510 """

511 request = RpcClosePrinter()

512 request['phPrinter'] = phPrinter

513 return dce.request(request)

514

515

516 def hRpcOpenPrinterEx(dce, printerName, pDatatype=NULL, pDevModeContainer=NULL, accessRequired=SERVER_READ,

517 pClientInfo=NULL):

518 """

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

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

521

522 :param DCERPC_v5 dce: a connected DCE instance.

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

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

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

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

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

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

529 DEVMODE_CONTAINER Parameters (section 3.1.4.1.8.1).

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

531 handle is being opened.

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

533

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

535 """

536 request = RpcOpenPrinterEx()

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

538 request['pDatatype'] = pDatatype

539 if pDevModeContainer is NULL: 539 ↛ 542line 539 didn't jump to line 542, because the condition on line 539 was never false

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

541 else:

542 request['pDevModeContainer'] = pDevModeContainer

543

544 request['AccessRequired'] = accessRequired

545 if pClientInfo is NULL: 545 ↛ 546line 545 didn't jump to line 546, because the condition on line 545 was never true

546 raise Exception('pClientInfo cannot be NULL')

547

548 request['pClientInfo'] = pClientInfo

549 return dce.request(request)

550

551

552 def hRpcRemoteFindFirstPrinterChangeNotificationEx(dce, hPrinter, fdwFlags, fdwOptions=0, pszLocalMachine=NULL,

553 dwPrinterLocal=0, pOptions=NULL):

554 """

555 creates a remote change notification object that monitors changes to printer objects and sends change notifications

556 to a print client using either RpcRouterReplyPrinter (section 3.2.4.1.2) or RpcRouterReplyPrinterEx (section 3.2.4.1.4)

557 Full Documentation: https://msdn.microsoft.com/en-us/library/cc244813.aspx

558

559 :param DCERPC_v5 dce: a connected DCE instance.

560 :param PRINTER_HANDLE hPrinter: A handle to a printer or server object.

561 :param int fdwFlags: Flags that specify the conditions that are required for a change notification object to enter a signaled state.

562 :param int fdwOptions: The category of printers for which change notifications are returned.

563 :param string pszLocalMachine: A string that represents the name of the client computer.

564 :param int dwPrinterLocal: An implementation-specific unique value that MUST be sufficient for the client to determine

565 whether a call to RpcReplyOpenPrinter by the server is associated with the hPrinter parameter in this call.

566 :param RPC_V2_NOTIFY_OPTIONS pOptions: An RPC_V2_NOTIFY_OPTIONS structure that specifies printer or job members that the client listens to for notifications.

567

568 :return: a RpcRemoteFindFirstPrinterChangeNotificationExResponse instance, raises DCERPCSessionError on error.

569 """

570 request = RpcRemoteFindFirstPrinterChangeNotificationEx()

571

572 request['hPrinter'] = hPrinter

573 request['fdwFlags'] = fdwFlags

574 request['fdwOptions'] = fdwOptions

575 request['dwPrinterLocal'] = dwPrinterLocal

576 if pszLocalMachine is NULL: 576 ↛ 577line 576 didn't jump to line 577, because the condition on line 576 was never true

577 raise Exception('pszLocalMachine cannot be NULL')

578 request['pszLocalMachine'] = checkNullString(pszLocalMachine)

579 request['pOptions'] = pOptions

580 return dce.request(request)

581

582 def hRpcEnumPrinters(dce, flags, name = NULL, level = 1):

583 """

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

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

586

587 :param DCERPC_v5 dce: a connected DCE instance.

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

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

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

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

592

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

594 """

595 request = RpcEnumPrinters()

596 request['Flags'] = flags

597 request['Name'] = name

598 request['pPrinterEnum'] = NULL

599 request['Level'] = level

600 bytesNeeded = 0

601 try:

602 dce.request(request)

603 except DCERPCSessionError as e:

604 if str(e).find('ERROR_INSUFFICIENT_BUFFER') < 0: 604 ↛ 605line 604 didn't jump to line 605, because the condition on line 604 was never true

605 raise

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

607

608 request = RpcEnumPrinters()

609 request['Flags'] = flags

610 request['Name'] = name

611 request['Level'] = level

612

613 request['cbBuf'] = bytesNeeded

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

615 return dce.request(request)

616

617

618 def hRpcAddPrinterDriverEx(dce, pName, pDriverContainer, dwFileCopyFlags):

619 """

620 RpcAddPrinterDriverEx installs a printer driver on the print server

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

622

623 :param DCERPC_v5 dce: a connected DCE instance.

624 :param pName

625 :param pDriverContainer

626 :param dwFileCopyFlags

627

628 :return: raises DCERPCSessionError on error.

629 """

630 request = RpcAddPrinterDriverEx()

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

632 request['pDriverContainer'] = pDriverContainer

633 request['dwFileCopyFlags'] = dwFileCopyFlags

634

635 #return request

636 return dce.request(request)

637

638

639 def hRpcEnumPrinterDrivers(dce, pName, pEnvironment, Level):

640 """

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

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

643

644 :param DCERPC_v5 dce: a connected DCE instance.

645 :param pName

646 :param pEnvironment

647 :param Level

648 :param pDrivers

649 :param cbBuf

650 :param pcbNeeded

651 :param pcReturned

652

653 :return: raises DCERPCSessionError on error.

654 """

655 # get value for cbBuf

656 request = RpcEnumPrinterDrivers()

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

658 request['pEnvironment'] = pEnvironment

659 request['Level'] = Level

660 request['pDrivers'] = NULL

661 request['cbBuf'] = 0

662 try:

663 dce.request(request)

664 except DCERPCSessionError as e:

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

666 raise

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

668

669 # now do RpcEnumPrinterDrivers again

670 request = RpcEnumPrinterDrivers()

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

672 request['pEnvironment'] = pEnvironment

673 request['Level'] = Level

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

675 request['cbBuf'] = bytesNeeded

676

677 #return request

678 return dce.request(request)