diff options
Diffstat (limited to 'source4/rpc_server/spoolss')
-rw-r--r-- | source4/rpc_server/spoolss/dcesrv_spoolss.c | 1560 |
1 files changed, 1560 insertions, 0 deletions
diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c new file mode 100644 index 0000000000..28e30002e2 --- /dev/null +++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c @@ -0,0 +1,1560 @@ +/* + Unix SMB/CIFS implementation. + + endpoint server for the spoolss pipe + + Copyright (C) Tim Potter 2004 + Copyright (C) Stefan Metzmacher 2005 + + 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "rpc_server/dcerpc_server.h" +#include "librpc/gen_ndr/ndr_spoolss.h" +#include "rpc_server/common/common.h" +#include "ntptr/ntptr.h" +#include "lib/socket/socket.h" +#include "smbd/service_stream.h" +#include "librpc/gen_ndr/ndr_spoolss_c.h" +#include "auth/credentials/credentials.h" +#include "param/param.h" + +enum spoolss_handle { + SPOOLSS_NOTIFY +}; + +#define SPOOLSS_BUFFER_UNION(fn,info,level) \ + ((info)?ndr_size_##fn(info, level, 0):0) + +#define SPOOLSS_BUFFER_UNION_ARRAY(fn,info,level,count) \ + ((info)?ndr_size_##fn##_info(dce_call, level, count, info):0) + +#define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= r->out.needed)?val_true:val_false) + +static WERROR dcesrv_spoolss_parse_printer_name(TALLOC_CTX *mem_ctx, const char *name, + const char **_server_name, + const char **_object_name, + enum ntptr_HandleType *_object_type) +{ + char *p; + char *server = NULL; + char *server_unc = NULL; + const char *object = name; + + /* no printername is there it's like open server */ + if (!name) { + *_server_name = NULL; + *_object_name = NULL; + *_object_type = NTPTR_HANDLE_SERVER; + return WERR_OK; + } + + /* just "\\" is invalid */ + if (strequal("\\\\", name)) { + return WERR_INVALID_PRINTER_NAME; + } + + if (strncmp("\\\\", name, 2) == 0) { + server_unc = talloc_strdup(mem_ctx, name); + W_ERROR_HAVE_NO_MEMORY(server_unc); + server = server_unc + 2; + + /* here we know we have "\\" in front not followed + * by '\0', now see if we have another "\" in the string + */ + p = strchr_m(server, '\\'); + if (!p) { + /* there's no other "\", so it's ("\\%s",server) + */ + *_server_name = server_unc; + *_object_name = NULL; + *_object_type = NTPTR_HANDLE_SERVER; + return WERR_OK; + } + /* here we know that we have ("\\%s\",server), + * if we have '\0' as next then it's an invalid name + * otherwise the printer_name + */ + p[0] = '\0'; + /* everything that follows is the printer name */ + p++; + object = p; + + /* just "" as server is invalid */ + if (strequal(server, "")) { + return WERR_INVALID_PRINTER_NAME; + } + } + + /* just "" is invalid */ + if (strequal(object, "")) { + return WERR_INVALID_PRINTER_NAME; + } + +#define XCV_PORT ",XcvPort " +#define XCV_MONITOR ",XcvMonitor " + if (strncmp(object, XCV_PORT, strlen(XCV_PORT)) == 0) { + object += strlen(XCV_PORT); + + /* just "" is invalid */ + if (strequal(object, "")) { + return WERR_INVALID_PRINTER_NAME; + } + + *_server_name = server_unc; + *_object_name = object; + *_object_type = NTPTR_HANDLE_PORT; + return WERR_OK; + } else if (strncmp(object, XCV_MONITOR, strlen(XCV_MONITOR)) == 0) { + object += strlen(XCV_MONITOR); + + /* just "" is invalid */ + if (strequal(object, "")) { + return WERR_INVALID_PRINTER_NAME; + } + + *_server_name = server_unc; + *_object_name = object; + *_object_type = NTPTR_HANDLE_MONITOR; + return WERR_OK; + } + + *_server_name = server_unc; + *_object_name = object; + *_object_type = NTPTR_HANDLE_PRINTER; + return WERR_OK; +} + +/* + * Check server_name is: + * - "" , functions that don't allow "", + * should check that on their own, before calling this function + * - our name (only netbios yet, TODO: need to test dns name!) + * - our ip address of the current use socket + * otherwise return WERR_INVALID_PRINTER_NAME + */ +static WERROR dcesrv_spoolss_check_server_name(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, + const char *server_name) +{ + bool ret; + struct socket_address *myaddr; + const char **aliases; + int i; + + /* NULL is ok */ + if (!server_name) return WERR_OK; + + /* "" is ok */ + ret = strequal("",server_name); + if (ret) return WERR_OK; + + /* just "\\" is invalid */ + if (strequal("\\\\", server_name)) { + return WERR_INVALID_PRINTER_NAME; + } + + /* then we need "\\" */ + if (strncmp("\\\\", server_name, 2) != 0) { + return WERR_INVALID_PRINTER_NAME; + } + + server_name += 2; + + /* NETBIOS NAME is ok */ + ret = strequal(lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx), server_name); + if (ret) return WERR_OK; + + aliases = lp_netbios_aliases(dce_call->conn->dce_ctx->lp_ctx); + + for (i=0; aliases && aliases[i]; i++) { + if (strequal(aliases[i], server_name)) { + return WERR_OK; + } + } + + /* DNS NAME is ok + * TODO: we need to check if aliases are also ok + */ + if (lp_realm(dce_call->conn->dce_ctx->lp_ctx)) { + char *str; + + str = talloc_asprintf(mem_ctx, "%s.%s", + lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx), + lp_realm(dce_call->conn->dce_ctx->lp_ctx)); + W_ERROR_HAVE_NO_MEMORY(str); + + ret = strequal(str, server_name); + talloc_free(str); + if (ret) return WERR_OK; + } + + myaddr = dcesrv_connection_get_my_addr(dce_call->conn, mem_ctx); + W_ERROR_HAVE_NO_MEMORY(myaddr); + + ret = strequal(myaddr->addr, server_name); + talloc_free(myaddr); + if (ret) return WERR_OK; + + return WERR_INVALID_PRINTER_NAME; +} + +static NTSTATUS dcerpc_spoolss_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) +{ + NTSTATUS status; + struct ntptr_context *ntptr; + + status = ntptr_init_context(dce_call->context, dce_call->conn->event_ctx, dce_call->conn->dce_ctx->lp_ctx, + lp_ntptr_providor(dce_call->conn->dce_ctx->lp_ctx), &ntptr); + NT_STATUS_NOT_OK_RETURN(status); + + dce_call->context->private = ntptr; + + return NT_STATUS_OK; +} + +#define DCESRV_INTERFACE_SPOOLSS_BIND dcerpc_spoolss_bind + +/* + spoolss_EnumPrinters +*/ +static WERROR dcesrv_spoolss_EnumPrinters(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EnumPrinters *r) +{ + struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context); + WERROR status; + + status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.server); + W_ERROR_NOT_OK_RETURN(status); + + status = ntptr_EnumPrinters(ntptr, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + + r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinters, r->out.info, r->in.level, r->out.count); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); + r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0); + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); +} + +static WERROR dcesrv_spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_OpenPrinterEx *r); +/* + spoolss_OpenPrinter +*/ +static WERROR dcesrv_spoolss_OpenPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_OpenPrinter *r) +{ + WERROR status; + struct spoolss_OpenPrinterEx *r2; + + r2 = talloc(mem_ctx, struct spoolss_OpenPrinterEx); + W_ERROR_HAVE_NO_MEMORY(r2); + + r2->in.printername = r->in.printername; + r2->in.datatype = r->in.datatype; + r2->in.devmode_ctr = r->in.devmode_ctr; + r2->in.access_mask = r->in.access_mask; + r2->in.level = 1; + r2->in.userlevel.level1 = NULL; + + r2->out.handle = r->out.handle; + + /* TODO: we should take care about async replies here, + if spoolss_OpenPrinterEx() would be async! + */ + status = dcesrv_spoolss_OpenPrinterEx(dce_call, mem_ctx, r2); + + r->out.handle = r2->out.handle; + + return status; +} + + +/* + spoolss_SetJob +*/ +static WERROR dcesrv_spoolss_SetJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_SetJob *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_GetJob +*/ +static WERROR dcesrv_spoolss_GetJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_GetJob *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_EnumJobs +*/ +static WERROR dcesrv_spoolss_EnumJobs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EnumJobs *r) +{ + return WERR_OK; +} + + +/* + spoolss_AddPrinter +*/ +static WERROR dcesrv_spoolss_AddPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AddPrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_DeletePrinter +*/ +static WERROR dcesrv_spoolss_DeletePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeletePrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_SetPrinter +*/ +static WERROR dcesrv_spoolss_SetPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_SetPrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_GetPrinter +*/ +static WERROR dcesrv_spoolss_GetPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_AddPrinterDriver +*/ +static WERROR dcesrv_spoolss_AddPrinterDriver(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AddPrinterDriver *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_EnumPrinterDrivers +*/ +static WERROR dcesrv_spoolss_EnumPrinterDrivers(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EnumPrinterDrivers *r) +{ + struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context); + WERROR status; + + status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.server); + W_ERROR_NOT_OK_RETURN(status); + + status = ntptr_EnumPrinterDrivers(ntptr, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + + r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinterDrivers, r->out.info, r->in.level, r->out.count); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); + r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0); + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); +} + + +/* + spoolss_GetPrinterDriver +*/ +static WERROR dcesrv_spoolss_GetPrinterDriver(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrinterDriver *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_GetPrinterDriverDirectory +*/ +static WERROR dcesrv_spoolss_GetPrinterDriverDirectory(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrinterDriverDirectory *r) +{ + struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context); + WERROR status; + + status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.server); + W_ERROR_NOT_OK_RETURN(status); + + status = ntptr_GetPrinterDriverDirectory(ntptr, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + + r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, r->out.info, r->in.level); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); +} + + +/* + spoolss_DeletePrinterDriver +*/ +static WERROR dcesrv_spoolss_DeletePrinterDriver(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeletePrinterDriver *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_AddPrintProcessor +*/ +static WERROR dcesrv_spoolss_AddPrintProcessor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AddPrintProcessor *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_EnumPrintProcessors +*/ +static WERROR dcesrv_spoolss_EnumPrintProcessors(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EnumPrintProcessors *r) +{ + return WERR_OK; +} + + +/* + spoolss_GetPrintProcessorDirectory +*/ +static WERROR dcesrv_spoolss_GetPrintProcessorDirectory(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrintProcessorDirectory *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_StartDocPrinter +*/ +static WERROR dcesrv_spoolss_StartDocPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_StartDocPrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_StartPagePrinter +*/ +static WERROR dcesrv_spoolss_StartPagePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_StartPagePrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_WritePrinter +*/ +static WERROR dcesrv_spoolss_WritePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_WritePrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_EndPagePrinter +*/ +static WERROR dcesrv_spoolss_EndPagePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EndPagePrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_AbortPrinter +*/ +static WERROR dcesrv_spoolss_AbortPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AbortPrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_ReadPrinter +*/ +static WERROR dcesrv_spoolss_ReadPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_ReadPrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_EndDocPrinter +*/ +static WERROR dcesrv_spoolss_EndDocPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EndDocPrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_AddJob +*/ +static WERROR dcesrv_spoolss_AddJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AddJob *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_ScheduleJob +*/ +static WERROR dcesrv_spoolss_ScheduleJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_ScheduleJob *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_GetPrinterData +*/ +static WERROR dcesrv_spoolss_GetPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrinterData *r) +{ + struct ntptr_GenericHandle *handle; + struct dcesrv_handle *h; + WERROR status; + + DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); + handle = talloc_get_type(h->data, struct ntptr_GenericHandle); + if (!handle) + return WERR_BADFID; + + switch (handle->type) { + case NTPTR_HANDLE_SERVER: + status = ntptr_GetPrintServerData(handle, mem_ctx, r); + break; + default: + status = WERR_FOOBAR; + break; + } + + W_ERROR_NOT_OK_RETURN(status); + + r->out.needed = ndr_size_spoolss_PrinterData(&r->out.data, r->out.type, 0); + r->out.type = SPOOLSS_BUFFER_OK(r->out.type, SPOOLSS_PRINTER_DATA_TYPE_NULL); + r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data); + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA); +} + + +/* + spoolss_SetPrinterData +*/ +static WERROR dcesrv_spoolss_SetPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_SetPrinterData *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_WaitForPrinterChange +*/ +static WERROR dcesrv_spoolss_WaitForPrinterChange(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_WaitForPrinterChange *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_ClosePrinter +*/ +static WERROR dcesrv_spoolss_ClosePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_ClosePrinter *r) +{ + struct dcesrv_handle *h; + + *r->out.handle = *r->in.handle; + + DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); + + talloc_free(h); + + ZERO_STRUCTP(r->out.handle); + + return WERR_OK; +} + + +/* + spoolss_AddForm +*/ +static WERROR dcesrv_spoolss_AddForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AddForm *r) +{ + struct ntptr_GenericHandle *handle; + struct dcesrv_handle *h; + WERROR status; + + DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); + handle = talloc_get_type(h->data, struct ntptr_GenericHandle); + if (!handle) + return WERR_BADFID; + + switch (handle->type) { + case NTPTR_HANDLE_SERVER: + status = ntptr_AddPrintServerForm(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + case NTPTR_HANDLE_PRINTER: + status = ntptr_AddPrinterForm(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + default: + return WERR_FOOBAR; + } + + return WERR_OK; +} + + +/* + spoolss_DeleteForm +*/ +static WERROR dcesrv_spoolss_DeleteForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeleteForm *r) +{ + struct ntptr_GenericHandle *handle; + struct dcesrv_handle *h; + WERROR status; + + DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); + handle = talloc_get_type(h->data, struct ntptr_GenericHandle); + if (!handle) + return WERR_BADFID; + + switch (handle->type) { + case NTPTR_HANDLE_SERVER: + status = ntptr_DeletePrintServerForm(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + case NTPTR_HANDLE_PRINTER: + status = ntptr_DeletePrinterForm(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + default: + return WERR_FOOBAR; + } + + return WERR_OK; +} + + +/* + spoolss_GetForm +*/ +static WERROR dcesrv_spoolss_GetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_GetForm *r) +{ + struct ntptr_GenericHandle *handle; + struct dcesrv_handle *h; + WERROR status; + + DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); + handle = talloc_get_type(h->data, struct ntptr_GenericHandle); + if (!handle) + return WERR_BADFID; + + switch (handle->type) { + case NTPTR_HANDLE_SERVER: + /* + * stupid, but w2k3 returns WERR_BADFID here? + */ + return WERR_BADFID; + case NTPTR_HANDLE_PRINTER: + status = ntptr_GetPrinterForm(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + default: + return WERR_FOOBAR; + } + + r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, r->out.info, r->in.level); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); +} + + +/* + spoolss_SetForm +*/ +static WERROR dcesrv_spoolss_SetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_SetForm *r) +{ + struct ntptr_GenericHandle *handle; + struct dcesrv_handle *h; + WERROR status; + + DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); + handle = talloc_get_type(h->data, struct ntptr_GenericHandle); + if (!handle) + return WERR_BADFID; + + switch (handle->type) { + case NTPTR_HANDLE_SERVER: + status = ntptr_SetPrintServerForm(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + case NTPTR_HANDLE_PRINTER: + status = ntptr_SetPrinterForm(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + default: + return WERR_FOOBAR; + } + + return WERR_OK; +} + + +/* + spoolss_EnumForms +*/ +static WERROR dcesrv_spoolss_EnumForms(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EnumForms *r) +{ + struct ntptr_GenericHandle *handle; + struct dcesrv_handle *h; + WERROR status; + + DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); + handle = talloc_get_type(h->data, struct ntptr_GenericHandle); + if (!handle) + return WERR_BADFID; + + switch (handle->type) { + case NTPTR_HANDLE_SERVER: + status = ntptr_EnumPrintServerForms(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + case NTPTR_HANDLE_PRINTER: + status = ntptr_EnumPrinterForms(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + default: + return WERR_FOOBAR; + } + + r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumForms, r->out.info, r->in.level, r->out.count); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); + r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0); + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); +} + + +/* + spoolss_EnumPorts +*/ +static WERROR dcesrv_spoolss_EnumPorts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EnumPorts *r) +{ + struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context); + WERROR status; + + status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.servername); + W_ERROR_NOT_OK_RETURN(status); + + status = ntptr_EnumPorts(ntptr, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + + r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPorts, r->out.info, r->in.level, r->out.count); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); + r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0); + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); +} + + +/* + spoolss_EnumMonitors +*/ +static WERROR dcesrv_spoolss_EnumMonitors(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EnumMonitors *r) +{ + struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context); + WERROR status; + + status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.servername); + W_ERROR_NOT_OK_RETURN(status); + + status = ntptr_EnumMonitors(ntptr, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + + r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumMonitors, r->out.info, r->in.level, r->out.count); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); + r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0); + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); +} + + +/* + spoolss_AddPort +*/ +static WERROR dcesrv_spoolss_AddPort(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AddPort *r) +{ + return WERR_NOT_SUPPORTED; +} + + +/* + spoolss_ConfigurePort +*/ +static WERROR dcesrv_spoolss_ConfigurePort(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_ConfigurePort *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_DeletePort +*/ +static WERROR dcesrv_spoolss_DeletePort(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeletePort *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_CreatePrinterIC +*/ +static WERROR dcesrv_spoolss_CreatePrinterIC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_CreatePrinterIC *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_PlayGDIScriptOnPrinterIC +*/ +static WERROR dcesrv_spoolss_PlayGDIScriptOnPrinterIC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_PlayGDIScriptOnPrinterIC *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_DeletePrinterIC +*/ +static WERROR dcesrv_spoolss_DeletePrinterIC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeletePrinterIC *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_AddPrinterConnection +*/ +static WERROR dcesrv_spoolss_AddPrinterConnection(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AddPrinterConnection *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_DeletePrinterConnection +*/ +static WERROR dcesrv_spoolss_DeletePrinterConnection(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeletePrinterConnection *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_PrinterMessageBox +*/ +static WERROR dcesrv_spoolss_PrinterMessageBox(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_PrinterMessageBox *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_AddMonitor +*/ +static WERROR dcesrv_spoolss_AddMonitor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AddMonitor *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_DeleteMonitor +*/ +static WERROR dcesrv_spoolss_DeleteMonitor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeleteMonitor *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_DeletePrintProcessor +*/ +static WERROR dcesrv_spoolss_DeletePrintProcessor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeletePrintProcessor *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_AddPrintProvidor +*/ +static WERROR dcesrv_spoolss_AddPrintProvidor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AddPrintProvidor *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_DeletePrintProvidor +*/ +static WERROR dcesrv_spoolss_DeletePrintProvidor(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeletePrintProvidor *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_EnumPrintProcDataTypes +*/ +static WERROR dcesrv_spoolss_EnumPrintProcDataTypes(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EnumPrintProcDataTypes *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_ResetPrinter +*/ +static WERROR dcesrv_spoolss_ResetPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_ResetPrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_GetPrinterDriver2 +*/ +static WERROR dcesrv_spoolss_GetPrinterDriver2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrinterDriver2 *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_FindFirstPrinterChangeNotification +*/ +static WERROR dcesrv_spoolss_FindFirstPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_FindFirstPrinterChangeNotification *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_FindNextPrinterChangeNotification +*/ +static WERROR dcesrv_spoolss_FindNextPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_FindNextPrinterChangeNotification *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_FindClosePrinterNotify +*/ +static WERROR dcesrv_spoolss_FindClosePrinterNotify(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_FindClosePrinterNotify *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_RouterFindFirstPrinterChangeNotificationOld +*/ +static WERROR dcesrv_spoolss_RouterFindFirstPrinterChangeNotificationOld(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_ReplyOpenPrinter +*/ +static WERROR dcesrv_spoolss_ReplyOpenPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_ReplyOpenPrinter *r) +{ + struct dcesrv_handle *handle; + + handle = dcesrv_handle_new(dce_call->context, SPOOLSS_NOTIFY); + W_ERROR_HAVE_NO_MEMORY(handle); + + /* For now, just return a handle */ + + *r->out.handle = handle->wire_handle; + + return WERR_OK; +} + + +/* + spoolss_RouterReplyPrinter +*/ +static WERROR dcesrv_spoolss_RouterReplyPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_RouterReplyPrinter *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_ReplyClosePrinter +*/ +static WERROR dcesrv_spoolss_ReplyClosePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_ReplyClosePrinter *r) +{ + struct dcesrv_handle *handle; + + DCESRV_PULL_HANDLE_WERR(handle, r->in.handle, SPOOLSS_NOTIFY); + + talloc_free(handle); + + ZERO_STRUCTP(r->out.handle); + + return WERR_OK; +} + +/* + spoolss_AddPortEx +*/ +static WERROR dcesrv_spoolss_AddPortEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AddPortEx *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_RouterFindFirstPrinterChangeNotification +*/ +static WERROR dcesrv_spoolss_RouterFindFirstPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_RouterFindFirstPrinterChangeNotification *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_SpoolerInit +*/ +static WERROR dcesrv_spoolss_SpoolerInit(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_SpoolerInit *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_ResetPrinterEx +*/ +static WERROR dcesrv_spoolss_ResetPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_ResetPrinterEx *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_RemoteFindFirstPrinterChangeNotifyEx +*/ +static WERROR dcesrv_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r) +{ + struct dcerpc_pipe *p; + struct dcerpc_binding *binding; + NTSTATUS status; + struct spoolss_ReplyOpenPrinter rop; + struct cli_credentials *creds; + struct policy_handle notify_handle; + + DEBUG(2, ("Received RFFPCNex from %s\n", r->in.str)); + + /* + * TODO: for now just open a connection to the client and drop it again + * to keep the w2k3 PrintServer + * happy to allow to open the Add Printer GUI + * and the torture suite passing + */ + + binding = talloc_zero(mem_ctx, struct dcerpc_binding); + + binding->transport = NCACN_NP; + if (strncmp(r->in.str, "\\\\", 2)) + return WERR_INVALID_COMPUTERNAME; + binding->host = r->in.str+2; + + creds = cli_credentials_init_anon(mem_ctx); /* FIXME: Use machine credentials instead ? */ + + status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_spoolss, + creds, dce_call->event_ctx, + dce_call->conn->dce_ctx->lp_ctx); + + if (NT_STATUS_IS_ERR(status)) { + DEBUG(0, ("unable to call back to %s\n", r->in.str)); + return WERR_SERVER_UNAVAILABLE; + } + + ZERO_STRUCT(rop); + rop.in.server_name = lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx); + W_ERROR_HAVE_NO_MEMORY(rop.in.server_name); + rop.in.printer_local = 0; + rop.in.type = REG_NONE; + rop.in.unknown1 = 0; + rop.in.unknown2 = 0; + rop.out.handle = ¬ify_handle; + + status = dcerpc_spoolss_ReplyOpenPrinter(p, mem_ctx, &rop); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(0, ("unable to open remote printer %s\n", r->in.str)); + return WERR_SERVER_UNAVAILABLE; + } + + talloc_free(p); + + return WERR_OK; +} + + +/* + spoolss_RouterRefreshPrinterChangeNotification +*/ +static WERROR dcesrv_spoolss_RouterRefreshPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_RouterRefreshPrinterChangeNotification *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_RemoteFindNextPrinterChangeNotifyEx +*/ +static WERROR dcesrv_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_44 +*/ +static WERROR dcesrv_spoolss_44(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_44 *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + +/* + spoolss_OpenPrinterEx +*/ +static WERROR dcesrv_spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_OpenPrinterEx *r) +{ + struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context); + struct ntptr_GenericHandle *handle; + struct dcesrv_handle *h; + const char *server; + const char *object; + enum ntptr_HandleType type; + WERROR status; + + ZERO_STRUCTP(r->out.handle); + + status = dcesrv_spoolss_parse_printer_name(mem_ctx, r->in.printername, &server, &object, &type); + W_ERROR_NOT_OK_RETURN(status); + + status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, server); + W_ERROR_NOT_OK_RETURN(status); + + switch (type) { + case NTPTR_HANDLE_SERVER: + status = ntptr_OpenPrintServer(ntptr, mem_ctx, r, server, &handle); + W_ERROR_NOT_OK_RETURN(status); + break; + case NTPTR_HANDLE_PORT: + status = ntptr_OpenPort(ntptr, mem_ctx, r, object, &handle); + W_ERROR_NOT_OK_RETURN(status); + break; + case NTPTR_HANDLE_MONITOR: + status = ntptr_OpenMonitor(ntptr, mem_ctx, r, object, &handle); + W_ERROR_NOT_OK_RETURN(status); + break; + case NTPTR_HANDLE_PRINTER: + status = ntptr_OpenPrinter(ntptr, mem_ctx, r, object, &handle); + W_ERROR_NOT_OK_RETURN(status); + break; + default: + return WERR_FOOBAR; + } + + h = dcesrv_handle_new(dce_call->context, handle->type); + W_ERROR_HAVE_NO_MEMORY(h); + + h->data = talloc_steal(h, handle); + + *r->out.handle = h->wire_handle; + + return WERR_OK; +} + +/* + spoolss_AddPrinterEx +*/ +static WERROR dcesrv_spoolss_AddPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AddPrinterEx *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_47 +*/ +static WERROR dcesrv_spoolss_47(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_47 *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_EnumPrinterData +*/ +static WERROR dcesrv_spoolss_EnumPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EnumPrinterData *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_DeletePrinterData +*/ +static WERROR dcesrv_spoolss_DeletePrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeletePrinterData *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_4a +*/ +static WERROR dcesrv_spoolss_4a(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_4a *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_4b +*/ +static WERROR dcesrv_spoolss_4b(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_4b *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_4c +*/ +static WERROR dcesrv_spoolss_4c(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_4c *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_SetPrinterDataEx +*/ +static WERROR dcesrv_spoolss_SetPrinterDataEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_SetPrinterDataEx *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_GetPrinterDataEx +*/ +static WERROR dcesrv_spoolss_GetPrinterDataEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrinterDataEx *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_EnumPrinterDataEx +*/ +static WERROR dcesrv_spoolss_EnumPrinterDataEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EnumPrinterDataEx *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_EnumPrinterKey +*/ +static WERROR dcesrv_spoolss_EnumPrinterKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EnumPrinterKey *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_DeletePrinterDataEx +*/ +static WERROR dcesrv_spoolss_DeletePrinterDataEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeletePrinterDataEx *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_DeletePrinterKey +*/ +static WERROR dcesrv_spoolss_DeletePrinterKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeletePrinterKey *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_53 +*/ +static WERROR dcesrv_spoolss_53(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_53 *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_DeletePrinterDriverEx +*/ +static WERROR dcesrv_spoolss_DeletePrinterDriverEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_DeletePrinterDriverEx *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_55 +*/ +static WERROR dcesrv_spoolss_55(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_55 *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_56 +*/ +static WERROR dcesrv_spoolss_56(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_56 *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_57 +*/ +static WERROR dcesrv_spoolss_57(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_57 *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_XcvData +*/ +static WERROR dcesrv_spoolss_XcvData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_XcvData *r) +{ + struct ntptr_GenericHandle *handle; + struct dcesrv_handle *h; + WERROR status; + + DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); + handle = talloc_get_type(h->data, struct ntptr_GenericHandle); + + switch (handle->type) { + case NTPTR_HANDLE_SERVER: + status = ntptr_XcvDataPrintServer(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + case NTPTR_HANDLE_PRINTER: + status = ntptr_XcvDataPrinter(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + case NTPTR_HANDLE_PORT: + status = ntptr_XcvDataPort(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + case NTPTR_HANDLE_MONITOR: + status = ntptr_XcvDataMonitor(handle, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + break; + default: + return WERR_FOOBAR; + } + + /* TODO: handle the buffer sizes here! */ + return WERR_OK; +} + + +/* + spoolss_AddPrinterDriverEx +*/ +static WERROR dcesrv_spoolss_AddPrinterDriverEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_AddPrinterDriverEx *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_5a +*/ +static WERROR dcesrv_spoolss_5a(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_5a *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_5b +*/ +static WERROR dcesrv_spoolss_5b(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_5b *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_5c +*/ +static WERROR dcesrv_spoolss_5c(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_5c *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_5d +*/ +static WERROR dcesrv_spoolss_5d(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_5d *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_5e +*/ +static WERROR dcesrv_spoolss_5e(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_5e *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* + spoolss_5f +*/ +static WERROR dcesrv_spoolss_5f(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_5f *r) +{ + DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); +} + + +/* include the generated boilerplate */ +#include "librpc/gen_ndr/ndr_spoolss_s.c" |