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 *unc_name, *server = NULL, *errstr;
- 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, &unc_name, &PyDict_Type, &creds,
+ args, kw, "s|Oi", kwlist, &unc_name, &creds,
&desired_access))
- goto done;
+ return NULL;
- /* FIXME: Return name format exception for names without a UNC
- prefix */
+ if (unc_name[0] != '\\' || unc_name[1] != '\\') {
+ PyErr_SetString(PyExc_ValueError, "UNC name required");
+ return NULL;
+ }
- server = strdup(unc_name + 2);
+ server = SMB_STRDUP(unc_name + 2);
if (strchr(server, '\\')) {
char *c = strchr(server, '\\');
*c = 0;
}
- if (!(cli = open_pipe_creds(
- server, creds, cli_spoolss_initialise, &errstr))) {
+ 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 init talloc context\n");
goto done;
}
- werror = cli_spoolss_open_printer_ex(
- cli, mem_ctx, unc_name, "", desired_access, server,
+ 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:
+ 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 */
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 */
{
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;
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 *result = NULL, *creds = NULL;
PRINTER_INFO_CTR ctr;
int level = 1, flags = PRINTER_ENUM_LOCAL, i;
- uint32 needed, num_printers;
- static char *kwlist[] = {"server", "level", "flags", "creds", NULL};
+ uint32 num_printers;
+ static char *kwlist[] = {"server", "name", "level", "flags",
+ "creds", NULL};
TALLOC_CTX *mem_ctx = NULL;
struct cli_state *cli = NULL;
- char *server, *errstr;
+ char *server, *errstr, *name = NULL;
/* Parse parameters */
if (!PyArg_ParseTupleAndKeywords(
- args, kw, "s|iiO!", kwlist, &server, &level, &flags,
- &PyDict_Type, &creds))
+ 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;
+ }
+
+ server += 2;
- if (!(cli = open_pipe_creds(
- server, creds, cli_spoolss_initialise, &errstr))) {
+ 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_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 = cli_spoolss_enum_printers(
- cli, mem_ctx, 0, &needed, flags, level,
- &num_printers, &ctr);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_enum_printers(
- cli, mem_ctx, needed, NULL, flags, level,
- &num_printers, &ctr);
+ 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));
for (i = 0; i < num_printers; i++) {
PyObject *value;
- fstring name;
+ fstring s;
- rpcstr_pull(name, ctr.printers_0[i].printername.buffer,
+ rpcstr_pull(s, ctr.printers_0[i].printername.buffer,
sizeof(fstring), -1, STR_TERMINATE);
py_from_PRINTER_INFO_0(&value, &ctr.printers_0[i]);
PyDict_SetItemString(
value, "level", PyInt_FromLong(0));
- PyDict_SetItemString(result, name, value);
+ PyDict_SetItemString(result, s, value);
}
break;
for(i = 0; i < num_printers; i++) {
PyObject *value;
- fstring name;
+ fstring s;
- rpcstr_pull(name, ctr.printers_1[i].name.buffer,
+ rpcstr_pull(s, ctr.printers_1[i].name.buffer,
sizeof(fstring), -1, STR_TERMINATE);
py_from_PRINTER_INFO_1(&value, &ctr.printers_1[i]);
PyDict_SetItemString(
value, "level", PyInt_FromLong(1));
- PyDict_SetItemString(result, name, value);
+ PyDict_SetItemString(result, s, value);
}
break;
for(i = 0; i < num_printers; i++) {
PyObject *value;
- fstring name;
+ fstring s;
- rpcstr_pull(name, ctr.printers_2[i].printername.buffer,
+ rpcstr_pull(s, ctr.printers_2[i].printername.buffer,
sizeof(fstring), -1, STR_TERMINATE);
py_from_PRINTER_INFO_2(&value, &ctr.printers_2[i]);
PyDict_SetItemString(
value, "level", PyInt_FromLong(2));
- PyDict_SetItemString(result, name, value);
+ PyDict_SetItemString(result, s, value);
}
break;
&PyDict_Type, &info, &PyDict_Type, &creds))
return NULL;
- if (!(cli = open_pipe_creds(
- server, creds, cli_spoolss_initialise, &errstr))) {
+ 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_addprinterex"))) {
PyErr_SetString(
spoolss_error, "unable to init talloc context\n");
- return NULL;
+ goto done;
}
if (!py_to_PRINTER_INFO_2(&info2, info, mem_ctx)) {
ctr.printers_2 = &info2;
- werror = cli_spoolss_addprinterex(cli, mem_ctx, 2, &ctr);
+ werror = rpccli_spoolss_addprinterex(cli->pipe_list, mem_ctx, 2, &ctr);
Py_INCREF(Py_None);
result = Py_None;
done:
- cli_shutdown(cli);
- talloc_destroy(mem_ctx);
+ if (cli)
+ cli_shutdown(cli);
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
return result;
}