1/* 2 Python wrappers for DCERPC/SMB client routines. 3 4 Copyright (C) Tim Potter, 2002 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19*/ 20 21#include "python/py_spoolss.h" 22 23/* Enumerate printer drivers */ 24 25PyObject *spoolss_enumprinterdrivers(PyObject *self, PyObject *args, 26 PyObject *kw) 27{ 28 WERROR werror; 29 PyObject *result = NULL, *creds = NULL; 30 PRINTER_DRIVER_CTR ctr; 31 int level = 1, i; 32 uint32 num_drivers; 33 char *arch = "Windows NT x86", *server, *errstr; 34 static char *kwlist[] = {"server", "level", "creds", "arch", NULL}; 35 struct cli_state *cli = NULL; 36 TALLOC_CTX *mem_ctx = NULL; 37 38 /* Parse parameters */ 39 40 if (!PyArg_ParseTupleAndKeywords( 41 args, kw, "s|iOs", kwlist, &server, &level, &creds, 42 &arch)) 43 return NULL; 44 45 if (server[0] != '\\' || server[1] != '\\') { 46 PyErr_SetString(PyExc_ValueError, "UNC name required"); 47 return NULL; 48 } 49 50 server += 2; 51 52 if (creds && creds != Py_None && !PyDict_Check(creds)) { 53 PyErr_SetString(PyExc_TypeError, 54 "credentials must be dictionary or None"); 55 return NULL; 56 } 57 58 /* Call rpc function */ 59 60 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) { 61 PyErr_SetString(spoolss_error, errstr); 62 free(errstr); 63 goto done; 64 } 65 66 if (!(mem_ctx = talloc_init("spoolss_enumprinterdrivers"))) { 67 PyErr_SetString( 68 spoolss_error, "unable to init talloc context\n"); 69 goto done; 70 } 71 72 werror = rpccli_spoolss_enumprinterdrivers( 73 cli->pipe_list, mem_ctx, level, arch, 74 &num_drivers, &ctr); 75 76 if (!W_ERROR_IS_OK(werror)) { 77 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); 78 goto done; 79 } 80 81 /* Return value */ 82 83 switch (level) { 84 case 1: 85 result = PyDict_New(); 86 87 for (i = 0; i < num_drivers; i++) { 88 PyObject *value; 89 fstring name; 90 91 rpcstr_pull(name, ctr.info1[i].name.buffer, 92 sizeof(fstring), -1, STR_TERMINATE); 93 94 py_from_DRIVER_INFO_1(&value, &ctr.info1[i]); 95 96 PyDict_SetItemString(result, name, value); 97 } 98 99 break; 100 case 2: 101 result = PyDict_New(); 102 103 for(i = 0; i < num_drivers; i++) { 104 PyObject *value; 105 fstring name; 106 107 rpcstr_pull(name, ctr.info2[i].name.buffer, 108 sizeof(fstring), -1, STR_TERMINATE); 109 110 py_from_DRIVER_INFO_2(&value, &ctr.info2[i]); 111 112 PyDict_SetItemString(result, name, value); 113 } 114 115 break; 116 case 3: 117 result = PyDict_New(); 118 119 for(i = 0; i < num_drivers; i++) { 120 PyObject *value; 121 fstring name; 122 123 rpcstr_pull(name, ctr.info3[i].name.buffer, 124 sizeof(fstring), -1, STR_TERMINATE); 125 126 py_from_DRIVER_INFO_3(&value, &ctr.info3[i]); 127 128 PyDict_SetItemString(result, name, value); 129 } 130 131 break; 132 case 6: 133 result = PyDict_New(); 134 135 for(i = 0; i < num_drivers; i++) { 136 PyObject *value; 137 fstring name; 138 139 rpcstr_pull(name, ctr.info6[i].name.buffer, 140 sizeof(fstring), -1, STR_TERMINATE); 141 142 py_from_DRIVER_INFO_6(&value, &ctr.info6[i]); 143 144 PyList_SetItem(result, i, value); 145 } 146 147 break; 148 default: 149 PyErr_SetString(spoolss_error, "unknown info level"); 150 goto done; 151 } 152 153 done: 154 if (cli) 155 cli_shutdown(cli); 156 157 if (mem_ctx) 158 talloc_destroy(mem_ctx); 159 160 return result; 161} 162 163/* Fetch printer driver */ 164 165PyObject *spoolss_hnd_getprinterdriver(PyObject *self, PyObject *args, 166 PyObject *kw) 167{ 168 spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self; 169 WERROR werror; 170 PyObject *result = Py_None; 171 PRINTER_DRIVER_CTR ctr; 172 int level = 1; 173 char *arch = "Windows NT x86"; 174 int version = 2; 175 static char *kwlist[] = {"level", "arch", NULL}; 176 177 /* Parse parameters */ 178 179 if (!PyArg_ParseTupleAndKeywords( 180 args, kw, "|is", kwlist, &level, &arch)) 181 return NULL; 182 183 /* Call rpc function */ 184 185 werror = rpccli_spoolss_getprinterdriver( 186 hnd->cli, hnd->mem_ctx, &hnd->pol, level, arch, version, &ctr); 187 188 if (!W_ERROR_IS_OK(werror)) { 189 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); 190 return NULL; 191 } 192 193 /* Return value */ 194 195 switch (level) { 196 case 1: 197 py_from_DRIVER_INFO_1(&result, ctr.info1); 198 break; 199 case 2: 200 py_from_DRIVER_INFO_2(&result, ctr.info2); 201 break; 202 case 3: 203 py_from_DRIVER_INFO_3(&result, ctr.info3); 204 break; 205 case 6: 206 py_from_DRIVER_INFO_6(&result, ctr.info6); 207 break; 208 default: 209 PyErr_SetString(spoolss_error, "unsupported info level"); 210 return NULL; 211 } 212 213 Py_INCREF(result); 214 return result; 215} 216 217/* Fetch printer driver directory */ 218 219PyObject *spoolss_getprinterdriverdir(PyObject *self, PyObject *args, 220 PyObject *kw) 221{ 222 WERROR werror; 223 PyObject *result = NULL, *creds = NULL; 224 DRIVER_DIRECTORY_CTR ctr; 225 uint32 level = 1; 226 char *arch = "Windows NT x86", *server, *errstr; 227 static char *kwlist[] = {"server", "level", "arch", "creds", NULL}; 228 struct cli_state *cli = NULL; 229 TALLOC_CTX *mem_ctx = NULL; 230 231 /* Parse parameters */ 232 233 if (!PyArg_ParseTupleAndKeywords( 234 args, kw, "s|isO", kwlist, &server, &level, 235 &arch, &creds)) 236 return NULL; 237 238 if (server[0] != '\\' || server[1] != '\\') { 239 PyErr_SetString(PyExc_ValueError, "UNC name required"); 240 return NULL; 241 } 242 243 server += 2; 244 245 if (creds && creds != Py_None && !PyDict_Check(creds)) { 246 PyErr_SetString(PyExc_TypeError, 247 "credentials must be dictionary or None"); 248 return NULL; 249 } 250 251 /* Call rpc function */ 252 253 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) { 254 PyErr_SetString(spoolss_error, errstr); 255 free(errstr); 256 goto done; 257 } 258 259 if (!(mem_ctx = talloc_init("spoolss_getprinterdriverdir"))) { 260 PyErr_SetString( 261 spoolss_error, "unable to init talloc context\n"); 262 goto done; 263 } 264 265 werror = rpccli_spoolss_getprinterdriverdir( 266 cli->pipe_list, mem_ctx, level, arch, &ctr); 267 268 if (!W_ERROR_IS_OK(werror)) { 269 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); 270 goto done; 271 } 272 273 /* Return value */ 274 275 switch (level) { 276 case 1: 277 py_from_DRIVER_DIRECTORY_1(&result, ctr.info1); 278 break; 279 default: 280 PyErr_SetString(spoolss_error, "unknown info level"); 281 goto done; 282 } 283 284 done: 285 if (cli) 286 cli_shutdown(cli); 287 288 if (mem_ctx) 289 talloc_destroy(mem_ctx); 290 291 return result; 292} 293 294PyObject *spoolss_addprinterdriver(PyObject *self, PyObject *args, 295 PyObject *kw) 296{ 297 static char *kwlist[] = { "server", "info", "creds", NULL }; 298 char *server, *errstr; 299 uint32 level; 300 PyObject *info, *result = NULL, *creds = NULL; 301 WERROR werror; 302 TALLOC_CTX *mem_ctx = NULL; 303 struct cli_state *cli = NULL; 304 PRINTER_DRIVER_CTR ctr; 305 union { 306 DRIVER_INFO_3 driver_3; 307 } dinfo; 308 309 if (!PyArg_ParseTupleAndKeywords( 310 args, kw, "sO!|O", kwlist, &server, &PyDict_Type, 311 &info, &creds)) 312 return NULL; 313 314 if (server[0] == '\\' || server[1] == '\\') 315 server += 2; 316 317 if (creds && creds != Py_None && !PyDict_Check(creds)) { 318 PyErr_SetString(PyExc_TypeError, 319 "credentials must be dictionary or None"); 320 return NULL; 321 } 322 323 if (!(mem_ctx = talloc_init("spoolss_addprinterdriver"))) { 324 PyErr_SetString( 325 spoolss_error, "unable to init talloc context\n"); 326 return NULL; 327 } 328 329 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) { 330 PyErr_SetString(spoolss_error, errstr); 331 free(errstr); 332 goto done; 333 } 334 335 if (!get_level_value(info, &level)) { 336 PyErr_SetString(spoolss_error, "invalid info level"); 337 goto done; 338 } 339 340 if (level != 3) { 341 PyErr_SetString(spoolss_error, "unsupported info level"); 342 goto done; 343 } 344 345 ZERO_STRUCT(ctr); 346 ZERO_STRUCT(dinfo); 347 348 switch(level) { 349 case 3: 350 ctr.info3 = &dinfo.driver_3; 351 352 if (!py_to_DRIVER_INFO_3(&dinfo.driver_3, info, mem_ctx)) { 353 PyErr_SetString(spoolss_error, 354 "error converting to driver info 3"); 355 goto done; 356 } 357 358 break; 359 default: 360 PyErr_SetString(spoolss_error, "unsupported info level"); 361 goto done; 362 } 363 364 werror = rpccli_spoolss_addprinterdriver(cli->pipe_list, mem_ctx, level, &ctr); 365 366 if (!W_ERROR_IS_OK(werror)) { 367 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); 368 goto done; 369 } 370 371 Py_INCREF(Py_None); 372 result = Py_None; 373 374done: 375 if (cli) 376 cli_shutdown(cli); 377 378 if (mem_ctx) 379 talloc_destroy(mem_ctx); 380 381 return result; 382 383} 384 385PyObject *spoolss_addprinterdriverex(PyObject *self, PyObject *args, 386 PyObject *kw) 387{ 388 /* Not supported by Samba server */ 389 390 PyErr_SetString(spoolss_error, "Not implemented"); 391 return NULL; 392} 393 394PyObject *spoolss_deleteprinterdriver(PyObject *self, PyObject *args, 395 PyObject *kw) 396{ 397 PyErr_SetString(spoolss_error, "Not implemented"); 398 return NULL; 399} 400 401PyObject *spoolss_deleteprinterdriverex(PyObject *self, PyObject *args, 402 PyObject *kw) 403{ 404 PyErr_SetString(spoolss_error, "Not implemented"); 405 return NULL; 406} 407