summaryrefslogtreecommitdiff
path: root/source4/ntptr
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-06-16 17:27:57 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:18:16 -0500
commit8f85427d6d8fa7e6bfd76ed5335c8dbe7dd14afe (patch)
treeea4000a042eebeca2dc09e6b1c329fcf6129f82d /source4/ntptr
parent038628b9c5eb033213e187b38f8260573cbf6b17 (diff)
downloadsamba-8f85427d6d8fa7e6bfd76ed5335c8dbe7dd14afe.tar.gz
samba-8f85427d6d8fa7e6bfd76ed5335c8dbe7dd14afe.tar.bz2
samba-8f85427d6d8fa7e6bfd76ed5335c8dbe7dd14afe.zip
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 used to be commit 455b5536d41bc31ebef8290812f45d4a38afa8e9)
Diffstat (limited to 'source4/ntptr')
-rw-r--r--source4/ntptr/config.mk24
-rw-r--r--source4/ntptr/ntptr.h189
-rw-r--r--source4/ntptr/ntptr_base.c134
-rw-r--r--source4/ntptr/ntptr_interface.c561
-rw-r--r--source4/ntptr/simple_ldb/ntptr_simple_ldb.c596
5 files changed, 1504 insertions, 0 deletions
diff --git a/source4/ntptr/config.mk b/source4/ntptr/config.mk
new file mode 100644
index 0000000000..ab36d75343
--- /dev/null
+++ b/source4/ntptr/config.mk
@@ -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
+################################################
diff --git a/source4/ntptr/ntptr.h b/source4/ntptr/ntptr.h
new file mode 100644
index 0000000000..847cef97c3
--- /dev/null
+++ b/source4/ntptr/ntptr.h
@@ -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;
+};
diff --git a/source4/ntptr/ntptr_base.c b/source4/ntptr/ntptr_base.c
new file mode 100644
index 0000000000..f12a58cb4e
--- /dev/null
+++ b/source4/ntptr/ntptr_base.c
@@ -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;
+}
diff --git a/source4/ntptr/ntptr_interface.c b/source4/ntptr/ntptr_interface.c
new file mode 100644
index 0000000000..b389a5b894
--- /dev/null
+++ b/source4/ntptr/ntptr_interface.c
@@ -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);
+}
+
diff --git a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c
new file mode 100644
index 0000000000..4c8113365e
--- /dev/null
+++ b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c
@@ -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;
+}