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 + -
显示快捷键?