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,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "python/py_spoolss.h"
PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw)
{
- char *full_name, *computer_name = NULL;
- TALLOC_CTX *mem_ctx;
+ char *unc_name, *server, *errstr;
+ TALLOC_CTX *mem_ctx = NULL;
POLICY_HND hnd;
WERROR werror;
PyObject *result = NULL, *creds = NULL;
struct cli_state *cli;
if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|O!i", kwlist, &full_name, &PyDict_Type, &creds,
- &desired_access)) {
+ args, kw, "s|Oi", kwlist, &unc_name, &creds,
+ &desired_access))
+ return NULL;
- goto done;
+ if (unc_name[0] != '\\' || unc_name[1] != '\\') {
+ PyErr_SetString(PyExc_ValueError, "UNC name required");
+ return NULL;
}
- /* FIXME: Return name format exception for names without a UNC
- prefix */
+ server = SMB_STRDUP(unc_name + 2);
- computer_name = strdup(full_name + 2);
-
- if (strchr(computer_name, '\\')) {
- char *c = strchr(computer_name, '\\');
+ if (strchr(server, '\\')) {
+ char *c = strchr(server, '\\');
*c = 0;
}
- if (!(cli = open_pipe_creds(computer_name, creds,
- cli_spoolss_initialise, NULL))) {
-
- /* Error state set in open_pipe_creds() */
+ if (creds && creds != Py_None && !PyDict_Check(creds)) {
+ PyErr_SetString(PyExc_TypeError,
+ "credentials must be dictionary or None");
+ return NULL;
+ }
+ if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
+ PyErr_SetString(spoolss_error, errstr);
+ free(errstr);
goto done;
}
- if (!(mem_ctx = talloc_init())) {
+ if (!(mem_ctx = talloc_init("spoolss_openprinter"))) {
PyErr_SetString(spoolss_error,
- "unable to initialise talloc context\n");
+ "unable to init talloc context\n");
goto done;
}
- werror = cli_spoolss_open_printer_ex(
- cli, mem_ctx, full_name, "", desired_access, computer_name,
+ werror = rpccli_spoolss_open_printer_ex(
+ cli->pipe_list, mem_ctx, unc_name, "", desired_access, server,
"", &hnd);
if (!W_ERROR_IS_OK(werror)) {
- cli_shutdown(cli);
- SAFE_FREE(cli);
PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
goto done;
}
result = new_spoolss_policy_hnd_object(cli, mem_ctx, &hnd);
done:
- SAFE_FREE(computer_name);
+ if (!result) {
+ if (cli)
+ cli_shutdown(cli);
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ }
+
+ SAFE_FREE(server);
return result;
}
/* Call rpc function */
- result = cli_spoolss_close_printer(hnd->cli, hnd->mem_ctx, &hnd->pol);
+ result = rpccli_spoolss_close_printer(
+ hnd->cli, hnd->mem_ctx, &hnd->pol);
/* Return value */
/* Fetch printer information */
-PyObject *spoolss_getprinter(PyObject *self, PyObject *args, PyObject *kw)
+PyObject *spoolss_hnd_getprinter(PyObject *self, PyObject *args, PyObject *kw)
{
spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
WERROR werror;
PyObject *result = NULL;
PRINTER_INFO_CTR ctr;
int level = 1;
- uint32 needed;
static char *kwlist[] = {"level", NULL};
/* Parse parameters */
if (!PyArg_ParseTupleAndKeywords(args, kw, "|i", kwlist, &level))
return NULL;
- if (level < 0 || level > 3) {
- PyErr_SetString(spoolss_error, "Invalid info level");
- return NULL;
- }
-
ZERO_STRUCT(ctr);
/* Call rpc function */
- werror = cli_spoolss_getprinter(
- hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, level, &ctr);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_getprinter(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
- level, &ctr);
+ werror = rpccli_spoolss_getprinter(
+ hnd->cli, hnd->mem_ctx, &hnd->pol, level, &ctr);
/* Return value */
/* Set printer information */
-PyObject *spoolss_setprinter(PyObject *self, PyObject *args, PyObject *kw)
+PyObject *spoolss_hnd_setprinter(PyObject *self, PyObject *args, PyObject *kw)
{
spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
WERROR werror;
- PyObject *info, *level_obj;
+ PyObject *info;
PRINTER_INFO_CTR ctr;
uint32 level;
static char *kwlist[] = {"dict", NULL};
union {
+ PRINTER_INFO_1 printers_1;
PRINTER_INFO_2 printers_2;
PRINTER_INFO_3 printers_3;
} pinfo;
/* Parse parameters */
- if (!PyArg_ParseTupleAndKeywords(args, kw, "O!", kwlist,
- &PyDict_Type, &info))
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "O!", kwlist, &PyDict_Type, &info))
return NULL;
- /* Check dictionary contains a level */
-
- if ((level_obj = PyDict_GetItemString(info, "level"))) {
-
- if (!PyInt_Check(level_obj)) {
- PyErr_SetString(spoolss_error,
- "level not an integer");
- return NULL;
- }
-
- level = PyInt_AsLong(level_obj);
-
- /* Only level 2, 3 supported by NT */
-
- if (level != 2 && level != 3) {
- PyErr_SetString(spoolss_error,
- "unsupported info level");
- return NULL;
- }
+ if (!get_level_value(info, &level)) {
+ PyErr_SetString(spoolss_error, "invalid info level");
+ return NULL;
+ }
- } else {
- PyErr_SetString(spoolss_error, "no info level present");
+ if (level < 1 && level > 3) {
+ PyErr_SetString(spoolss_error, "unsupported info level");
return NULL;
}
ZERO_STRUCT(ctr);
switch (level) {
+ case 1:
+ ctr.printers_1 = &pinfo.printers_1;
+
+ if (!py_to_PRINTER_INFO_1(ctr.printers_1, info)){
+ PyErr_SetString(spoolss_error,
+ "error converting printer to info 1");
+ return NULL;
+ }
+
+ break;
case 2:
ctr.printers_2 = &pinfo.printers_2;
- if (!py_to_PRINTER_INFO_2(&pinfo.printers_2, info,
+ if (!py_to_PRINTER_INFO_2(ctr.printers_2, info,
hnd->mem_ctx)){
PyErr_SetString(spoolss_error,
"error converting printer to info 2");
case 3:
ctr.printers_3 = &pinfo.printers_3;
- if (!py_to_PRINTER_INFO_3(&pinfo.printers_3, info,
+ if (!py_to_PRINTER_INFO_3(ctr.printers_3, info,
hnd->mem_ctx)) {
PyErr_SetString(spoolss_error,
"error converting to printer info 3");
/* Call rpc function */
- werror = cli_spoolss_setprinter(hnd->cli, hnd->mem_ctx, &hnd->pol,
- level, &ctr, 0);
+ werror = rpccli_spoolss_setprinter(
+ hnd->cli, hnd->mem_ctx, &hnd->pol, level, &ctr, 0);
/* Return value */
PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw)
{
WERROR werror;
- PyObject *result, *creds = NULL;
+ PyObject *result = NULL, *creds = NULL;
PRINTER_INFO_CTR ctr;
int level = 1, flags = PRINTER_ENUM_LOCAL, i;
- uint32 needed, num_printers;
+ uint32 num_printers;
static char *kwlist[] = {"server", "name", "level", "flags",
"creds", NULL};
TALLOC_CTX *mem_ctx = NULL;
struct cli_state *cli = NULL;
- char *server, *name = NULL;
+ char *server, *errstr, *name = NULL;
/* Parse parameters */
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s|siiO!", kwlist,
- &server, &name, &level, &flags,
- &PyDict_Type, &creds))
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "s|siiO", kwlist, &server, &name, &level,
+ &flags, &creds))
return NULL;
- if (server[0] == '\\' && server[1] == '\\')
- server += 2;
+ if (server[0] != '\\' || server[1] != '\\') {
+ PyErr_SetString(PyExc_ValueError, "UNC name required");
+ return NULL;
+ }
- mem_ctx = talloc_init();
- cli = open_pipe_creds(server, creds, cli_spoolss_initialise, NULL);
+ server += 2;
- /* Call rpc function */
-
- werror = cli_spoolss_enum_printers(
- cli, mem_ctx, 0, &needed, flags, level,
- &num_printers, &ctr);
+ if (creds && creds != Py_None && !PyDict_Check(creds)) {
+ PyErr_SetString(PyExc_TypeError,
+ "credentials must be dictionary or None");
+ return NULL;
+ }
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_enum_printers(
- cli, mem_ctx, needed, NULL, flags, level,
- &num_printers, &ctr);
+ if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
+ PyErr_SetString(spoolss_error, errstr);
+ free(errstr);
+ goto done;
+ }
- /* Return value */
+ if (!(mem_ctx = talloc_init("spoolss_enumprinters"))) {
+ PyErr_SetString(
+ spoolss_error, "unable to init talloc context\n");
+ goto done;
+ }
+
+ /* This RPC is weird. By setting the server name to different
+ values we can get different behaviour. If however the server
+ name is not specified, we default it to being the full server
+ name as this is probably what the caller intended. To pass a
+ NULL name, pass a value of "" */
+
+ if (!name)
+ name = server;
+ else {
+ if (!name[0])
+ name = NULL;
+ }
+
+ /* Call rpc function */
+ werror = rpccli_spoolss_enum_printers(
+ cli->pipe_list, mem_ctx, name, flags, level, &num_printers, &ctr);
+
if (!W_ERROR_IS_OK(werror)) {
PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
+ goto done;
}
- result = PyList_New(num_printers);
-
+ /* Return value */
+
switch (level) {
case 0:
+ result = PyDict_New();
+
for (i = 0; i < num_printers; i++) {
PyObject *value;
+ fstring s;
+
+ rpcstr_pull(s, ctr.printers_0[i].printername.buffer,
+ sizeof(fstring), -1, STR_TERMINATE);
py_from_PRINTER_INFO_0(&value, &ctr.printers_0[i]);
- PyList_SetItem(result, i, value);
+ PyDict_SetItemString(
+ value, "level", PyInt_FromLong(0));
+
+ PyDict_SetItemString(result, s, value);
}
break;
case 1:
+ result = PyDict_New();
+
for(i = 0; i < num_printers; i++) {
PyObject *value;
+ fstring s;
+
+ rpcstr_pull(s, ctr.printers_1[i].name.buffer,
+ sizeof(fstring), -1, STR_TERMINATE);
py_from_PRINTER_INFO_1(&value, &ctr.printers_1[i]);
- PyList_SetItem(result, i, value);
+ PyDict_SetItemString(
+ value, "level", PyInt_FromLong(1));
+
+ PyDict_SetItemString(result, s, value);
}
break;
case 2:
+ result = PyDict_New();
+
for(i = 0; i < num_printers; i++) {
PyObject *value;
+ fstring s;
+
+ rpcstr_pull(s, ctr.printers_2[i].printername.buffer,
+ sizeof(fstring), -1, STR_TERMINATE);
py_from_PRINTER_INFO_2(&value, &ctr.printers_2[i]);
- PyList_SetItem(result, i, value);
+ PyDict_SetItemString(
+ value, "level", PyInt_FromLong(2));
+
+ PyDict_SetItemString(result, s, value);
}
break;
- case 3:
- for(i = 0; i < num_printers; i++) {
- PyObject *value;
+ default:
+ PyErr_SetString(spoolss_error, "unknown info level");
+ goto done;
+ }
- py_from_PRINTER_INFO_3(&value, &ctr.printers_3[i]);
+done:
+ if (cli)
+ cli_shutdown(cli);
- PyList_SetItem(result, i, value);
- }
-
- break;
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ return result;
+}
+
+/* Add a printer */
+
+PyObject *spoolss_addprinterex(PyObject *self, PyObject *args, PyObject *kw)
+{
+ static char *kwlist[] = { "server", "printername", "info", "creds",
+ NULL};
+ char *printername, *server, *errstr;
+ PyObject *info, *result = NULL, *creds = NULL;
+ struct cli_state *cli = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+ PRINTER_INFO_CTR ctr;
+ PRINTER_INFO_2 info2;
+ WERROR werror;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "ssO!|O!", kwlist, &server, &printername,
+ &PyDict_Type, &info, &PyDict_Type, &creds))
+ return NULL;
+
+ if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
+ PyErr_SetString(spoolss_error, errstr);
+ free(errstr);
+ goto done;
}
- Py_INCREF(result);
+ if (!(mem_ctx = talloc_init("spoolss_addprinterex"))) {
+ PyErr_SetString(
+ spoolss_error, "unable to init talloc context\n");
+ goto done;
+ }
+
+ if (!py_to_PRINTER_INFO_2(&info2, info, mem_ctx)) {
+ PyErr_SetString(spoolss_error,
+ "error converting to printer info 2");
+ goto done;
+ }
+
+ ctr.printers_2 = &info2;
+
+ werror = rpccli_spoolss_addprinterex(cli->pipe_list, mem_ctx, 2, &ctr);
+
+ Py_INCREF(Py_None);
+ result = Py_None;
+
+done:
+ if (cli)
+ cli_shutdown(cli);
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
return result;
}