dcesrv_spoolss.c
来自「samba最新软件」· C语言 代码 · 共 1,561 行 · 第 1/3 页
C
1,561 行
/* 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,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?