mirror of
https://github.com/samba-team/samba.git
synced 2025-11-09 20:23:51 +03:00
r7643: This patch adds a new NTPTR subsystem:
- this is an abstraction layer for print services, like out NTVFS subsystem for file services - all protocol specific details are still in rpc_server/spoolss/ - like the stupid in and out Buffer handling - checking of the r->in.server_name - ... - this subsystem can have multiple implementation selected by the "ntptr providor" global-section parameter - I currently added a "simple_ldb" backend, that stores Printers, Forms, Ports, Monitors, ... in the spoolss.db, and does no real printing this backend is basicly for testing, how the spoolss protocol works - the interface is just a prototype and will be changed a bit the next days or weeks, till the simple_ldb backend can handle all calls that are used by normal w2k3/xp clients - I'll also make the api async, as the ntvfs api this will make things like the RemoteFindFirstPrinterChangeNotifyEx(), that opens a connection back to the client, easier to implement, as we should not block the whole smbd for that - the idea is to later implement a "unix" backend that works like the current samba3 code - and maybe some embedded print server vendors can write there own backend that can directly talk to a printer without having cups or something like this - the default settings are (it currently makes no sense to change them :-): ntptr providor = simple_ldb spoolss database = $private_dir/spoolss.db metze
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
fddfe1f04b
commit
455b5536d4
@@ -38,6 +38,7 @@ utils/config.mk
|
|||||||
ntvfs/posix/config.mk
|
ntvfs/posix/config.mk
|
||||||
ntvfs/config.mk
|
ntvfs/config.mk
|
||||||
ntvfs/unixuid/config.mk
|
ntvfs/unixuid/config.mk
|
||||||
|
ntptr/config.mk
|
||||||
torture/config.mk
|
torture/config.mk
|
||||||
librpc/config.mk
|
librpc/config.mk
|
||||||
client/config.mk
|
client/config.mk
|
||||||
|
|||||||
@@ -37,8 +37,43 @@ union spoolss_FormInfo;
|
|||||||
union spoolss_PortInfo;
|
union spoolss_PortInfo;
|
||||||
union spoolss_MonitorInfo;
|
union spoolss_MonitorInfo;
|
||||||
union spoolss_PrintProcessorInfo;
|
union spoolss_PrintProcessorInfo;
|
||||||
|
|
||||||
struct spoolss_GetPrinterData;
|
struct spoolss_GetPrinterData;
|
||||||
struct spoolss_SetPrinterData;
|
struct spoolss_SetPrinterData;
|
||||||
|
struct spoolss_OpenPrinterEx;
|
||||||
|
struct spoolss_EnumPrinterData;
|
||||||
|
struct spoolss_DeletePrinterData;
|
||||||
|
struct spoolss_AddForm;
|
||||||
|
struct spoolss_GetForm;
|
||||||
|
struct spoolss_SetForm;
|
||||||
|
struct spoolss_DeleteForm;
|
||||||
|
struct spoolss_AddPrinterDriver;
|
||||||
|
struct spoolss_DeletePrinterDriver;
|
||||||
|
struct spoolss_GetPrinterDriverDirectory;
|
||||||
|
struct spoolss_AddPrinter;
|
||||||
|
struct spoolss_GetPrinter;
|
||||||
|
struct spoolss_SetPrinter;
|
||||||
|
struct spoolss_DeletePrinter;
|
||||||
|
struct spoolss_GetPrinterDriver;
|
||||||
|
struct spoolss_EnumPrinterData;
|
||||||
|
struct spoolss_DeletePrinterData;
|
||||||
|
struct spoolss_AddForm;
|
||||||
|
struct spoolss_GetForm;
|
||||||
|
struct spoolss_SetForm;
|
||||||
|
struct spoolss_DeleteForm;
|
||||||
|
struct spoolss_AddJob;
|
||||||
|
struct spoolss_ScheduleJob;
|
||||||
|
struct spoolss_GetJob;
|
||||||
|
struct spoolss_SetJob;
|
||||||
|
struct spoolss_StartDocPrinter;
|
||||||
|
struct spoolss_EndDocPrinter;
|
||||||
|
struct spoolss_StartPagePrinter;
|
||||||
|
struct spoolss_EndPagePrinter;
|
||||||
|
struct spoolss_WritePrinter;
|
||||||
|
struct spoolss_ReadPrinter;
|
||||||
|
|
||||||
|
struct ntptr_context;
|
||||||
|
struct ntptr_GenericHandle;
|
||||||
|
|
||||||
struct drsuapi_DsReplicaObjectListItem;
|
struct drsuapi_DsReplicaObjectListItem;
|
||||||
struct drsuapi_DsReplicaObjectListItemEx;
|
struct drsuapi_DsReplicaObjectListItemEx;
|
||||||
|
|||||||
@@ -878,7 +878,7 @@
|
|||||||
[in,switch_is(level)] spoolss_SetFormInfo info
|
[in,switch_is(level)] spoolss_SetFormInfo info
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef [nodiscriminant,relative_base,public] union {
|
typedef [nodiscriminant,relative_base,public,gensize] union {
|
||||||
[case(1)] spoolss_FormInfo1 info1;
|
[case(1)] spoolss_FormInfo1 info1;
|
||||||
[default];
|
[default];
|
||||||
} spoolss_FormInfo;
|
} spoolss_FormInfo;
|
||||||
|
|||||||
24
source/ntptr/config.mk
Normal file
24
source/ntptr/config.mk
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# NTPTR Server subsystem
|
||||||
|
|
||||||
|
################################################
|
||||||
|
# Start MODULE ntptr_simple_ldb
|
||||||
|
[MODULE::ntptr_simple_ldb]
|
||||||
|
INIT_FUNCTION = ntptr_simple_ldb_init
|
||||||
|
SUBSYSTEM = NTPTR
|
||||||
|
INIT_OBJ_FILES = \
|
||||||
|
ntptr/simple_ldb/ntptr_simple_ldb.o
|
||||||
|
REQUIRED_SUBSYSTEMS = \
|
||||||
|
LIBLDB
|
||||||
|
# End MODULE ntptr_simple_ldb
|
||||||
|
################################################
|
||||||
|
|
||||||
|
################################################
|
||||||
|
# Start SUBSYSTEM NTPTR
|
||||||
|
[SUBSYSTEM::NTPTR]
|
||||||
|
INIT_OBJ_FILES = \
|
||||||
|
ntptr/ntptr_base.o
|
||||||
|
ADD_OBJ_FILES = \
|
||||||
|
ntptr/ntptr_interface.o
|
||||||
|
#
|
||||||
|
# End SUBSYSTEM NTPTR
|
||||||
|
################################################
|
||||||
189
source/ntptr/ntptr.h
Normal file
189
source/ntptr/ntptr.h
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
Unix SMB/CIFS implementation.
|
||||||
|
|
||||||
|
NTPTR structures and defines
|
||||||
|
|
||||||
|
Copyright (C) Stefan (metze) 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 2 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, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* modules can use the following to determine if the interface has changed */
|
||||||
|
#define NTPTR_INTERFACE_VERSION 0
|
||||||
|
|
||||||
|
struct ntptr_context;
|
||||||
|
|
||||||
|
enum ntptr_HandleType {
|
||||||
|
NTPTR_HANDLE_SERVER,
|
||||||
|
NTPTR_HANDLE_PRINTER,
|
||||||
|
NTPTR_HANDLE_PORT,
|
||||||
|
NTPTR_HANDLE_MONITOR
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ntptr_GenericHandle {
|
||||||
|
enum ntptr_HandleType type;
|
||||||
|
struct ntptr_context *ntptr;
|
||||||
|
uint32_t access_mask;
|
||||||
|
void *private_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* the ntptr operations structure - contains function pointers to
|
||||||
|
the backend implementations of each operation */
|
||||||
|
struct ntptr_ops {
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
/* initial setup */
|
||||||
|
NTSTATUS (*init_context)(struct ntptr_context *ntptr);
|
||||||
|
|
||||||
|
/* PrintServer functions */
|
||||||
|
WERROR (*OpenPrintServer)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_OpenPrinterEx *r,
|
||||||
|
const char *printer_name,
|
||||||
|
struct ntptr_GenericHandle **server);
|
||||||
|
|
||||||
|
/* PrintServer PrinterData functions */
|
||||||
|
WERROR (*EnumPrintServerData)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPrinterData *r);
|
||||||
|
WERROR (*GetPrintServerData)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetPrinterData *r);
|
||||||
|
WERROR (*SetPrintServerData)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_SetPrinterData *r);
|
||||||
|
WERROR (*DeletePrintServerData)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_DeletePrinterData *r);
|
||||||
|
|
||||||
|
/* PrintServer Form functions */
|
||||||
|
WERROR (*EnumPrintServerForms)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumForms *r);
|
||||||
|
WERROR (*AddPrintServerForm)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_AddForm *r);
|
||||||
|
WERROR (*GetPrintServerForm)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetForm *r);
|
||||||
|
WERROR (*SetPrintServerForm)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_SetForm *r);
|
||||||
|
WERROR (*DeletePrintServerForm)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_DeleteForm *r);
|
||||||
|
|
||||||
|
/* PrintServer Driver functions */
|
||||||
|
WERROR (*EnumPrinterDrivers)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPrinterDrivers *r);
|
||||||
|
WERROR (*AddPrinterDriver)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_AddPrinterDriver *r);
|
||||||
|
WERROR (*DeletePrinterDriver)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_DeletePrinterDriver *r);
|
||||||
|
WERROR (*GetPrinterDriverDirectory)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetPrinterDriverDirectory *r);
|
||||||
|
|
||||||
|
/* Port functions */
|
||||||
|
WERROR (*EnumPorts)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPorts *r);
|
||||||
|
WERROR (*OpenPort)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_OpenPrinterEx *r,
|
||||||
|
const char *port_name,
|
||||||
|
struct ntptr_GenericHandle **prt);
|
||||||
|
|
||||||
|
/* Monitor functions */
|
||||||
|
WERROR (*EnumMonitors)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumMonitors *r);
|
||||||
|
WERROR (*OpenMonitor)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_OpenPrinterEx *r,
|
||||||
|
const char *monitor_name,
|
||||||
|
struct ntptr_GenericHandle **monitor);
|
||||||
|
|
||||||
|
/* PrintProcessor functions */
|
||||||
|
WERROR (*EnumPrintProcessors)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPrintProcessors *r);
|
||||||
|
|
||||||
|
/* Printer functions */
|
||||||
|
WERROR (*EnumPrinters)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPrinters *r);
|
||||||
|
WERROR (*OpenPrinter)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_OpenPrinterEx *r,
|
||||||
|
const char *printer_name,
|
||||||
|
struct ntptr_GenericHandle **printer);
|
||||||
|
WERROR (*AddPrinter)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_AddPrinter *r,
|
||||||
|
struct ntptr_GenericHandle **printer);
|
||||||
|
WERROR (*GetPrinter)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetPrinter *r);
|
||||||
|
WERROR (*SetPrinter)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_SetPrinter *r);
|
||||||
|
WERROR (*DeletePrinter)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_DeletePrinter *r);
|
||||||
|
|
||||||
|
/* Printer Driver functions */
|
||||||
|
WERROR (*GetPrinterDriver)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetPrinterDriver *r);
|
||||||
|
|
||||||
|
/* Printer PrinterData functions */
|
||||||
|
WERROR (*EnumPrinterData)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPrinterData *r);
|
||||||
|
WERROR (*GetPrinterData)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetPrinterData *r);
|
||||||
|
WERROR (*SetPrinterData)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_SetPrinterData *r);
|
||||||
|
WERROR (*DeletePrinterData)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_DeletePrinterData *r);
|
||||||
|
|
||||||
|
/* Printer Form functions */
|
||||||
|
WERROR (*EnumPrinterForms)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumForms *r);
|
||||||
|
WERROR (*AddPrinterForm)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_AddForm *r);
|
||||||
|
WERROR (*GetPrinterForm)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetForm *r);
|
||||||
|
WERROR (*SetPrinterForm)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_SetForm *r);
|
||||||
|
WERROR (*DeletePrinterForm)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_DeleteForm *r);
|
||||||
|
|
||||||
|
/* Printer Job functions */
|
||||||
|
WERROR (*EnumJobs)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumJobs *r);
|
||||||
|
WERROR (*AddJob)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_AddJob *r);
|
||||||
|
WERROR (*ScheduleJob)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_ScheduleJob *r);
|
||||||
|
WERROR (*GetJob)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetJob *r);
|
||||||
|
WERROR (*SetJob)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_SetJob *r);
|
||||||
|
|
||||||
|
/* Printer Printing functions */
|
||||||
|
WERROR (*StartDocPrinter)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_StartDocPrinter *r);
|
||||||
|
WERROR (*EndDocPrinter)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EndDocPrinter *r);
|
||||||
|
WERROR (*StartPagePrinter)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_StartPagePrinter *r);
|
||||||
|
WERROR (*EndPagePrinter)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EndPagePrinter *r);
|
||||||
|
WERROR (*WritePrinter)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_WritePrinter *r);
|
||||||
|
WERROR (*ReadPrinter)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_ReadPrinter *r);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ntptr_context {
|
||||||
|
const struct ntptr_ops *ops;
|
||||||
|
void *private_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* this structure is used by backends to determine the size of some critical types */
|
||||||
|
struct ntptr_critical_sizes {
|
||||||
|
int interface_version;
|
||||||
|
int sizeof_ntptr_critical_sizes;
|
||||||
|
int sizeof_ntptr_context;
|
||||||
|
int sizeof_ntptr_ops;
|
||||||
|
};
|
||||||
134
source/ntptr/ntptr_base.c
Normal file
134
source/ntptr/ntptr_base.c
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
Unix SMB/CIFS implementation.
|
||||||
|
|
||||||
|
NTPTR base code
|
||||||
|
|
||||||
|
Copyright (C) Stefan (metze) 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 2 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, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
this implements the core code for all NTPTR modules. Backends register themselves here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
#include "ntptr/ntptr.h"
|
||||||
|
#include "dlinklist.h"
|
||||||
|
|
||||||
|
/* the list of currently registered NTPTR backends */
|
||||||
|
static struct ntptr_backend {
|
||||||
|
const struct ntptr_ops *ops;
|
||||||
|
} *backends = NULL;
|
||||||
|
static int num_backends;
|
||||||
|
|
||||||
|
/*
|
||||||
|
register a NTPTR backend.
|
||||||
|
|
||||||
|
The 'name' can be later used by other backends to find the operations
|
||||||
|
structure for this backend.
|
||||||
|
*/
|
||||||
|
NTSTATUS ntptr_register(const void *_ops)
|
||||||
|
{
|
||||||
|
const struct ntptr_ops *ops = _ops;
|
||||||
|
struct ntptr_ops *new_ops;
|
||||||
|
|
||||||
|
if (ntptr_backend_byname(ops->name) != NULL) {
|
||||||
|
/* its already registered! */
|
||||||
|
DEBUG(0,("NTPTR backend '%s' already registered\n",
|
||||||
|
ops->name));
|
||||||
|
return NT_STATUS_OBJECT_NAME_COLLISION;
|
||||||
|
}
|
||||||
|
|
||||||
|
backends = realloc_p(backends, struct ntptr_backend, num_backends+1);
|
||||||
|
if (!backends) {
|
||||||
|
smb_panic("out of memory in ntptr_register");
|
||||||
|
}
|
||||||
|
|
||||||
|
new_ops = smb_xmemdup(ops, sizeof(*ops));
|
||||||
|
new_ops->name = smb_xstrdup(ops->name);
|
||||||
|
|
||||||
|
backends[num_backends].ops = new_ops;
|
||||||
|
|
||||||
|
num_backends++;
|
||||||
|
|
||||||
|
DEBUG(3,("NTPTR backend '%s'\n",
|
||||||
|
ops->name));
|
||||||
|
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
return the operations structure for a named backend
|
||||||
|
*/
|
||||||
|
const struct ntptr_ops *ntptr_backend_byname(const char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0;i<num_backends;i++) {
|
||||||
|
if (strcmp(backends[i].ops->name, name) == 0) {
|
||||||
|
return backends[i].ops;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
return the NTPTR interface version, and the size of some critical types
|
||||||
|
This can be used by backends to either detect compilation errors, or provide
|
||||||
|
multiple implementations for different smbd compilation options in one module
|
||||||
|
*/
|
||||||
|
static const struct ntptr_critical_sizes critical_sizes = {
|
||||||
|
.interface_version = NTPTR_INTERFACE_VERSION,
|
||||||
|
.sizeof_ntptr_critical_sizes = sizeof(struct ntptr_critical_sizes),
|
||||||
|
.sizeof_ntptr_context = sizeof(struct ntptr_context),
|
||||||
|
.sizeof_ntptr_ops = sizeof(struct ntptr_ops),
|
||||||
|
};
|
||||||
|
const struct ntptr_critical_sizes *ntptr_interface_version(void)
|
||||||
|
{
|
||||||
|
return &critical_sizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
create a ntptr_context with a specified NTPTR backend
|
||||||
|
*/
|
||||||
|
NTSTATUS ntptr_init_context(TALLOC_CTX *mem_ctx, const char *providor, struct ntptr_context **_ntptr)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
struct ntptr_context *ntptr;
|
||||||
|
|
||||||
|
if (!providor) {
|
||||||
|
return NT_STATUS_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ntptr = talloc(mem_ctx, struct ntptr_context);
|
||||||
|
NT_STATUS_HAVE_NO_MEMORY(ntptr);
|
||||||
|
ntptr->private_data = NULL;
|
||||||
|
ntptr->ops = ntptr_backend_byname(providor);
|
||||||
|
|
||||||
|
if (!ntptr->ops) {
|
||||||
|
DEBUG(1,("ntptr_init_context: failed to find NTPTR providor='%s'\n",
|
||||||
|
providor));
|
||||||
|
return NT_STATUS_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ntptr->ops->init_context(ntptr);
|
||||||
|
NT_STATUS_NOT_OK_RETURN(status);
|
||||||
|
|
||||||
|
*_ntptr = ntptr;
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
561
source/ntptr/ntptr_interface.c
Normal file
561
source/ntptr/ntptr_interface.c
Normal file
@@ -0,0 +1,561 @@
|
|||||||
|
/*
|
||||||
|
Unix SMB/CIFS implementation.
|
||||||
|
|
||||||
|
NTPTR interface functions
|
||||||
|
|
||||||
|
Copyright (C) Stefan (metze) 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 2 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, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
#include "ntptr/ntptr.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* PrintServer functions */
|
||||||
|
WERROR ntptr_OpenPrintServer(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_OpenPrinterEx *r,
|
||||||
|
const char *printer_name,
|
||||||
|
struct ntptr_GenericHandle **server)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->OpenPrintServer) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->OpenPrintServer(ntptr, mem_ctx, r, printer_name, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* PrintServer PrinterData functions */
|
||||||
|
WERROR ntptr_EnumPrintServerData(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPrinterData *r)
|
||||||
|
{
|
||||||
|
if (server->type != NTPTR_HANDLE_SERVER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!server->ntptr->ops->EnumPrintServerData) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return server->ntptr->ops->EnumPrintServerData(server, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetPrinterData *r)
|
||||||
|
{
|
||||||
|
if (server->type != NTPTR_HANDLE_SERVER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!server->ntptr->ops->GetPrintServerData) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return server->ntptr->ops->GetPrintServerData(server, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_SetPrintServerData(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_SetPrinterData *r)
|
||||||
|
{
|
||||||
|
if (server->type != NTPTR_HANDLE_SERVER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!server->ntptr->ops->SetPrintServerData) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return server->ntptr->ops->SetPrintServerData(server, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_DeletePrintServerData(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_DeletePrinterData *r)
|
||||||
|
{
|
||||||
|
if (server->type != NTPTR_HANDLE_SERVER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!server->ntptr->ops->DeletePrintServerData) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return server->ntptr->ops->DeletePrintServerData(server, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* PrintServer Form functions */
|
||||||
|
WERROR ntptr_EnumPrintServerForms(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumForms *r)
|
||||||
|
{
|
||||||
|
if (server->type != NTPTR_HANDLE_SERVER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!server->ntptr->ops->EnumPrintServerForms) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return server->ntptr->ops->EnumPrintServerForms(server, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_AddPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_AddForm *r)
|
||||||
|
{
|
||||||
|
if (server->type != NTPTR_HANDLE_SERVER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!server->ntptr->ops->AddPrintServerForm) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return server->ntptr->ops->AddPrintServerForm(server, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_GetPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetForm *r)
|
||||||
|
{
|
||||||
|
if (server->type != NTPTR_HANDLE_SERVER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!server->ntptr->ops->GetPrintServerForm) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return server->ntptr->ops->GetPrintServerForm(server, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_SetPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_SetForm *r)
|
||||||
|
{
|
||||||
|
if (server->type != NTPTR_HANDLE_SERVER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!server->ntptr->ops->SetPrintServerForm) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return server->ntptr->ops->SetPrintServerForm(server, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_DeletePrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_DeleteForm *r)
|
||||||
|
{
|
||||||
|
if (server->type != NTPTR_HANDLE_SERVER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!server->ntptr->ops->DeletePrintServerForm) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return server->ntptr->ops->DeletePrintServerForm(server, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* PrintServer Driver functions */
|
||||||
|
WERROR ntptr_EnumPrinterDrivers(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPrinterDrivers *r)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->EnumPrinterDrivers) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->EnumPrinterDrivers(ntptr, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_AddPrinterDriver(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_AddPrinterDriver *r)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->AddPrinterDriver) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->AddPrinterDriver(ntptr, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_DeletePrinterDriver(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_DeletePrinterDriver *r)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->DeletePrinterDriver) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->DeletePrinterDriver(ntptr, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_GetPrinterDriverDirectory(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetPrinterDriverDirectory *r)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->GetPrinterDriverDirectory) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->GetPrinterDriverDirectory(ntptr, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Port functions */
|
||||||
|
WERROR ntptr_EnumPorts(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPorts *r)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->EnumPorts) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->EnumPorts(ntptr, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_OpenPort(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_OpenPrinterEx *r,
|
||||||
|
const char *port_name,
|
||||||
|
struct ntptr_GenericHandle **prt)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->OpenPort) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->OpenPort(ntptr, mem_ctx, r, port_name, prt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Monitor functions */
|
||||||
|
WERROR ntptr_EnumMonitors(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumMonitors *r)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->EnumMonitors) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->EnumMonitors(ntptr, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_OpenMonitor(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_OpenPrinterEx *r,
|
||||||
|
const char *monitor_name,
|
||||||
|
struct ntptr_GenericHandle **monitor)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->OpenMonitor) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->OpenMonitor(ntptr, mem_ctx, r, monitor_name, monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* PrintProcessor functions */
|
||||||
|
WERROR ntptr_EnumPrintProcessors(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPrintProcessors *r)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->EnumPrintProcessors) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->EnumPrintProcessors(ntptr, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Printer functions */
|
||||||
|
WERROR ntptr_EnumPrinters(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPrinters *r)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->EnumPrinters) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->EnumPrinters(ntptr, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_OpenPrinter(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_OpenPrinterEx *r,
|
||||||
|
const char *printer_name,
|
||||||
|
struct ntptr_GenericHandle **printer)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->OpenPrinter) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->OpenPrinter(ntptr, mem_ctx, r, printer_name, printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_AddPrinter(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_AddPrinter *r,
|
||||||
|
struct ntptr_GenericHandle **printer)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->AddPrinter) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->AddPrinter(ntptr, mem_ctx, r, printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_GetPrinter(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetPrinter *r)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->GetPrinter) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->GetPrinter(ntptr, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_SetPrinter(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_SetPrinter *r)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->SetPrinter) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->SetPrinter(ntptr, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_DeletePrinter(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_DeletePrinter *r)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->DeletePrinter) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->DeletePrinter(ntptr, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Printer Driver functions */
|
||||||
|
WERROR ntptr_GetPrinterDriver(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetPrinterDriver *r)
|
||||||
|
{
|
||||||
|
if (!ntptr->ops->GetPrinterDriver) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return ntptr->ops->GetPrinterDriver(ntptr, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Printer PrinterData functions */
|
||||||
|
WERROR ntptr_EnumPrinterData(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPrinterData *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->EnumPrinterData) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->EnumPrinterData(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_GetPrinterData(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetPrinterData *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->GetPrinterData) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->GetPrinterData(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_SetPrinterData(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_SetPrinterData *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->SetPrinterData) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->SetPrinterData(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_DeletePrinterData(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_DeletePrinterData *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->DeletePrinterData) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->DeletePrinterData(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Printer Form functions */
|
||||||
|
WERROR ntptr_EnumPrinterForms(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumForms *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->EnumPrinterForms) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->EnumPrinterForms(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_AddPrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_AddForm *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->AddPrinterForm) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->AddPrinterForm(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_GetPrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetForm *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->GetPrinterForm) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->GetPrinterForm(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_SetPrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_SetForm *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->SetPrinterForm) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->SetPrinterForm(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_DeletePrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_DeleteForm *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->DeletePrinterForm) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->DeletePrinterForm(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Printer Job functions */
|
||||||
|
WERROR ntptr_EnumJobs(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumJobs *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->EnumJobs) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->EnumJobs(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_AddJob(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_AddJob *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->AddJob) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->AddJob(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_ScheduleJob(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_ScheduleJob *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->ScheduleJob) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->ScheduleJob(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_GetJob(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetJob *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->GetJob) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->GetJob(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_SetJob(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_SetJob *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->SetJob) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->SetJob(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Printer Printing functions */
|
||||||
|
WERROR ntptr_StartDocPrinter(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_StartDocPrinter *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->StartDocPrinter) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->StartDocPrinter(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_EndDocPrinter(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EndDocPrinter *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->EndDocPrinter) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->EndDocPrinter(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_StartPagePrinter(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_StartPagePrinter *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->StartPagePrinter) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->StartPagePrinter(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_EndPagePrinter(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EndPagePrinter *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->EndPagePrinter) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->EndPagePrinter(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_WritePrinter(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_WritePrinter *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->WritePrinter) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->WritePrinter(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR ntptr_ReadPrinter(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_ReadPrinter *r)
|
||||||
|
{
|
||||||
|
if (printer->type != NTPTR_HANDLE_PRINTER) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
if (!printer->ntptr->ops->ReadPrinter) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return printer->ntptr->ops->ReadPrinter(printer, mem_ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
596
source/ntptr/simple_ldb/ntptr_simple_ldb.c
Normal file
596
source/ntptr/simple_ldb/ntptr_simple_ldb.c
Normal file
@@ -0,0 +1,596 @@
|
|||||||
|
/*
|
||||||
|
Unix SMB/CIFS implementation.
|
||||||
|
|
||||||
|
Simple LDB NTPTR backend
|
||||||
|
|
||||||
|
Copyright (C) Stefan (metze) 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 2 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, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
This implements a NTPTR backend that store
|
||||||
|
all objects (Printers, Ports, Monitors, PrinterDrivers ...)
|
||||||
|
in a ldb database, but doesn't do real printing.
|
||||||
|
|
||||||
|
This is just used for testing how some of
|
||||||
|
the SPOOLSS protocol details should work
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
#include "ntptr/ntptr.h"
|
||||||
|
#include "librpc/gen_ndr/ndr_spoolss.h"
|
||||||
|
#include "lib/ldb/include/ldb.h"
|
||||||
|
#include "db_wrap.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
connect to the SPOOLSS database
|
||||||
|
return a ldb_context pointer on success, or NULL on failure
|
||||||
|
*/
|
||||||
|
static struct ldb_context *sptr_db_connect(TALLOC_CTX *mem_ctx)
|
||||||
|
{
|
||||||
|
return ldb_wrap_connect(mem_ctx, lp_spoolss_url(), 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sptr_db_search(struct ldb_context *ldb,
|
||||||
|
TALLOC_CTX *mem_ctx,
|
||||||
|
const char *basedn,
|
||||||
|
struct ldb_message ***res,
|
||||||
|
const char * const *attrs,
|
||||||
|
const char *format, ...) PRINTF_ATTRIBUTE(6,7);
|
||||||
|
|
||||||
|
static int sptr_db_search(struct ldb_context *ldb,
|
||||||
|
TALLOC_CTX *mem_ctx,
|
||||||
|
const char *basedn,
|
||||||
|
struct ldb_message ***res,
|
||||||
|
const char * const *attrs,
|
||||||
|
const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
count = gendb_search_v(ldb, mem_ctx, basedn, res, attrs, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS sptr_init_context(struct ntptr_context *ntptr)
|
||||||
|
{
|
||||||
|
struct ldb_context *sptr_db = sptr_db_connect(ntptr);
|
||||||
|
NT_STATUS_HAVE_NO_MEMORY(sptr_db);
|
||||||
|
|
||||||
|
ntptr->private_data = sptr_db;
|
||||||
|
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PrintServer functions */
|
||||||
|
static WERROR sptr_OpenPrintServer(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_OpenPrinterEx *r,
|
||||||
|
const char *server_name,
|
||||||
|
struct ntptr_GenericHandle **_server)
|
||||||
|
{
|
||||||
|
struct ntptr_GenericHandle *server;
|
||||||
|
|
||||||
|
/* TODO: do access check here! */
|
||||||
|
|
||||||
|
server = talloc(mem_ctx, struct ntptr_GenericHandle);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(server);
|
||||||
|
|
||||||
|
server->type = NTPTR_HANDLE_SERVER;
|
||||||
|
server->ntptr = ntptr;
|
||||||
|
server->access_mask = r->in.access_mask;
|
||||||
|
server->private_data = NULL;
|
||||||
|
|
||||||
|
*_server = server;
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PrintServer PrinterData functions
|
||||||
|
*/
|
||||||
|
static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetPrinterData *r)
|
||||||
|
{
|
||||||
|
if (strcmp("W3SvcInstalled", r->in.value_name) == 0) {
|
||||||
|
r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
||||||
|
r->out.data.value = 0;
|
||||||
|
return WERR_OK;
|
||||||
|
} else if (strcmp("BeepEnabled", r->in.value_name) == 0) {
|
||||||
|
r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
||||||
|
r->out.data.value = 0;
|
||||||
|
return WERR_OK;
|
||||||
|
} else if (strcmp("EventLog", r->in.value_name) == 0) {
|
||||||
|
r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
||||||
|
r->out.data.value = 0;
|
||||||
|
return WERR_OK;
|
||||||
|
} else if (strcmp("NetPopup", r->in.value_name) == 0) {
|
||||||
|
r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
||||||
|
r->out.data.value = 0;
|
||||||
|
return WERR_OK;
|
||||||
|
} else if (strcmp("NetPopupToComputer", r->in.value_name) == 0) {
|
||||||
|
r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
||||||
|
r->out.data.value = 0;
|
||||||
|
return WERR_OK;
|
||||||
|
} else if (strcmp("MajorVersion", r->in.value_name) == 0) {
|
||||||
|
r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
||||||
|
r->out.data.value = 3;
|
||||||
|
return WERR_OK;
|
||||||
|
} else if (strcmp("MinorVersion", r->in.value_name) == 0) {
|
||||||
|
r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
||||||
|
r->out.data.value = 0;
|
||||||
|
return WERR_OK;
|
||||||
|
} else if (strcmp("DefaultSpoolDirectory", r->in.value_name) == 0) {
|
||||||
|
r->out.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
|
||||||
|
r->out.data.string = "C:\\PRINTERS";
|
||||||
|
return WERR_OK;
|
||||||
|
} else if (strcmp("Architecture", r->in.value_name) == 0) {
|
||||||
|
r->out.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
|
||||||
|
r->out.data.string = SPOOLSS_ARCHITECTURE_NT_X86;
|
||||||
|
return WERR_OK;
|
||||||
|
} else if (strcmp("DsPresent", r->in.value_name) == 0) {
|
||||||
|
r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
||||||
|
r->out.data.value = 1;
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WERR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PrintServer Form functions */
|
||||||
|
static WERROR sptr_EnumPrintServerForms(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumForms *r)
|
||||||
|
{
|
||||||
|
struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
|
||||||
|
struct ldb_message **msgs;
|
||||||
|
int count;
|
||||||
|
int i;
|
||||||
|
union spoolss_FormInfo *info;
|
||||||
|
|
||||||
|
count = sptr_db_search(sptr_db, mem_ctx, "CN=PrintServer", &msgs, NULL,
|
||||||
|
"(&(objectclass=form))");
|
||||||
|
|
||||||
|
if (count == 0) return WERR_OK;
|
||||||
|
if (count < 0) return WERR_GENERAL_FAILURE;
|
||||||
|
|
||||||
|
info = talloc_array(mem_ctx, union spoolss_FormInfo, count);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info);
|
||||||
|
|
||||||
|
switch (r->in.level) {
|
||||||
|
case 1:
|
||||||
|
for (i=0; i < count; i++) {
|
||||||
|
info[i].info1.flags = samdb_result_uint(msgs[i], "flags", SPOOLSS_FORM_PRINTER);
|
||||||
|
|
||||||
|
info[i].info1.form_name = samdb_result_string(msgs[i], "form_name", "Letter");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info1.form_name);
|
||||||
|
|
||||||
|
info[i].info1.size.width = samdb_result_uint(msgs[i], "size_widgth", 0x34b5c);
|
||||||
|
info[i].info1.size.height = samdb_result_uint(msgs[i], "size_height", 0x44368);
|
||||||
|
|
||||||
|
info[i].info1.area.left = samdb_result_uint(msgs[i], "area_left", 0);
|
||||||
|
info[i].info1.area.top = samdb_result_uint(msgs[i], "area_top", 0);
|
||||||
|
info[i].info1.area.right = samdb_result_uint(msgs[i], "are_right", 0x34b5c);
|
||||||
|
info[i].info1.area.bottom = samdb_result_uint(msgs[i], "area_bottom", 0x44368);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return WERR_UNKNOWN_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->out.info = info;
|
||||||
|
r->out.count = count;
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WERROR sptr_GetPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetForm *r)
|
||||||
|
{
|
||||||
|
struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
|
||||||
|
struct ldb_message **msgs;
|
||||||
|
int count;
|
||||||
|
union spoolss_FormInfo *info;
|
||||||
|
|
||||||
|
count = sptr_db_search(sptr_db, mem_ctx, "CN=PrintServer", &msgs, NULL,
|
||||||
|
"(&(form_name=%s)(objectclass=form))",
|
||||||
|
r->in.form_name);
|
||||||
|
|
||||||
|
if (count == 0) return WERR_FOOBAR;
|
||||||
|
if (count > 1) return WERR_FOOBAR;
|
||||||
|
if (count < 0) return WERR_GENERAL_FAILURE;
|
||||||
|
|
||||||
|
info = talloc(mem_ctx, union spoolss_FormInfo);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info);
|
||||||
|
|
||||||
|
switch (r->in.level) {
|
||||||
|
case 1:
|
||||||
|
info->info1.flags = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_PRINTER);
|
||||||
|
|
||||||
|
info->info1.form_name = samdb_result_string(msgs[0], "form_name", "Letter");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info->info1.form_name);
|
||||||
|
|
||||||
|
info->info1.size.width = samdb_result_uint(msgs[0], "size_widgth", 0x34b5c);
|
||||||
|
info->info1.size.height = samdb_result_uint(msgs[0], "size_height", 0x44368);
|
||||||
|
|
||||||
|
info->info1.area.left = samdb_result_uint(msgs[0], "area_left", 0);
|
||||||
|
info->info1.area.top = samdb_result_uint(msgs[0], "area_top", 0);
|
||||||
|
info->info1.area.right = samdb_result_uint(msgs[0], "are_right", 0x34b5c);
|
||||||
|
info->info1.area.bottom = samdb_result_uint(msgs[0], "area_bottom", 0x44368);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return WERR_UNKNOWN_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->out.info = info;
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PrintServer Driver functions */
|
||||||
|
static WERROR sptr_EnumPrinterDrivers(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPrinterDrivers *r)
|
||||||
|
{
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WERROR sptr_GetPrinterDriverDirectory(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_GetPrinterDriverDirectory *r)
|
||||||
|
{
|
||||||
|
union spoolss_DriverDirectoryInfo *info;
|
||||||
|
const char *prefix;
|
||||||
|
const char *postfix;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: normally r->in.level is 1, but both w2k3 and nt4 sp6a
|
||||||
|
* are ignoring the r->in.level completely, so we do :-)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: check the server name is ours
|
||||||
|
* - if it's a invalid UNC then return WERR_INVALID_NAME
|
||||||
|
* - if it's the wrong host name return WERR_INVALID_PARAM
|
||||||
|
* - if it's "" then we need to return a local WINDOWS path
|
||||||
|
*/
|
||||||
|
if (!r->in.server || !r->in.server[0]) {
|
||||||
|
prefix = "C:\\DRIVERS";
|
||||||
|
} else {
|
||||||
|
prefix = talloc_asprintf(mem_ctx, "%s\\print$", r->in.server);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->in.environment && strcmp(SPOOLSS_ARCHITECTURE_NT_X86, r->in.environment) == 0) {
|
||||||
|
postfix = "W32X86";
|
||||||
|
} else {
|
||||||
|
return WERR_INVALID_ENVIRONMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = talloc(mem_ctx, union spoolss_DriverDirectoryInfo);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info);
|
||||||
|
|
||||||
|
info->info1.directory_name = talloc_asprintf(mem_ctx, "%s\\%s", prefix, postfix);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info->info1.directory_name);
|
||||||
|
|
||||||
|
r->out.info = info;
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Printer functions */
|
||||||
|
static WERROR sptr_EnumPrinters(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPrinters *r)
|
||||||
|
{
|
||||||
|
struct ldb_context *sptr_db = talloc_get_type(ntptr->private_data, struct ldb_context);
|
||||||
|
struct ldb_message **msgs;
|
||||||
|
int count;
|
||||||
|
int i;
|
||||||
|
union spoolss_PrinterInfo *info;
|
||||||
|
|
||||||
|
count = sptr_db_search(sptr_db, mem_ctx, NULL, &msgs, NULL,
|
||||||
|
"(&(objectclass=printer))");
|
||||||
|
|
||||||
|
if (count == 0) return WERR_OK;
|
||||||
|
if (count < 0) return WERR_GENERAL_FAILURE;
|
||||||
|
|
||||||
|
info = talloc_array(mem_ctx, union spoolss_PrinterInfo, count);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info);
|
||||||
|
|
||||||
|
switch(r->in.level) {
|
||||||
|
case 1:
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
info[i].info1.flags = samdb_result_uint(msgs[i], "flags", 0);
|
||||||
|
|
||||||
|
info[i].info1.name = samdb_result_string(msgs[i], "name", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info1.name);
|
||||||
|
|
||||||
|
info[i].info1.description = samdb_result_string(msgs[i], "description", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info1.description);
|
||||||
|
|
||||||
|
info[i].info1.comment = samdb_result_string(msgs[i], "comment", NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
info[i].info2.servername = samdb_result_string(msgs[i], "servername", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername);
|
||||||
|
|
||||||
|
info[i].info2.printername = samdb_result_string(msgs[i], "printername", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername);
|
||||||
|
|
||||||
|
info[i].info2.sharename = samdb_result_string(msgs[i], "sharename", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.sharename);
|
||||||
|
|
||||||
|
info[i].info2.portname = samdb_result_string(msgs[i], "portname", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.portname);
|
||||||
|
|
||||||
|
info[i].info2.drivername = samdb_result_string(msgs[i], "drivername", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.drivername);
|
||||||
|
|
||||||
|
info[i].info2.comment = samdb_result_string(msgs[i], "comment", NULL);
|
||||||
|
|
||||||
|
info[i].info2.location = samdb_result_string(msgs[i], "location", NULL);
|
||||||
|
|
||||||
|
info[i].info2.devmode = NULL;
|
||||||
|
|
||||||
|
info[i].info2.sepfile = samdb_result_string(msgs[i], "sepfile", NULL);
|
||||||
|
|
||||||
|
info[i].info2.printprocessor = samdb_result_string(msgs[i], "printprocessor", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.printprocessor);
|
||||||
|
|
||||||
|
info[i].info2.datatype = samdb_result_string(msgs[i], "datatype", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.datatype);
|
||||||
|
|
||||||
|
info[i].info2.parameters = samdb_result_string(msgs[i], "parameters", NULL);
|
||||||
|
|
||||||
|
info[i].info2.secdesc = NULL;
|
||||||
|
|
||||||
|
info[i].info2.attributes = samdb_result_uint(msgs[i], "attributes", 0);
|
||||||
|
info[i].info2.priority = samdb_result_uint(msgs[i], "priority", 0);
|
||||||
|
info[i].info2.defaultpriority = samdb_result_uint(msgs[i], "defaultpriority", 0);
|
||||||
|
info[i].info2.starttime = samdb_result_uint(msgs[i], "starttime", 0);
|
||||||
|
info[i].info2.untiltime = samdb_result_uint(msgs[i], "untiltime", 0);
|
||||||
|
info[i].info2.status = samdb_result_uint(msgs[i], "status", 0);
|
||||||
|
info[i].info2.cjobs = samdb_result_uint(msgs[i], "cjobs", 0);
|
||||||
|
info[i].info2.averageppm = samdb_result_uint(msgs[i], "averageppm", 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
info[i].info4.printername = samdb_result_string(msgs[i], "printername", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername);
|
||||||
|
|
||||||
|
info[i].info4.servername = samdb_result_string(msgs[i], "servername", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername);
|
||||||
|
|
||||||
|
info[i].info4.attributes = samdb_result_uint(msgs[i], "attributes", 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
info[i].info5.printername = samdb_result_string(msgs[i], "name", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info5.printername);
|
||||||
|
|
||||||
|
info[i].info5.portname = samdb_result_string(msgs[i], "port", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info5.portname);
|
||||||
|
|
||||||
|
info[i].info5.attributes = samdb_result_uint(msgs[i], "attributes", 0);
|
||||||
|
info[i].info5.device_not_selected_timeout = samdb_result_uint(msgs[i], "device_not_selected_timeout", 0);
|
||||||
|
info[i].info5.transmission_retry_timeout = samdb_result_uint(msgs[i], "transmission_retry_timeout", 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return WERR_UNKNOWN_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->out.info = info;
|
||||||
|
r->out.count = count;
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WERROR sptr_OpenPrinter(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_OpenPrinterEx *r,
|
||||||
|
const char *printer_name,
|
||||||
|
struct ntptr_GenericHandle **printer)
|
||||||
|
{
|
||||||
|
return WERR_INVALID_PRINTER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* port functions */
|
||||||
|
static WERROR sptr_EnumPorts(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumPorts *r)
|
||||||
|
{
|
||||||
|
struct ldb_context *sptr_db = talloc_get_type(ntptr->private_data, struct ldb_context);
|
||||||
|
struct ldb_message **msgs;
|
||||||
|
int count;
|
||||||
|
int i;
|
||||||
|
union spoolss_PortInfo *info;
|
||||||
|
|
||||||
|
count = sptr_db_search(sptr_db, mem_ctx, NULL, &msgs, NULL,
|
||||||
|
"(&(objectclass=port))");
|
||||||
|
|
||||||
|
if (count == 0) return WERR_OK;
|
||||||
|
if (count < 0) return WERR_GENERAL_FAILURE;
|
||||||
|
|
||||||
|
info = talloc_array(mem_ctx, union spoolss_PortInfo, count);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info);
|
||||||
|
|
||||||
|
switch (r->in.level) {
|
||||||
|
case 1:
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
info[i].info1.port_name = samdb_result_string(msgs[i], "port_name", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info1.port_name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
for (i=0; i < count; i++) {
|
||||||
|
info[i].info2.port_name = samdb_result_string(msgs[i], "port_name", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.port_name);
|
||||||
|
|
||||||
|
info[i].info2.monitor_name = samdb_result_string(msgs[i], "monitor_name", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name);
|
||||||
|
|
||||||
|
info[i].info2.description = samdb_result_string(msgs[i], "description", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.description);
|
||||||
|
|
||||||
|
info[i].info2.port_type = samdb_result_uint(msgs[i], "port_type", SPOOLSS_PORT_TYPE_WRITE);
|
||||||
|
info[i].info2.reserved = samdb_result_uint(msgs[i], "reserved", 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return WERR_UNKNOWN_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->out.info = info;
|
||||||
|
r->out.count = count;
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* monitor functions */
|
||||||
|
static WERROR sptr_EnumMonitors(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
|
||||||
|
struct spoolss_EnumMonitors *r)
|
||||||
|
{
|
||||||
|
struct ldb_context *sptr_db = talloc_get_type(ntptr->private_data, struct ldb_context);
|
||||||
|
struct ldb_message **msgs;
|
||||||
|
int count;
|
||||||
|
int i;
|
||||||
|
union spoolss_MonitorInfo *info;
|
||||||
|
|
||||||
|
count = sptr_db_search(sptr_db, mem_ctx, NULL, &msgs, NULL,
|
||||||
|
"(&(objectclass=monitor))");
|
||||||
|
|
||||||
|
if (count == 0) return WERR_OK;
|
||||||
|
if (count < 0) return WERR_GENERAL_FAILURE;
|
||||||
|
|
||||||
|
info = talloc_array(mem_ctx, union spoolss_MonitorInfo, count);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info);
|
||||||
|
|
||||||
|
switch (r->in.level) {
|
||||||
|
case 1:
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
info[i].info1.monitor_name = samdb_result_string(msgs[i], "monitor_name", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info1.monitor_name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
for (i=0; i < count; i++) {
|
||||||
|
info[i].info2.monitor_name = samdb_result_string(msgs[i], "monitor_name", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name);
|
||||||
|
|
||||||
|
info[i].info2.environment = samdb_result_string(msgs[i], "environment", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.environment);
|
||||||
|
|
||||||
|
info[i].info2.dll_name = samdb_result_string(msgs[i], "dll_name", "");
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(info[i].info2.dll_name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return WERR_UNKNOWN_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->out.info = info;
|
||||||
|
r->out.count = count;
|
||||||
|
return WERR_OK;
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
initialialise the simble ldb backend, registering ourselves with the ntptr subsystem
|
||||||
|
*/
|
||||||
|
static const struct ntptr_ops ntptr_simple_ldb_ops = {
|
||||||
|
.name = "simple_ldb",
|
||||||
|
.init_context = sptr_init_context,
|
||||||
|
|
||||||
|
/* PrintServer functions */
|
||||||
|
.OpenPrintServer = sptr_OpenPrintServer,
|
||||||
|
|
||||||
|
/* PrintServer PrinterData functions */
|
||||||
|
/* .EnumPrintServerData = sptr_EnumPrintServerData,
|
||||||
|
*/ .GetPrintServerData = sptr_GetPrintServerData,
|
||||||
|
/* .SetPrintServerData = sptr_SetPrintServerData,
|
||||||
|
.DeletePrintServerData = sptr_DeletePrintServerData,
|
||||||
|
*/
|
||||||
|
/* PrintServer Form functions */
|
||||||
|
.EnumPrintServerForms = sptr_EnumPrintServerForms,
|
||||||
|
/* .AddPrintServerForm = sptr_AddPrintServerForm,
|
||||||
|
*/ .GetPrintServerForm = sptr_GetPrintServerForm,
|
||||||
|
/* .SetPrintServerForm = sptr_SetPrintServerForm,
|
||||||
|
.DeletePrintServerForm = sptr_DeletePrintServerForm,
|
||||||
|
*/
|
||||||
|
/* PrintServer Driver functions */
|
||||||
|
.EnumPrinterDrivers = sptr_EnumPrinterDrivers,
|
||||||
|
/* .AddPrinterDriver = sptr_AddPrinterDriver,
|
||||||
|
.DeletePrinterDriver = sptr_DeletePrinterDriver,
|
||||||
|
*/ .GetPrinterDriverDirectory = sptr_GetPrinterDriverDirectory,
|
||||||
|
|
||||||
|
/* Port functions */
|
||||||
|
.EnumPorts = sptr_EnumPorts,
|
||||||
|
/* .OpenPort = sptr_OpenPort,
|
||||||
|
*/
|
||||||
|
/* Monitor functions */
|
||||||
|
.EnumMonitors = sptr_EnumMonitors,
|
||||||
|
/* .OpenMonitor = sptr_OpenMonitor,
|
||||||
|
*/
|
||||||
|
/* PrintProcessor functions */
|
||||||
|
/* .EnumPrintProcessors = sptr_EnumPrintProcessors,
|
||||||
|
*/
|
||||||
|
/* Printer functions */
|
||||||
|
.EnumPrinters = sptr_EnumPrinters,
|
||||||
|
.OpenPrinter = sptr_OpenPrinter,
|
||||||
|
/* .AddPrinter = sptr_AddPrinter,
|
||||||
|
.GetPrinter = sptr_GetPrinter,
|
||||||
|
.SetPrinter = sptr_SetPrinter,
|
||||||
|
.DeletePrinter = sptr_DeletePrinter,
|
||||||
|
*/
|
||||||
|
/* Printer Driver functions */
|
||||||
|
/* .GetPrinterDriver = sptr_GetPrinterDriver,
|
||||||
|
*/
|
||||||
|
/* Printer PrinterData functions */
|
||||||
|
/* .EnumPrinterData = sptr_EnumPrinterData,
|
||||||
|
.GetPrinterData = sptr_GetPrinterData,
|
||||||
|
.SetPrinterData = sptr_SetPrinterData,
|
||||||
|
.DeletePrinterData = sptr_DeletePrinterData,
|
||||||
|
*/
|
||||||
|
/* Printer Form functions */
|
||||||
|
/* .EnumPrinterForms = sptr_EnumPrinterForms,
|
||||||
|
.AddPrinterForm = sptr_AddPrinterForm,
|
||||||
|
.GetPrinterForm = sptr_GetPrinterForm,
|
||||||
|
.SetPrinterForm = sptr_SetPrinterForm,
|
||||||
|
.DeletePrinterForm = sptr_DeletePrinterForm,
|
||||||
|
*/
|
||||||
|
/* Printer Job functions */
|
||||||
|
/* .EnumJobs = sptr_EnumJobs,
|
||||||
|
.AddJob = sptr_AddJob,
|
||||||
|
.ScheduleJob = sptr_ScheduleJob,
|
||||||
|
.GetJob = sptr_GetJob,
|
||||||
|
.SetJob = sptr_SetJob,
|
||||||
|
*/
|
||||||
|
/* Printer Printing functions */
|
||||||
|
/* .StartDocPrinter = sptr_StartDocPrinter,
|
||||||
|
.EndDocPrinter = sptr_EndDocPrinter,
|
||||||
|
.StartPagePrinter = sptr_StartPagePrinter,
|
||||||
|
.EndPagePrinter = sptr_EndPagePrinter,
|
||||||
|
.WritePrinter = sptr_WritePrinter,
|
||||||
|
.ReadPrinter = sptr_ReadPrinter,
|
||||||
|
*/};
|
||||||
|
|
||||||
|
NTSTATUS ntptr_simple_ldb_init(void)
|
||||||
|
{
|
||||||
|
NTSTATUS ret;
|
||||||
|
|
||||||
|
ret = ntptr_register(&ntptr_simple_ldb_ops);
|
||||||
|
if (!NT_STATUS_IS_OK(ret)) {
|
||||||
|
DEBUG(0,("Failed to register NTPTR '%s' backend!\n",
|
||||||
|
ntptr_simple_ldb_ops.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -167,6 +167,7 @@ typedef struct
|
|||||||
char *szWINSPartners;
|
char *szWINSPartners;
|
||||||
char **dcerpc_ep_servers;
|
char **dcerpc_ep_servers;
|
||||||
char **server_services;
|
char **server_services;
|
||||||
|
char *ntptr_providor;
|
||||||
char *szWinbindUID;
|
char *szWinbindUID;
|
||||||
char *szWinbindGID;
|
char *szWinbindGID;
|
||||||
char *szNonUnixAccountRange;
|
char *szNonUnixAccountRange;
|
||||||
@@ -528,6 +529,7 @@ static struct parm_struct parm_table[] = {
|
|||||||
{"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
|
{"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
|
||||||
{"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
|
{"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
|
||||||
{"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
|
{"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
|
||||||
|
{"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
|
||||||
{"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
|
{"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
|
||||||
{"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
|
{"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
|
||||||
|
|
||||||
@@ -921,6 +923,7 @@ static void init_globals(void)
|
|||||||
|
|
||||||
do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup");
|
do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup");
|
||||||
do_parameter("server services", "smb rpc nbt ldap cldap web");
|
do_parameter("server services", "smb rpc nbt ldap cldap web");
|
||||||
|
do_parameter("ntptr providor", "simple_ldb");
|
||||||
do_parameter("auth methods", "anonymous sam_ignoredomain");
|
do_parameter("auth methods", "anonymous sam_ignoredomain");
|
||||||
do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
|
do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
|
||||||
do_parameter("private dir", dyn_PRIVATE_DIR);
|
do_parameter("private dir", dyn_PRIVATE_DIR);
|
||||||
@@ -1175,6 +1178,7 @@ FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
|
|||||||
FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
|
FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
|
||||||
FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
|
FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
|
||||||
FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
|
FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
|
||||||
|
FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
|
||||||
FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
|
FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
|
||||||
FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
|
FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
|
||||||
FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
|
FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
|
||||||
|
|||||||
@@ -161,12 +161,12 @@ REQUIRED_SUBSYSTEMS = \
|
|||||||
INIT_FUNCTION = dcerpc_server_spoolss_init
|
INIT_FUNCTION = dcerpc_server_spoolss_init
|
||||||
SUBSYSTEM = DCERPC
|
SUBSYSTEM = DCERPC
|
||||||
INIT_OBJ_FILES = \
|
INIT_OBJ_FILES = \
|
||||||
rpc_server/spoolss/dcesrv_spoolss.o \
|
rpc_server/spoolss/dcesrv_spoolss.o
|
||||||
rpc_server/spoolss/spoolssdb.o
|
|
||||||
REQUIRED_SUBSYSTEMS = \
|
REQUIRED_SUBSYSTEMS = \
|
||||||
DCERPC_COMMON \
|
DCERPC_COMMON \
|
||||||
NDR_SPOOLSS
|
NDR_SPOOLSS \
|
||||||
# End MODULE dcerpc_lsa
|
NTPTR
|
||||||
|
# End MODULE dcerpc_spoolss
|
||||||
################################################
|
################################################
|
||||||
|
|
||||||
################################################
|
################################################
|
||||||
|
|||||||
@@ -25,138 +25,186 @@
|
|||||||
#include "rpc_server/dcerpc_server.h"
|
#include "rpc_server/dcerpc_server.h"
|
||||||
#include "librpc/gen_ndr/ndr_spoolss.h"
|
#include "librpc/gen_ndr/ndr_spoolss.h"
|
||||||
#include "rpc_server/common/common.h"
|
#include "rpc_server/common/common.h"
|
||||||
#include "rpc_server/spoolss/dcesrv_spoolss.h"
|
#include "ntptr/ntptr.h"
|
||||||
#include "lib/socket/socket.h"
|
#include "lib/socket/socket.h"
|
||||||
#include "smbd/service_stream.h"
|
#include "smbd/service_stream.h"
|
||||||
|
|
||||||
#define SPOOLSS_BUFFER_SIZE(fn,level,count,info) \
|
#define SPOOLSS_BUFFER_UNION(fn,info,level) \
|
||||||
ndr_size_##fn##_info(dce_call, level, count, info)
|
((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)
|
#define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= r->out.needed)?val_true:val_false)
|
||||||
|
|
||||||
|
static WERROR 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 spoolss_check_server_name(struct dcesrv_call_state *dce_call,
|
||||||
|
TALLOC_CTX *mem_ctx,
|
||||||
|
const char *server_name)
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
const char *ip_str;
|
||||||
|
|
||||||
|
if (!server_name) return WERR_OK;
|
||||||
|
|
||||||
|
ret = strequal("",server_name);
|
||||||
|
if (ret) return WERR_OK;
|
||||||
|
|
||||||
|
if (strncmp("\\\\", server_name, 2) != 0) {
|
||||||
|
return WERR_INVALID_PRINTER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
server_name += 2;
|
||||||
|
|
||||||
|
ret = strequal(lp_netbios_name(), server_name);
|
||||||
|
if (ret) return WERR_OK;
|
||||||
|
|
||||||
|
/* TODO: check dns name here ? */
|
||||||
|
|
||||||
|
ip_str = socket_get_my_addr(dce_call->conn->srv_conn->socket, mem_ctx);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(ip_str);
|
||||||
|
|
||||||
|
ret = strequal(ip_str, server_name);
|
||||||
|
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, lp_ntptr_providor(), &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
|
spoolss_EnumPrinters
|
||||||
*/
|
*/
|
||||||
static WERROR spoolss_EnumPrinters(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR spoolss_EnumPrinters(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct spoolss_EnumPrinters *r)
|
struct spoolss_EnumPrinters *r)
|
||||||
{
|
{
|
||||||
void *spoolss_ctx;
|
struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
|
||||||
struct ldb_message **msgs;
|
WERROR status;
|
||||||
int count;
|
|
||||||
int i;
|
|
||||||
union spoolss_PrinterInfo *info;
|
|
||||||
|
|
||||||
spoolss_ctx = spoolssdb_connect();
|
status = spoolss_check_server_name(dce_call, mem_ctx, r->in.server);
|
||||||
W_ERROR_HAVE_NO_MEMORY(spoolss_ctx);
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
|
|
||||||
count = spoolssdb_search(spoolss_ctx, mem_ctx, NULL, &msgs, NULL,
|
status = ntptr_EnumPrinters(ntptr, mem_ctx, r);
|
||||||
"(&(objectclass=printer))");
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
spoolssdb_close(spoolss_ctx);
|
|
||||||
|
|
||||||
if (count == 0) return WERR_OK;
|
r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinters, r->out.info, r->in.level, r->out.count);
|
||||||
if (count < 0) return WERR_GENERAL_FAILURE;
|
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
|
||||||
|
r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0);
|
||||||
info = talloc_array(mem_ctx, union spoolss_PrinterInfo, count);
|
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
||||||
W_ERROR_HAVE_NO_MEMORY(info);
|
|
||||||
|
|
||||||
switch(r->in.level) {
|
|
||||||
case 1:
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
info[i].info1.flags = samdb_result_uint(msgs[i], "flags", 0);
|
|
||||||
|
|
||||||
info[i].info1.name = samdb_result_string(msgs[i], "name", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info1.name);
|
|
||||||
|
|
||||||
info[i].info1.description = samdb_result_string(msgs[i], "description", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info1.description);
|
|
||||||
|
|
||||||
info[i].info1.comment = samdb_result_string(msgs[i], "comment", NULL);
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinters, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
case 2:
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
info[i].info2.servername = samdb_result_string(msgs[i], "servername", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername);
|
|
||||||
|
|
||||||
info[i].info2.printername = samdb_result_string(msgs[i], "printername", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername);
|
|
||||||
|
|
||||||
info[i].info2.sharename = samdb_result_string(msgs[i], "sharename", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.sharename);
|
|
||||||
|
|
||||||
info[i].info2.portname = samdb_result_string(msgs[i], "portname", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.portname);
|
|
||||||
|
|
||||||
info[i].info2.drivername = samdb_result_string(msgs[i], "drivername", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.drivername);
|
|
||||||
|
|
||||||
info[i].info2.comment = samdb_result_string(msgs[i], "comment", NULL);
|
|
||||||
|
|
||||||
info[i].info2.location = samdb_result_string(msgs[i], "location", NULL);
|
|
||||||
|
|
||||||
info[i].info2.devmode = NULL;
|
|
||||||
|
|
||||||
info[i].info2.sepfile = samdb_result_string(msgs[i], "sepfile", NULL);
|
|
||||||
|
|
||||||
info[i].info2.printprocessor = samdb_result_string(msgs[i], "printprocessor", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.printprocessor);
|
|
||||||
|
|
||||||
info[i].info2.datatype = samdb_result_string(msgs[i], "datatype", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.datatype);
|
|
||||||
|
|
||||||
info[i].info2.parameters = samdb_result_string(msgs[i], "parameters", NULL);
|
|
||||||
|
|
||||||
info[i].info2.secdesc = NULL;
|
|
||||||
|
|
||||||
info[i].info2.attributes = samdb_result_uint(msgs[i], "attributes", 0);
|
|
||||||
info[i].info2.priority = samdb_result_uint(msgs[i], "priority", 0);
|
|
||||||
info[i].info2.defaultpriority = samdb_result_uint(msgs[i], "defaultpriority", 0);
|
|
||||||
info[i].info2.starttime = samdb_result_uint(msgs[i], "starttime", 0);
|
|
||||||
info[i].info2.untiltime = samdb_result_uint(msgs[i], "untiltime", 0);
|
|
||||||
info[i].info2.status = samdb_result_uint(msgs[i], "status", 0);
|
|
||||||
info[i].info2.cjobs = samdb_result_uint(msgs[i], "cjobs", 0);
|
|
||||||
info[i].info2.averageppm = samdb_result_uint(msgs[i], "averageppm", 0);
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinters, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
case 4:
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
info[i].info4.printername = samdb_result_string(msgs[i], "printername", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername);
|
|
||||||
|
|
||||||
info[i].info4.servername = samdb_result_string(msgs[i], "servername", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername);
|
|
||||||
|
|
||||||
info[i].info4.attributes = samdb_result_uint(msgs[i], "attributes", 0);
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinters, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
case 5:
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
info[i].info5.printername = samdb_result_string(msgs[i], "name", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info5.printername);
|
|
||||||
|
|
||||||
info[i].info5.portname = samdb_result_string(msgs[i], "port", "");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info5.portname);
|
|
||||||
|
|
||||||
info[i].info5.attributes = samdb_result_uint(msgs[i], "attributes", 0);
|
|
||||||
info[i].info5.device_not_selected_timeout = samdb_result_uint(msgs[i], "device_not_selected_timeout", 0);
|
|
||||||
info[i].info5.transmission_retry_timeout = samdb_result_uint(msgs[i], "transmission_retry_timeout", 0);
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinters, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
}
|
|
||||||
|
|
||||||
return WERR_UNKNOWN_LEVEL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static WERROR spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
@@ -279,64 +327,19 @@ static WERROR spoolss_AddPrinterDriver(struct dcesrv_call_state *dce_call, TALLO
|
|||||||
static WERROR spoolss_EnumPrinterDrivers(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR spoolss_EnumPrinterDrivers(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct spoolss_EnumPrinterDrivers *r)
|
struct spoolss_EnumPrinterDrivers *r)
|
||||||
{
|
{
|
||||||
union spoolss_DriverInfo *info;
|
struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
|
||||||
int count;
|
WERROR status;
|
||||||
int i;
|
|
||||||
|
|
||||||
count = 0;
|
status = spoolss_check_server_name(dce_call, mem_ctx, r->in.server);
|
||||||
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
|
|
||||||
if (count == 0) return WERR_OK;
|
status = ntptr_EnumPrinterDrivers(ntptr, mem_ctx, r);
|
||||||
if (count < 0) return WERR_GENERAL_FAILURE;
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
|
|
||||||
info = talloc_array(mem_ctx, union spoolss_DriverInfo, count);
|
r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinterDrivers, r->out.info, r->in.level, r->out.count);
|
||||||
W_ERROR_HAVE_NO_MEMORY(info);
|
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
|
||||||
|
r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0);
|
||||||
switch (r->in.level) {
|
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
||||||
case 1:
|
|
||||||
for (i=0; i < count; i++) {
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
case 2:
|
|
||||||
for (i=0; i < count; i++) {
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
case 3:
|
|
||||||
for (i=0; i < count; i++) {
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
case 4:
|
|
||||||
for (i=0; i < count; i++) {
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
case 5:
|
|
||||||
for (i=0; i < count; i++) {
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
case 6:
|
|
||||||
for (i=0; i < count; i++) {
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
}
|
|
||||||
|
|
||||||
return WERR_UNKNOWN_LEVEL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -356,42 +359,17 @@ static WERROR spoolss_GetPrinterDriver(struct dcesrv_call_state *dce_call, TALLO
|
|||||||
static WERROR spoolss_GetPrinterDriverDirectory(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR spoolss_GetPrinterDriverDirectory(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct spoolss_GetPrinterDriverDirectory *r)
|
struct spoolss_GetPrinterDriverDirectory *r)
|
||||||
{
|
{
|
||||||
union spoolss_DriverDirectoryInfo *info;
|
struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
|
||||||
const char *prefix;
|
WERROR status;
|
||||||
const char *postfix;
|
|
||||||
|
|
||||||
/*
|
status = spoolss_check_server_name(dce_call, mem_ctx, r->in.server);
|
||||||
* NOTE: normally r->in.level is 1, but both w2k3 and nt4 sp6a
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
* are ignoring the r->in.level completely, so we do :-)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: check the server name is ours
|
|
||||||
* - if it's a invalid UNC then return WERR_INVALID_NAME
|
|
||||||
* - if it's the wrong host name return WERR_INVALID_PARAM
|
|
||||||
* - if it's "" then we need to return a local WINDOWS path
|
|
||||||
*/
|
|
||||||
if (strcmp("", r->in.server) == 0) {
|
|
||||||
prefix = "C:\\DRIVERS";
|
|
||||||
} else {
|
|
||||||
prefix = talloc_asprintf(mem_ctx, "%s\\print$", r->in.server);
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(SPOOLSS_ARCHITECTURE_NT_X86, r->in.environment) == 0) {
|
status = ntptr_GetPrinterDriverDirectory(ntptr, mem_ctx, r);
|
||||||
postfix = "W32X86";
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
} else {
|
|
||||||
return WERR_INVALID_ENVIRONMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
info = talloc(mem_ctx, union spoolss_DriverDirectoryInfo);
|
r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, r->out.info, r->in.level);
|
||||||
W_ERROR_HAVE_NO_MEMORY(info);
|
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
|
||||||
|
|
||||||
info->info1.directory_name = talloc_asprintf(mem_ctx, "%s\\%s", prefix, postfix);
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info->info1.directory_name);
|
|
||||||
|
|
||||||
r->out.needed = ndr_size_spoolss_DriverDirectoryInfo(info, r->in.level, 0);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -532,67 +510,28 @@ static WERROR spoolss_ScheduleJob(struct dcesrv_call_state *dce_call, TALLOC_CTX
|
|||||||
static WERROR spoolss_GetPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR spoolss_GetPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct spoolss_GetPrinterData *r)
|
struct spoolss_GetPrinterData *r)
|
||||||
{
|
{
|
||||||
|
struct ntptr_GenericHandle *handle;
|
||||||
struct dcesrv_handle *h;
|
struct dcesrv_handle *h;
|
||||||
WERROR status = WERR_INVALID_PARAM;
|
WERROR status;
|
||||||
enum spoolss_PrinterDataType type = SPOOLSS_PRINTER_DATA_TYPE_NULL;
|
|
||||||
union spoolss_PrinterData data;
|
|
||||||
|
|
||||||
DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
|
DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
|
||||||
|
handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
|
||||||
|
|
||||||
if (h->wire_handle.handle_type == SPOOLSS_HANDLE_SERVER) {
|
switch (handle->type) {
|
||||||
/* TODO: do access check here */
|
case NTPTR_HANDLE_SERVER:
|
||||||
|
status = ntptr_GetPrintServerData(handle, mem_ctx, r);
|
||||||
if (strcmp("W3SvcInstalled", r->in.value_name) == 0) {
|
break;
|
||||||
type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
default:
|
||||||
data.value = 0;
|
status = WERR_FOOBAR;
|
||||||
status = WERR_OK;
|
break;
|
||||||
} else if (strcmp("BeepEnabled", r->in.value_name) == 0) {
|
|
||||||
type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
|
||||||
data.value = 0;
|
|
||||||
status = WERR_OK;
|
|
||||||
} else if (strcmp("EventLog", r->in.value_name) == 0) {
|
|
||||||
type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
|
||||||
data.value = 0;
|
|
||||||
status = WERR_OK;
|
|
||||||
} else if (strcmp("NetPopup", r->in.value_name) == 0) {
|
|
||||||
type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
|
||||||
data.value = 0;
|
|
||||||
status = WERR_OK;
|
|
||||||
} else if (strcmp("NetPopupToComputer", r->in.value_name) == 0) {
|
|
||||||
type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
|
||||||
data.value = 0;
|
|
||||||
status = WERR_OK;
|
|
||||||
} else if (strcmp("MajorVersion", r->in.value_name) == 0) {
|
|
||||||
type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
|
||||||
data.value = 3;
|
|
||||||
status = WERR_OK;
|
|
||||||
} else if (strcmp("MinorVersion", r->in.value_name) == 0) {
|
|
||||||
type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
|
||||||
data.value = 0;
|
|
||||||
status = WERR_OK;
|
|
||||||
} else if (strcmp("DefaultSpoolDirectory", r->in.value_name) == 0) {
|
|
||||||
type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
|
|
||||||
data.string = "C:\\PRINTERS";
|
|
||||||
status = WERR_OK;
|
|
||||||
} else if (strcmp("Architecture", r->in.value_name) == 0) {
|
|
||||||
type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
|
|
||||||
data.string = SPOOLSS_ARCHITECTURE_NT_X86;
|
|
||||||
status = WERR_OK;
|
|
||||||
} else if (strcmp("DsPresent", r->in.value_name) == 0) {
|
|
||||||
type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
|
|
||||||
data.value = 1;
|
|
||||||
status = WERR_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (W_ERROR_IS_OK(status)) {
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
r->out.needed = ndr_size_spoolss_PrinterData(&data, type, 0);
|
|
||||||
r->out.type = SPOOLSS_BUFFER_OK(type, SPOOLSS_PRINTER_DATA_TYPE_NULL);
|
|
||||||
r->out.data = SPOOLSS_BUFFER_OK(data, data);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -662,7 +601,29 @@ static WERROR spoolss_DeleteForm(struct dcesrv_call_state *dce_call, TALLOC_CTX
|
|||||||
static WERROR spoolss_GetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR spoolss_GetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct spoolss_GetForm *r)
|
struct spoolss_GetForm *r)
|
||||||
{
|
{
|
||||||
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
|
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_GetPrintServerForm(handle, mem_ctx, r);
|
||||||
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
|
break;
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -682,44 +643,30 @@ static WERROR spoolss_SetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
|
|||||||
static WERROR spoolss_EnumForms(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR spoolss_EnumForms(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct spoolss_EnumForms *r)
|
struct spoolss_EnumForms *r)
|
||||||
{
|
{
|
||||||
union spoolss_FormInfo *info;
|
struct ntptr_GenericHandle *handle;
|
||||||
int count;
|
|
||||||
int i;
|
|
||||||
struct dcesrv_handle *h;
|
struct dcesrv_handle *h;
|
||||||
|
WERROR status;
|
||||||
|
|
||||||
DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
|
DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
|
||||||
|
handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
|
||||||
|
|
||||||
count = 1;
|
switch (handle->type) {
|
||||||
|
case NTPTR_HANDLE_SERVER:
|
||||||
if (count == 0) return WERR_OK;
|
status = ntptr_EnumPrintServerForms(handle, mem_ctx, r);
|
||||||
if (count < 0) return WERR_GENERAL_FAILURE;
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
|
break;
|
||||||
info = talloc_array(mem_ctx, union spoolss_FormInfo, count);
|
case NTPTR_HANDLE_PRINTER:
|
||||||
W_ERROR_HAVE_NO_MEMORY(info);
|
status = ntptr_EnumPrinterForms(handle, mem_ctx, r);
|
||||||
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
switch (r->in.level) {
|
break;
|
||||||
case 1:
|
default:
|
||||||
for (i=0; i < count; i++) {
|
return WERR_FOOBAR;
|
||||||
info[i].info1.flags = SPOOLSS_FORM_PRINTER;
|
|
||||||
|
|
||||||
info[i].info1.form_name = talloc_strdup(mem_ctx, "Letter");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info1.form_name);
|
|
||||||
|
|
||||||
info[i].info1.size.width = 0x34b5c;
|
|
||||||
info[i].info1.size.height = 0x44368;
|
|
||||||
|
|
||||||
info[i].info1.area.left = 0;
|
|
||||||
info[i].info1.area.top = 0;
|
|
||||||
info[i].info1.area.right = 0x34b5c;
|
|
||||||
info[i].info1.area.bottom = 0x44368;
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumForms, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return WERR_UNKNOWN_LEVEL;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -729,49 +676,19 @@ static WERROR spoolss_EnumForms(struct dcesrv_call_state *dce_call, TALLOC_CTX *
|
|||||||
static WERROR spoolss_EnumPorts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR spoolss_EnumPorts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct spoolss_EnumPorts *r)
|
struct spoolss_EnumPorts *r)
|
||||||
{
|
{
|
||||||
union spoolss_PortInfo *info;
|
struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
|
||||||
int count;
|
WERROR status;
|
||||||
int i;
|
|
||||||
|
|
||||||
count = 1;
|
status = spoolss_check_server_name(dce_call, mem_ctx, r->in.servername);
|
||||||
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
|
|
||||||
if (count == 0) return WERR_OK;
|
status = ntptr_EnumPorts(ntptr, mem_ctx, r);
|
||||||
if (count < 0) return WERR_GENERAL_FAILURE;
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
|
|
||||||
info = talloc_array(mem_ctx, union spoolss_PortInfo, count);
|
r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPorts, r->out.info, r->in.level, r->out.count);
|
||||||
W_ERROR_HAVE_NO_MEMORY(info);
|
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
|
||||||
|
r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0);
|
||||||
switch (r->in.level) {
|
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
||||||
case 1:
|
|
||||||
for (i=0; i < count; i++) {
|
|
||||||
info[i].info1.port_name = talloc_strdup(mem_ctx, "Samba Printer Port");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info1.port_name);
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPorts, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
case 2:
|
|
||||||
for (i=0; i < count; i++) {
|
|
||||||
info[i].info2.port_name = talloc_strdup(mem_ctx, "Samba Printer Port");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.port_name);
|
|
||||||
|
|
||||||
info[i].info2.monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name);
|
|
||||||
|
|
||||||
info[i].info2.description = talloc_strdup(mem_ctx, "Local Port");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.description);
|
|
||||||
|
|
||||||
info[i].info2.port_type = SPOOLSS_PORT_TYPE_WRITE;
|
|
||||||
info[i].info2.reserved = 0;
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPorts, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
}
|
|
||||||
|
|
||||||
return WERR_UNKNOWN_LEVEL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -781,46 +698,19 @@ static WERROR spoolss_EnumPorts(struct dcesrv_call_state *dce_call, TALLOC_CTX *
|
|||||||
static WERROR spoolss_EnumMonitors(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR spoolss_EnumMonitors(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct spoolss_EnumMonitors *r)
|
struct spoolss_EnumMonitors *r)
|
||||||
{
|
{
|
||||||
union spoolss_MonitorInfo *info;
|
struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
|
||||||
int count;
|
WERROR status;
|
||||||
int i;
|
|
||||||
|
|
||||||
count = 1;
|
status = spoolss_check_server_name(dce_call, mem_ctx, r->in.servername);
|
||||||
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
|
|
||||||
if (count == 0) return WERR_OK;
|
status = ntptr_EnumMonitors(ntptr, mem_ctx, r);
|
||||||
if (count < 0) return WERR_GENERAL_FAILURE;
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
|
|
||||||
info = talloc_array(mem_ctx, union spoolss_MonitorInfo, count);
|
r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumMonitors, r->out.info, r->in.level, r->out.count);
|
||||||
W_ERROR_HAVE_NO_MEMORY(info);
|
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
|
||||||
|
r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0);
|
||||||
switch (r->in.level) {
|
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
||||||
case 1:
|
|
||||||
for (i=0; i < count; i++) {
|
|
||||||
info[i].info1.monitor_name = talloc_strdup(mem_ctx, "Standard TCP/IP Port");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info1.monitor_name);
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumMonitors, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
case 2:
|
|
||||||
for (i=0; i < count; i++) {
|
|
||||||
info[i].info2.monitor_name = talloc_strdup(mem_ctx, "Standard TCP/IP Port");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name);
|
|
||||||
|
|
||||||
info[i].info2.environment = talloc_strdup(mem_ctx, SPOOLSS_ARCHITECTURE_NT_X86);
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.environment);
|
|
||||||
|
|
||||||
info[i].info2.dll_name = talloc_strdup(mem_ctx, "tcpmon.dll");
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(info[i].info2.dll_name);
|
|
||||||
}
|
|
||||||
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumMonitors, r->in.level, count, info);
|
|
||||||
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
|
|
||||||
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
|
|
||||||
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
|
|
||||||
}
|
|
||||||
|
|
||||||
return WERR_UNKNOWN_LEVEL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1110,7 +1000,12 @@ static WERROR spoolss_ResetPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_
|
|||||||
static WERROR spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
|
struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
|
||||||
{
|
{
|
||||||
return WERR_NOT_SUPPORTED;
|
/*
|
||||||
|
* TODO: for now just return ok,
|
||||||
|
* to keep the w2k3 PrintServer
|
||||||
|
* happy to allow to open the Add Printer GUI
|
||||||
|
*/
|
||||||
|
return WERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1143,175 +1038,57 @@ static WERROR spoolss_44(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx
|
|||||||
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
|
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static WERROR spoolss_OpenPrinterEx_server(struct dcesrv_call_state *dce_call,
|
|
||||||
TALLOC_CTX *mem_ctx,
|
|
||||||
struct spoolss_OpenPrinterEx *r,
|
|
||||||
const char *server_name)
|
|
||||||
{
|
|
||||||
struct spoolss_handle_server *state;
|
|
||||||
struct dcesrv_handle *handle;
|
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
/* Check printername is our name or our ip address
|
|
||||||
*/
|
|
||||||
ret = strequal(server_name, lp_netbios_name());
|
|
||||||
if (!ret) {
|
|
||||||
const char *ip = socket_get_my_addr(dce_call->conn->srv_conn->socket, mem_ctx);
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(ip);
|
|
||||||
|
|
||||||
ret = strequal(server_name, ip);
|
|
||||||
if (!ret) {
|
|
||||||
return WERR_INVALID_PRINTER_NAME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: do access check here */
|
|
||||||
|
|
||||||
handle = dcesrv_handle_new(dce_call->context, SPOOLSS_HANDLE_SERVER);
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(handle);
|
|
||||||
|
|
||||||
state = talloc(handle, struct spoolss_handle_server);
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(state);
|
|
||||||
|
|
||||||
handle->data = state;
|
|
||||||
|
|
||||||
state->access_mask = r->in.access_mask;
|
|
||||||
|
|
||||||
*r->out.handle = handle->wire_handle;
|
|
||||||
|
|
||||||
return WERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static WERROR spoolss_OpenPrinterEx_port(struct dcesrv_call_state *dce_call,
|
|
||||||
TALLOC_CTX *mem_ctx,
|
|
||||||
struct spoolss_OpenPrinterEx *r,
|
|
||||||
const char *server_name,
|
|
||||||
const char *port_name)
|
|
||||||
{
|
|
||||||
DEBUG(1, ("looking for port [%s] (server[%s])\n", port_name, server_name));
|
|
||||||
|
|
||||||
return WERR_INVALID_PRINTER_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
static WERROR spoolss_OpenPrinterEx_monitor(struct dcesrv_call_state *dce_call,
|
|
||||||
TALLOC_CTX *mem_ctx,
|
|
||||||
struct spoolss_OpenPrinterEx *r,
|
|
||||||
const char *server_name,
|
|
||||||
const char *monitor_name)
|
|
||||||
{
|
|
||||||
if (strequal("Standard TCP/IP Port", monitor_name)) {
|
|
||||||
struct dcesrv_handle *handle;
|
|
||||||
|
|
||||||
handle = dcesrv_handle_new(dce_call->context, SPOOLSS_HANDLE_MONITOR);
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(handle);
|
|
||||||
|
|
||||||
handle->data = NULL;
|
|
||||||
|
|
||||||
*r->out.handle = handle->wire_handle;
|
|
||||||
|
|
||||||
return WERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG(1, ("looking for monitor [%s] (server[%s])\n", monitor_name, server_name));
|
|
||||||
|
|
||||||
return WERR_INVALID_PRINTER_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
static WERROR spoolss_OpenPrinterEx_printer(struct dcesrv_call_state *dce_call,
|
|
||||||
TALLOC_CTX *mem_ctx,
|
|
||||||
struct spoolss_OpenPrinterEx *r,
|
|
||||||
const char *server_name,
|
|
||||||
const char *printer_name)
|
|
||||||
{
|
|
||||||
DEBUG(3, ("looking for printer [%s] (server[%s])\n", printer_name, server_name));
|
|
||||||
|
|
||||||
return WERR_INVALID_PRINTER_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
spoolss_OpenPrinterEx
|
spoolss_OpenPrinterEx
|
||||||
*/
|
*/
|
||||||
static WERROR spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct spoolss_OpenPrinterEx *r)
|
struct spoolss_OpenPrinterEx *r)
|
||||||
{
|
{
|
||||||
char *p;
|
struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
|
||||||
char *server = NULL;
|
struct ntptr_GenericHandle *handle;
|
||||||
const char *object = r->in.printername;
|
struct dcesrv_handle *h;
|
||||||
|
const char *server;
|
||||||
|
const char *object;
|
||||||
|
enum ntptr_HandleType type;
|
||||||
|
WERROR status;
|
||||||
|
|
||||||
ZERO_STRUCTP(r->out.handle);
|
ZERO_STRUCTP(r->out.handle);
|
||||||
|
|
||||||
/* no printername is there it's like open server */
|
status = spoolss_parse_printer_name(mem_ctx, r->in.printername, &server, &object, &type);
|
||||||
if (!r->in.printername) {
|
W_ERROR_NOT_OK_RETURN(status);
|
||||||
return spoolss_OpenPrinterEx_server(dce_call, mem_ctx, r, NULL);
|
|
||||||
|
status = 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* just "\\" is invalid */
|
h = dcesrv_handle_new(dce_call->context, handle->type);
|
||||||
if (strequal(r->in.printername, "\\\\")) {
|
W_ERROR_HAVE_NO_MEMORY(h);
|
||||||
return WERR_INVALID_PRINTER_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(r->in.printername, "\\\\", 2) == 0) {
|
h->data = talloc_steal(h, handle);
|
||||||
server = talloc_strdup(mem_ctx, r->in.printername + 2);
|
|
||||||
W_ERROR_HAVE_NO_MEMORY(server);
|
|
||||||
|
|
||||||
/* here we know we have "\\" in front not followed
|
*r->out.handle = h->wire_handle;
|
||||||
* 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)
|
|
||||||
*/
|
|
||||||
return spoolss_OpenPrinterEx_server(dce_call, mem_ctx, r, server);
|
|
||||||
}
|
|
||||||
/* 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 */
|
return WERR_OK;
|
||||||
if (strequal(server, "")) {
|
|
||||||
DEBUG(2,("OpenPrinterEx invalid print server: [%s][%s][%s]\n", r->in.printername, server, object));
|
|
||||||
return WERR_INVALID_PRINTER_NAME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* just "" is invalid */
|
|
||||||
if (strequal(object, "")) {
|
|
||||||
DEBUG(2,("OpenPrinterEx invalid object: [%s][%s][%s]\n", r->in.printername, server, object));
|
|
||||||
return WERR_INVALID_PRINTER_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG(3,("OpenPrinterEx object: [%s][%s][%s]\n", r->in.printername, server, object));
|
|
||||||
|
|
||||||
#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, "")) {
|
|
||||||
DEBUG(2,("OpenPrinterEx invalid port: [%s][%s][%s]\n", r->in.printername, server, object));
|
|
||||||
return WERR_INVALID_PRINTER_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
return spoolss_OpenPrinterEx_port(dce_call, mem_ctx, r, server, object);
|
|
||||||
} else if (strncmp(object, XCV_MONITOR, strlen(XCV_MONITOR)) == 0) {
|
|
||||||
object += strlen(XCV_MONITOR);
|
|
||||||
|
|
||||||
/* just "" is invalid */
|
|
||||||
if (strequal(object, "")) {
|
|
||||||
DEBUG(2,("OpenPrinterEx invalid monitor: [%s][%s][%s]\n", r->in.printername, server, object));
|
|
||||||
return WERR_INVALID_PRINTER_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
return spoolss_OpenPrinterEx_monitor(dce_call, mem_ctx, r, server, object);
|
|
||||||
}
|
|
||||||
|
|
||||||
return spoolss_OpenPrinterEx_printer(dce_call, mem_ctx, r, server, object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
|
|
||||||
endpoint server for the spoolss pipe - definitions
|
|
||||||
|
|
||||||
Copyright (C) Tim Potter 2004
|
|
||||||
|
|
||||||
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
|
|
||||||
(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, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
this type allows us to distinguish handle types
|
|
||||||
*/
|
|
||||||
enum spoolss_handle_type {
|
|
||||||
SPOOLSS_HANDLE_SERVER,
|
|
||||||
SPOOLSS_HANDLE_PRINTER,
|
|
||||||
SPOOLSS_HANDLE_PORT,
|
|
||||||
SPOOLSS_HANDLE_MONITOR
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
state asscoiated with a spoolss_OpenPrinter{,Ex}() operation
|
|
||||||
*/
|
|
||||||
struct spoolss_handle_server {
|
|
||||||
uint32_t access_mask;
|
|
||||||
};
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
|
|
||||||
interface functions for the spoolss database
|
|
||||||
|
|
||||||
Copyright (C) Andrew Tridgell 2004
|
|
||||||
Copyright (C) Tim Potter 2004
|
|
||||||
|
|
||||||
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
|
|
||||||
(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, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "includes.h"
|
|
||||||
#include "lib/ldb/include/ldb.h"
|
|
||||||
|
|
||||||
struct spoolssdb_context {
|
|
||||||
struct ldb_context *ldb;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
this is used to catch debug messages from ldb
|
|
||||||
*/
|
|
||||||
static void spoolssdb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
|
|
||||||
static void spoolssdb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
char *s = NULL;
|
|
||||||
if (DEBUGLEVEL < 4 && level > LDB_DEBUG_WARNING) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
vasprintf(&s, fmt, ap);
|
|
||||||
if (!s) return;
|
|
||||||
DEBUG(level, ("spoolssdb: %s\n", s));
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
connect to the spoolss database
|
|
||||||
return an opaque context pointer on success, or NULL on failure
|
|
||||||
*/
|
|
||||||
void *spoolssdb_connect(void)
|
|
||||||
{
|
|
||||||
struct spoolssdb_context *ctx;
|
|
||||||
/*
|
|
||||||
the way that unix fcntl locking works forces us to have a
|
|
||||||
static ldb handle here rather than a much more sensible
|
|
||||||
approach of having the ldb handle as part of the
|
|
||||||
spoolss_OpenPrinter() pipe state. Otherwise we would try to open
|
|
||||||
the ldb more than once, and tdb would rightly refuse the
|
|
||||||
second open due to the broken nature of unix locking.
|
|
||||||
*/
|
|
||||||
static struct ldb_context *static_spoolss_db;
|
|
||||||
|
|
||||||
if (static_spoolss_db == NULL) {
|
|
||||||
static_spoolss_db = ldb_connect(lp_spoolss_url(), 0, NULL);
|
|
||||||
if (static_spoolss_db == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ldb_set_debug(static_spoolss_db, spoolssdb_debug, NULL);
|
|
||||||
|
|
||||||
ctx = malloc_p(struct spoolssdb_context);
|
|
||||||
if (!ctx) {
|
|
||||||
errno = ENOMEM;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->ldb = static_spoolss_db;
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* close a connection to the spoolss db */
|
|
||||||
void spoolssdb_close(void *ctx)
|
|
||||||
{
|
|
||||||
struct spoolssdb_context *spoolss_ctx = ctx;
|
|
||||||
/* we don't actually close due to broken posix locking semantics */
|
|
||||||
spoolss_ctx->ldb = NULL;
|
|
||||||
free(spoolss_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
search the db for the specified attributes - varargs variant
|
|
||||||
*/
|
|
||||||
int spoolssdb_search(void *ctx,
|
|
||||||
TALLOC_CTX *mem_ctx,
|
|
||||||
const char *basedn,
|
|
||||||
struct ldb_message ***res,
|
|
||||||
const char * const *attrs,
|
|
||||||
const char *format, ...) _PRINTF_ATTRIBUTE(6,7)
|
|
||||||
{
|
|
||||||
struct spoolssdb_context *spoolss_ctx = ctx;
|
|
||||||
va_list ap;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
count = gendb_search_v(spoolss_ctx->ldb, mem_ctx, basedn, res, attrs, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user