This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
#include "python/py_spoolss.h"
-/* Structure/hash conversions */
-
-struct pyconv py_DRIVER_INFO_1[] = {
- { "name", PY_UNISTR, offsetof(DRIVER_INFO_1, name) },
- { NULL }
-};
-
-struct pyconv py_DRIVER_INFO_2[] = {
- { "version", PY_UINT32, offsetof(DRIVER_INFO_2, version) },
- { "name", PY_UNISTR, offsetof(DRIVER_INFO_2, name) },
- { "architecture", PY_UNISTR, offsetof(DRIVER_INFO_2, architecture) },
- { "driver_path", PY_UNISTR, offsetof(DRIVER_INFO_2, driverpath) },
- { "data_file", PY_UNISTR, offsetof(DRIVER_INFO_2, datafile) },
- { "config_file", PY_UNISTR, offsetof(DRIVER_INFO_2, configfile) },
- { NULL }
-};
-
-struct pyconv py_DRIVER_INFO_3[] = {
- { "version", PY_UINT32, offsetof(DRIVER_INFO_3, version) },
- { "name", PY_UNISTR, offsetof(DRIVER_INFO_3, name) },
- { "architecture", PY_UNISTR, offsetof(DRIVER_INFO_3, architecture) },
- { "driver_path", PY_UNISTR, offsetof(DRIVER_INFO_3, driverpath) },
- { "data_file", PY_UNISTR, offsetof(DRIVER_INFO_3, datafile) },
- { "config_file", PY_UNISTR, offsetof(DRIVER_INFO_3, configfile) },
- { "help_file", PY_UNISTR, offsetof(DRIVER_INFO_3, helpfile) },
- /* dependentfiles */
- { "monitor_name", PY_UNISTR, offsetof(DRIVER_INFO_3, monitorname) },
- { "default_datatype", PY_UNISTR, offsetof(DRIVER_INFO_3, defaultdatatype) },
- { NULL }
-};
-
-struct pyconv py_DRIVER_INFO_6[] = {
- { "version", PY_UINT32, offsetof(DRIVER_INFO_6, version) },
- { "name", PY_UNISTR, offsetof(DRIVER_INFO_6, name) },
- { "architecture", PY_UNISTR, offsetof(DRIVER_INFO_6, architecture) },
- { "driver_path", PY_UNISTR, offsetof(DRIVER_INFO_6, driverpath) },
- { "data_file", PY_UNISTR, offsetof(DRIVER_INFO_6, datafile) },
- { "config_file", PY_UNISTR, offsetof(DRIVER_INFO_6, configfile) },
- { "help_file", PY_UNISTR, offsetof(DRIVER_INFO_6, helpfile) },
- /* dependentfiles */
- { "monitor_name", PY_UNISTR, offsetof(DRIVER_INFO_6, monitorname) },
- { "default_datatype", PY_UNISTR, offsetof(DRIVER_INFO_6, defaultdatatype) },
- /* driver_date */
-
- { "padding", PY_UINT32, offsetof(DRIVER_INFO_6, padding) },
- { "driver_version_low", PY_UINT32, offsetof(DRIVER_INFO_6, driver_version_low) },
- { "driver_version_high", PY_UINT32, offsetof(DRIVER_INFO_6, driver_version_high) },
- { "mfg_name", PY_UNISTR, offsetof(DRIVER_INFO_6, mfgname) },
- { "oem_url", PY_UNISTR, offsetof(DRIVER_INFO_6, oem_url) },
- { "hardware_id", PY_UNISTR, offsetof(DRIVER_INFO_6, hardware_id) },
- { "provider", PY_UNISTR, offsetof(DRIVER_INFO_6, provider) },
-
- { NULL }
-};
-
-struct pyconv py_DRIVER_DIRECTORY_1[] = {
- { "name", PY_UNISTR, offsetof(DRIVER_DIRECTORY_1, name) },
- { NULL }
-};
-
/* Enumerate printer drivers */
PyObject *spoolss_enumprinterdrivers(PyObject *self, PyObject *args,
PyObject *kw)
{
WERROR werror;
- PyObject *result = Py_None, *creds = NULL;
+ PyObject *result = NULL, *creds = NULL;
PRINTER_DRIVER_CTR ctr;
int level = 1, i;
- uint32 needed, num_drivers;
- char *arch = "Windows NT x86", *server_name;
- static char *kwlist[] = {"server", "level", "arch", "creds", NULL};
+ uint32 num_drivers;
+ char *arch = "Windows NT x86", *server, *errstr;
+ static char *kwlist[] = {"server", "level", "creds", "arch", NULL};
struct cli_state *cli = NULL;
TALLOC_CTX *mem_ctx = NULL;
-
+
/* Parse parameters */
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s|isO!", kwlist,
- &server_name, &level, &arch,
- &PyDict_Type, &creds))
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "s|iOs", kwlist, &server, &level, &creds,
+ &arch))
return NULL;
+ if (server[0] != '\\' || server[1] != '\\') {
+ PyErr_SetString(PyExc_ValueError, "UNC name required");
+ return NULL;
+ }
+
+ server += 2;
+
+ if (creds && creds != Py_None && !PyDict_Check(creds)) {
+ PyErr_SetString(PyExc_TypeError,
+ "credentials must be dictionary or None");
+ return NULL;
+ }
+
/* Call rpc function */
- if (!(cli = open_pipe_creds(server_name, creds,
- cli_spoolss_initialise, NULL))) {
- fprintf(stderr, "could not initialise cli state\n");
+ if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
+ PyErr_SetString(spoolss_error, errstr);
+ free(errstr);
goto done;
}
- if (!(mem_ctx = talloc_init())) {
- fprintf(stderr, "unable to initialise talloc context\n");
+ if (!(mem_ctx = talloc_init("spoolss_enumprinterdrivers"))) {
+ PyErr_SetString(
+ spoolss_error, "unable to init talloc context\n");
goto done;
}
- werror = cli_spoolss_enumprinterdrivers(
- cli, mem_ctx, 0, &needed, level, arch,
+ werror = rpccli_spoolss_enumprinterdrivers(
+ cli->pipe_list, mem_ctx, level, arch,
&num_drivers, &ctr);
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_enumprinterdrivers(
- cli, mem_ctx, needed, NULL, level, arch,
- &num_drivers, &ctr);
+ if (!W_ERROR_IS_OK(werror)) {
+ PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
+ goto done;
+ }
/* Return value */
-
- if (!W_ERROR_IS_OK(werror))
- goto done;
switch (level) {
case 1:
- result = PyList_New(num_drivers);
+ result = PyDict_New();
for (i = 0; i < num_drivers; i++) {
PyObject *value;
+ fstring name;
- value = from_struct(&ctr.info1, py_DRIVER_INFO_1);
- PyList_SetItem(result, i, value);
+ rpcstr_pull(name, ctr.info1[i].name.buffer,
+ sizeof(fstring), -1, STR_TERMINATE);
+
+ py_from_DRIVER_INFO_1(&value, &ctr.info1[i]);
+
+ PyDict_SetItemString(result, name, value);
}
break;
case 2:
- result = PyList_New(num_drivers);
+ result = PyDict_New();
for(i = 0; i < num_drivers; i++) {
PyObject *value;
+ fstring name;
- value = from_struct(&ctr.info2, py_DRIVER_INFO_2);
- PyList_SetItem(result, i, value);
+ rpcstr_pull(name, ctr.info2[i].name.buffer,
+ sizeof(fstring), -1, STR_TERMINATE);
+
+ py_from_DRIVER_INFO_2(&value, &ctr.info2[i]);
+
+ PyDict_SetItemString(result, name, value);
+ }
+
+ break;
+ case 3:
+ result = PyDict_New();
+
+ for(i = 0; i < num_drivers; i++) {
+ PyObject *value;
+ fstring name;
+
+ rpcstr_pull(name, ctr.info3[i].name.buffer,
+ sizeof(fstring), -1, STR_TERMINATE);
+
+ py_from_DRIVER_INFO_3(&value, &ctr.info3[i]);
+
+ PyDict_SetItemString(result, name, value);
}
break;
case 6:
- result = PyList_New(num_drivers);
+ result = PyDict_New();
for(i = 0; i < num_drivers; i++) {
PyObject *value;
+ fstring name;
+
+ rpcstr_pull(name, ctr.info6[i].name.buffer,
+ sizeof(fstring), -1, STR_TERMINATE);
+
+ py_from_DRIVER_INFO_6(&value, &ctr.info6[i]);
- value = from_struct(&ctr.info2, py_DRIVER_INFO_6);
PyList_SetItem(result, i, value);
}
break;
default:
- result = Py_None;
- break;
+ PyErr_SetString(spoolss_error, "unknown info level");
+ goto done;
}
done:
if (mem_ctx)
talloc_destroy(mem_ctx);
- Py_INCREF(result);
return result;
}
/* Fetch printer driver */
-PyObject *spoolss_getprinterdriver(PyObject *self, PyObject *args,
+PyObject *spoolss_hnd_getprinterdriver(PyObject *self, PyObject *args,
PyObject *kw)
{
spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
PyObject *result = Py_None;
PRINTER_DRIVER_CTR ctr;
int level = 1;
- uint32 needed;
char *arch = "Windows NT x86";
+ int version = 2;
static char *kwlist[] = {"level", "arch", NULL};
/* Parse parameters */
- if (!PyArg_ParseTupleAndKeywords(args, kw, "|is", kwlist,
- &level, &arch))
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "|is", kwlist, &level, &arch))
return NULL;
/* Call rpc function */
- werror = cli_spoolss_getprinterdriver(
- hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, level,
- arch, &ctr);
+ werror = rpccli_spoolss_getprinterdriver(
+ hnd->cli, hnd->mem_ctx, &hnd->pol, level, arch, version, &ctr);
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_getprinterdriver(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
- level, arch, &ctr);
+ if (!W_ERROR_IS_OK(werror)) {
+ PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
+ return NULL;
+ }
/* Return value */
- if (W_ERROR_IS_OK(werror)) {
- switch (level) {
- case 1:
- result = from_struct(&ctr.info1, py_DRIVER_INFO_1);
- break;
- case 2:
- result = from_struct(&ctr.info2, py_DRIVER_INFO_2);
- break;
- case 6:
- result = from_struct(&ctr.info6, py_DRIVER_INFO_6);
- break;
- default:
- break;
- }
+ switch (level) {
+ case 1:
+ py_from_DRIVER_INFO_1(&result, ctr.info1);
+ break;
+ case 2:
+ py_from_DRIVER_INFO_2(&result, ctr.info2);
+ break;
+ case 3:
+ py_from_DRIVER_INFO_3(&result, ctr.info3);
+ break;
+ case 6:
+ py_from_DRIVER_INFO_6(&result, ctr.info6);
+ break;
+ default:
+ PyErr_SetString(spoolss_error, "unsupported info level");
+ return NULL;
}
Py_INCREF(result);
PyObject *kw)
{
WERROR werror;
- PyObject *result = Py_None, *creds = NULL;
+ PyObject *result = NULL, *creds = NULL;
DRIVER_DIRECTORY_CTR ctr;
- uint32 needed, level;
- char *arch = "Windows NT x86", *server_name;
+ uint32 level = 1;
+ char *arch = "Windows NT x86", *server, *errstr;
static char *kwlist[] = {"server", "level", "arch", "creds", NULL};
struct cli_state *cli = NULL;
TALLOC_CTX *mem_ctx = NULL;
/* Parse parameters */
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s|isO!", kwlist,
- &server_name, &level, &arch,
- &PyDict_Type, &creds))
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "s|isO", kwlist, &server, &level,
+ &arch, &creds))
+ return NULL;
+
+ if (server[0] != '\\' || server[1] != '\\') {
+ PyErr_SetString(PyExc_ValueError, "UNC name required");
+ return NULL;
+ }
+
+ server += 2;
+
+ if (creds && creds != Py_None && !PyDict_Check(creds)) {
+ PyErr_SetString(PyExc_TypeError,
+ "credentials must be dictionary or None");
return NULL;
+ }
/* Call rpc function */
- if (!(cli = open_pipe_creds(server_name, creds,
- cli_spoolss_initialise, NULL))) {
- fprintf(stderr, "could not initialise cli state\n");
+ if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
+ PyErr_SetString(spoolss_error, errstr);
+ free(errstr);
goto done;
}
-
- if (!(mem_ctx = talloc_init())) {
- fprintf(stderr, "unable to initialise talloc context\n");
+
+ if (!(mem_ctx = talloc_init("spoolss_getprinterdriverdir"))) {
+ PyErr_SetString(
+ spoolss_error, "unable to init talloc context\n");
goto done;
}
- werror = cli_spoolss_getprinterdriverdir(
- cli, mem_ctx, 0, &needed, level, arch, &ctr);
+ werror = rpccli_spoolss_getprinterdriverdir(
+ cli->pipe_list, mem_ctx, level, arch, &ctr);
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_getprinterdriverdir(
- cli, mem_ctx, needed, NULL, level, arch, &ctr);
+ if (!W_ERROR_IS_OK(werror)) {
+ PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
+ goto done;
+ }
/* Return value */
- if (W_ERROR_IS_OK(werror)) {
- switch (level) {
- case 1:
- result = from_struct(
- &ctr.info1, py_DRIVER_DIRECTORY_1);
- break;
- default:
- break;
- }
+ switch (level) {
+ case 1:
+ py_from_DRIVER_DIRECTORY_1(&result, ctr.info1);
+ break;
+ default:
+ PyErr_SetString(spoolss_error, "unknown info level");
+ goto done;
}
done:
if (mem_ctx)
talloc_destroy(mem_ctx);
- Py_INCREF(result);
return result;
}
+
+PyObject *spoolss_addprinterdriver(PyObject *self, PyObject *args,
+ PyObject *kw)
+{
+ static char *kwlist[] = { "server", "info", "creds", NULL };
+ char *server, *errstr;
+ uint32 level;
+ PyObject *info, *result = NULL, *creds = NULL;
+ WERROR werror;
+ TALLOC_CTX *mem_ctx = NULL;
+ struct cli_state *cli = NULL;
+ PRINTER_DRIVER_CTR ctr;
+ union {
+ DRIVER_INFO_3 driver_3;
+ } dinfo;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "sO!|O", kwlist, &server, &PyDict_Type,
+ &info, &creds))
+ return NULL;
+
+ if (server[0] == '\\' || server[1] == '\\')
+ server += 2;
+
+ if (creds && creds != Py_None && !PyDict_Check(creds)) {
+ PyErr_SetString(PyExc_TypeError,
+ "credentials must be dictionary or None");
+ return NULL;
+ }
+
+ if (!(mem_ctx = talloc_init("spoolss_addprinterdriver"))) {
+ PyErr_SetString(
+ spoolss_error, "unable to init talloc context\n");
+ return NULL;
+ }
+
+ if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
+ PyErr_SetString(spoolss_error, errstr);
+ free(errstr);
+ goto done;
+ }
+
+ if (!get_level_value(info, &level)) {
+ PyErr_SetString(spoolss_error, "invalid info level");
+ goto done;
+ }
+
+ if (level != 3) {
+ PyErr_SetString(spoolss_error, "unsupported info level");
+ goto done;
+ }
+
+ ZERO_STRUCT(ctr);
+ ZERO_STRUCT(dinfo);
+
+ switch(level) {
+ case 3:
+ ctr.info3 = &dinfo.driver_3;
+
+ if (!py_to_DRIVER_INFO_3(&dinfo.driver_3, info, mem_ctx)) {
+ PyErr_SetString(spoolss_error,
+ "error converting to driver info 3");
+ goto done;
+ }
+
+ break;
+ default:
+ PyErr_SetString(spoolss_error, "unsupported info level");
+ goto done;
+ }
+
+ werror = rpccli_spoolss_addprinterdriver(cli->pipe_list, mem_ctx, level, &ctr);
+
+ if (!W_ERROR_IS_OK(werror)) {
+ PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
+ goto done;
+ }
+
+ Py_INCREF(Py_None);
+ result = Py_None;
+
+done:
+ if (cli)
+ cli_shutdown(cli);
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ return result;
+
+}
+
+PyObject *spoolss_addprinterdriverex(PyObject *self, PyObject *args,
+ PyObject *kw)
+{
+ /* Not supported by Samba server */
+
+ PyErr_SetString(spoolss_error, "Not implemented");
+ return NULL;
+}
+
+PyObject *spoolss_deleteprinterdriver(PyObject *self, PyObject *args,
+ PyObject *kw)
+{
+ PyErr_SetString(spoolss_error, "Not implemented");
+ return NULL;
+}
+
+PyObject *spoolss_deleteprinterdriverex(PyObject *self, PyObject *args,
+ PyObject *kw)
+{
+ PyErr_SetString(spoolss_error, "Not implemented");
+ return NULL;
+}