summaryrefslogtreecommitdiff
path: root/source4/ntptr
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntptr')
-rw-r--r--source4/ntptr/config.mk27
-rw-r--r--source4/ntptr/ntptr.h237
-rw-r--r--source4/ntptr/ntptr_base.c151
-rw-r--r--source4/ntptr/ntptr_interface.c595
-rw-r--r--source4/ntptr/simple_ldb/ntptr_simple_ldb.c848
5 files changed, 1858 insertions, 0 deletions
diff --git a/source4/ntptr/config.mk b/source4/ntptr/config.mk
new file mode 100644
index 0000000000..71b3bc05a8
--- /dev/null
+++ b/source4/ntptr/config.mk
@@ -0,0 +1,27 @@
+# ntptr server subsystem
+
+################################################
+# Start MODULE ntptr_simple_ldb
+[MODULE::ntptr_simple_ldb]
+INIT_FUNCTION = ntptr_simple_ldb_init
+SUBSYSTEM = ntptr
+PRIVATE_DEPENDENCIES = \
+ LIBLDB NDR_SPOOLSS DCERPC_COMMON
+# End MODULE ntptr_simple_ldb
+################################################
+
+ntptr_simple_ldb_OBJ_FILES = $(ntptrsrcdir)/simple_ldb/ntptr_simple_ldb.o
+
+################################################
+# Start SUBSYSTEM ntptr
+[SUBSYSTEM::ntptr]
+PUBLIC_DEPENDENCIES = DCERPC_COMMON
+#
+# End SUBSYSTEM ntptr
+################################################
+
+ntptr_OBJ_FILES = \
+ $(ntptrsrcdir)/ntptr_base.o \
+ $(ntptrsrcdir)/ntptr_interface.o
+
+$(eval $(call proto_header_template,$(ntptrsrcdir)/ntptr_proto.h,$(ntptr_OBJ_FILES:.o=.c)))
diff --git a/source4/ntptr/ntptr.h b/source4/ntptr/ntptr.h
new file mode 100644
index 0000000000..7138a2fdfb
--- /dev/null
+++ b/source4/ntptr/ntptr.h
@@ -0,0 +1,237 @@
+/*
+ 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* 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;
+ const char *object_name;
+ uint32_t access_mask;
+ void *private_data;
+};
+
+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_AddJob;
+struct spoolss_EnumJobs;
+struct spoolss_SetJob;
+struct spoolss_GetJob;
+struct spoolss_ScheduleJob;
+struct spoolss_ReadPrinter;
+struct spoolss_WritePrinter;
+struct spoolss_StartDocPrinter;
+struct spoolss_EndDocPrinter;
+struct spoolss_StartPagePrinter;
+struct spoolss_EndPagePrinter;
+struct spoolss_GetPrinterData;
+struct spoolss_SetPrinterData;
+struct spoolss_EnumPrinterDrivers;
+struct spoolss_EnumMonitors;
+struct spoolss_EnumPrinters;
+struct spoolss_EnumForms;
+struct spoolss_EnumPorts;
+struct spoolss_EnumPrintProcessors;
+struct spoolss_XcvData;
+
+/* 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);
+ WERROR (*XcvDataPrintServer)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
+ struct spoolss_XcvData *r);
+
+ /* 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 (*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 **port);
+ WERROR (*XcvDataPort)(struct ntptr_GenericHandle *port, TALLOC_CTX *mem_ctx,
+ struct spoolss_XcvData *r);
+
+ /* 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);
+ WERROR (*XcvDataMonitor)(struct ntptr_GenericHandle *monitor, TALLOC_CTX *mem_ctx,
+ struct spoolss_XcvData *r);
+
+ /* 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);
+ WERROR (*XcvDataPrinter)(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
+ struct spoolss_XcvData *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;
+ struct event_context *ev_ctx;
+ struct loadparm_context *lp_ctx;
+};
+
+/* 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;
+};
+
+struct loadparm_context;
+
+#include "ntptr/ntptr_proto.h"
diff --git a/source4/ntptr/ntptr_base.c b/source4/ntptr/ntptr_base.c
new file mode 100644
index 0000000000..a7004be90b
--- /dev/null
+++ b/source4/ntptr/ntptr_base.c
@@ -0,0 +1,151 @@
+/*
+ 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ this implements the core code for all NTPTR modules. Backends register themselves here.
+*/
+
+#include "includes.h"
+#include "ntptr/ntptr.h"
+#include "param/param.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;
+}
+
+NTSTATUS ntptr_init(struct loadparm_context *lp_ctx)
+{
+ extern NTSTATUS ntptr_simple_ldb_init(void);
+ init_module_fn static_init[] = { STATIC_ntptr_MODULES };
+ init_module_fn *shared_init = load_samba_modules(NULL, lp_ctx, "ntptr");
+
+ run_init_functions(static_init);
+ run_init_functions(shared_init);
+
+ talloc_free(shared_init);
+
+ 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, struct event_context *ev_ctx,
+ struct loadparm_context *lp_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);
+ ntptr->ev_ctx = ev_ctx;
+ ntptr->lp_ctx = lp_ctx;
+
+ 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..109a9f560b
--- /dev/null
+++ b/source4/ntptr/ntptr_interface.c
@@ -0,0 +1,595 @@
+/*
+ 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "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);
+}
+
+WERROR ntptr_XcvDataPrintServer(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
+ struct spoolss_XcvData *r)
+{
+ if (server->type != NTPTR_HANDLE_SERVER) {
+ return WERR_FOOBAR;
+ }
+ if (!server->ntptr->ops->XcvDataPrintServer) {
+ return WERR_NOT_SUPPORTED;
+ }
+ return server->ntptr->ops->XcvDataPrintServer(server, mem_ctx, r);
+}
+
+
+/* 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_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 **port)
+{
+ if (!ntptr->ops->OpenPort) {
+ return WERR_NOT_SUPPORTED;
+ }
+ return ntptr->ops->OpenPort(ntptr, mem_ctx, r, port_name, port);
+}
+
+WERROR ntptr_XcvDataPort(struct ntptr_GenericHandle *port, TALLOC_CTX *mem_ctx,
+ struct spoolss_XcvData *r)
+{
+ if (port->type != NTPTR_HANDLE_PORT) {
+ return WERR_FOOBAR;
+ }
+ if (!port->ntptr->ops->XcvDataPort) {
+ return WERR_NOT_SUPPORTED;
+ }
+ return port->ntptr->ops->XcvDataPort(port, mem_ctx, r);
+}
+
+/* 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);
+}
+
+WERROR ntptr_XcvDataMonitor(struct ntptr_GenericHandle *monitor, TALLOC_CTX *mem_ctx,
+ struct spoolss_XcvData *r)
+{
+ if (monitor->type != NTPTR_HANDLE_MONITOR) {
+ return WERR_FOOBAR;
+ }
+ if (!monitor->ntptr->ops->XcvDataMonitor) {
+ return WERR_NOT_SUPPORTED;
+ }
+ return monitor->ntptr->ops->XcvDataMonitor(monitor, mem_ctx, r);
+}
+
+
+/* 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);
+}
+
+WERROR ntptr_XcvDataPrinter(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
+ struct spoolss_XcvData *r)
+{
+ if (printer->type != NTPTR_HANDLE_PRINTER) {
+ return WERR_FOOBAR;
+ }
+ if (!printer->ntptr->ops->XcvDataPrinter) {
+ return WERR_NOT_SUPPORTED;
+ }
+ return printer->ntptr->ops->XcvDataPrinter(printer, 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..3573fac3ea
--- /dev/null
+++ b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c
@@ -0,0 +1,848 @@
+/*
+ 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ 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 "auth/auth.h"
+#include "dsdb/samdb/samdb.h"
+#include "ldb_wrap.h"
+#include "util/util_ldb.h"
+#include "rpc_server/common/common.h"
+#include "param/param.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, struct event_context *ev_ctx, struct loadparm_context *lp_ctx)
+{
+ return ldb_wrap_connect(mem_ctx, ev_ctx, lp_ctx, lp_spoolss_url(lp_ctx), system_session(mem_ctx, lp_ctx),
+ NULL, 0, NULL);
+}
+
+static int sptr_db_search(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_dn *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,
+ struct ldb_dn *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;
+}
+
+#define SET_STRING(ldb, mod, attr, value) do { \
+ if (value == NULL) return WERR_INVALID_PARAM; \
+ if (samdb_msg_add_string(ldb, (TALLOC_CTX *)mod, mod, attr, value) != 0) { \
+ return WERR_NOMEM; \
+ } \
+} while (0)
+
+#define SET_UINT(ldb, mod, attr, value) do { \
+ if (samdb_msg_add_uint(ldb, (TALLOC_CTX *)mod, mod, attr, value) != 0) { \
+ return WERR_NOMEM; \
+ } \
+} while (0)
+
+static NTSTATUS sptr_init_context(struct ntptr_context *ntptr)
+{
+ struct ldb_context *sptr_db = sptr_db_connect(ntptr, ntptr->ev_ctx, ntptr->lp_ctx);
+ 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->object_name = talloc_strdup(server, server_name);
+ W_ERROR_HAVE_NO_MEMORY(server->object_name);
+ server->access_mask = 0;
+ 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;
+ } else if (strcmp("OSVersion", r->in.value_name) == 0) {
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+ struct spoolss_OSVersion os;
+
+ os.major = dcesrv_common_get_version_major(mem_ctx, server->ntptr->lp_ctx);
+ os.minor = dcesrv_common_get_version_minor(mem_ctx, server->ntptr->lp_ctx);
+ os.build = dcesrv_common_get_version_build(mem_ctx, server->ntptr->lp_ctx);
+ os.extra_string = "";
+
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(server->ntptr->lp_ctx), &os, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return WERR_GENERAL_FAILURE;
+ }
+
+ r->out.type = SPOOLSS_PRINTER_DATA_TYPE_BINARY;
+ r->out.data.binary = blob;
+ return WERR_OK;
+ } else if (strcmp("OSVersionEx", r->in.value_name) == 0) {
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+ struct spoolss_OSVersionEx os_ex;
+
+ os_ex.major = dcesrv_common_get_version_major(mem_ctx, server->ntptr->lp_ctx);
+ os_ex.minor = dcesrv_common_get_version_minor(mem_ctx, server->ntptr->lp_ctx);
+ os_ex.build = dcesrv_common_get_version_build(mem_ctx, server->ntptr->lp_ctx);
+ os_ex.extra_string = "";
+ os_ex.unknown2 = 0;
+ os_ex.unknown3 = 0;
+
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(server->ntptr->lp_ctx), &os_ex, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersionEx);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return WERR_GENERAL_FAILURE;
+ }
+
+ r->out.type = SPOOLSS_PRINTER_DATA_TYPE_BINARY;
+ r->out.data.binary = blob;
+ return WERR_OK;
+ } else if (strcmp("DNSMachineName", r->in.value_name) == 0) {
+ if (!lp_realm(server->ntptr->lp_ctx)) return WERR_INVALID_PARAM;
+
+ r->out.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
+ r->out.data.string = talloc_asprintf(mem_ctx, "%s.%s",
+ lp_netbios_name(server->ntptr->lp_ctx),
+ lp_realm(server->ntptr->lp_ctx));
+ W_ERROR_HAVE_NO_MEMORY(r->out.data.string);
+ 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,
+ ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,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_BUILTIN);
+
+ info[i].info1.form_name = samdb_result_string(msgs[i], "form-name", NULL);
+ W_ERROR_HAVE_NO_MEMORY(info[i].info1.form_name);
+
+ info[i].info1.size.width = samdb_result_uint(msgs[i], "size-width", 0);
+ info[i].info1.size.height = samdb_result_uint(msgs[i], "size-height", 0);
+
+ 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], "area-right", 0);
+ info[i].info1.area.bottom = samdb_result_uint(msgs[i], "area-bottom", 0);
+ }
+ break;
+ default:
+ return WERR_UNKNOWN_LEVEL;
+ }
+
+ r->out.info = info;
+ r->out.count = count;
+ return WERR_OK;
+}
+
+static WERROR sptr_AddPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
+ struct spoolss_AddForm *r)
+{
+ struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
+ struct ldb_message *msg,**msgs;
+ const char * const attrs[] = {"flags", NULL };
+ int count, ret;
+
+ /* TODO: do checks access here
+ * if (!(server->access_mask & desired_access)) {
+ * return WERR_FOOBAR;
+ * }
+ */
+
+ switch (r->in.level) {
+ case 1:
+ if (!r->in.info.info1) {
+ return WERR_FOOBAR;
+ }
+ count = sptr_db_search(sptr_db, mem_ctx,
+ ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
+ &msgs, attrs, "(&(form-name=%s)(objectClass=form))",
+ r->in.info.info1->form_name);
+
+ if (count == 1) return WERR_FOOBAR;
+ if (count > 1) return WERR_FOOBAR;
+ if (count < 0) return WERR_GENERAL_FAILURE;
+
+ if (r->in.info.info1->flags != SPOOLSS_FORM_USER) {
+ return WERR_FOOBAR;
+ }
+
+ msg = ldb_msg_new(mem_ctx);
+ W_ERROR_HAVE_NO_MEMORY(msg);
+
+ /* add core elements to the ldb_message for the Form */
+ msg->dn = ldb_dn_new_fmt(msg, sptr_db, "form-name=%s,CN=Forms,CN=PrintServer", r->in.info.info1->form_name);
+ SET_STRING(sptr_db, msg, "objectClass", "form");
+
+ SET_UINT(sptr_db, msg, "flags", r->in.info.info1->flags);
+
+ SET_STRING(sptr_db, msg, "form-name", r->in.info.info1->form_name);
+
+ SET_UINT(sptr_db, msg, "size-width", r->in.info.info1->size.width);
+ SET_UINT(sptr_db, msg, "size-height", r->in.info.info1->size.height);
+
+ SET_UINT(sptr_db, msg, "area-left", r->in.info.info1->area.left);
+ SET_UINT(sptr_db, msg, "area-top", r->in.info.info1->area.top);
+ SET_UINT(sptr_db, msg, "area-right", r->in.info.info1->area.right);
+ SET_UINT(sptr_db, msg, "area-bottom", r->in.info.info1->area.bottom);
+ break;
+ default:
+ return WERR_UNKNOWN_LEVEL;
+ }
+
+ ret = ldb_add(sptr_db, msg);
+ if (ret != 0) {
+ return WERR_FOOBAR;
+ }
+
+ return WERR_OK;
+}
+
+static WERROR sptr_SetPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
+ struct spoolss_SetForm *r)
+{
+ struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
+ struct ldb_message *msg,**msgs;
+ const char * const attrs[] = { "flags", NULL};
+ int count, ret;
+ enum spoolss_FormFlags flags;
+
+ /* TODO: do checks access here
+ * if (!(server->access_mask & desired_access)) {
+ * return WERR_FOOBAR;
+ * }
+ */
+
+ switch (r->in.level) {
+ case 1:
+ if (!r->in.info.info1) {
+ return WERR_FOOBAR;
+ }
+
+ count = sptr_db_search(sptr_db, mem_ctx,
+ ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
+ &msgs, attrs, "(&(form-name=%s)(objectClass=form))",
+ r->in.info.info1->form_name);
+
+ if (count == 0) return WERR_FOOBAR;
+ if (count > 1) return WERR_FOOBAR;
+ if (count < 0) return WERR_GENERAL_FAILURE;
+
+ flags = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN);
+ if (flags != SPOOLSS_FORM_USER) {
+ return WERR_FOOBAR;
+ }
+
+ msg = ldb_msg_new(mem_ctx);
+ W_ERROR_HAVE_NO_MEMORY(msg);
+
+ /* add core elements to the ldb_message for the user */
+ msg->dn = msgs[0]->dn;
+
+ SET_UINT(sptr_db, msg, "flags", r->in.info.info1->flags);
+
+ SET_STRING(sptr_db, msg, "form-name", r->in.info.info1->form_name);
+
+ SET_UINT(sptr_db, msg, "size-width", r->in.info.info1->size.width);
+ SET_UINT(sptr_db, msg, "size-height", r->in.info.info1->size.height);
+
+ SET_UINT(sptr_db, msg, "area-left", r->in.info.info1->area.left);
+ SET_UINT(sptr_db, msg, "area-top", r->in.info.info1->area.top);
+ SET_UINT(sptr_db, msg, "area-right", r->in.info.info1->area.right);
+ SET_UINT(sptr_db, msg, "area-bottom", r->in.info.info1->area.bottom);
+ break;
+ default:
+ return WERR_UNKNOWN_LEVEL;
+ }
+
+ ret = samdb_replace(sptr_db, mem_ctx, msg);
+ if (ret != 0) {
+ return WERR_FOOBAR;
+ }
+
+ return WERR_OK;
+}
+
+static WERROR sptr_DeletePrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
+ struct spoolss_DeleteForm *r)
+{
+ struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
+ struct ldb_message **msgs;
+ const char * const attrs[] = { "flags", NULL};
+ int count, ret;
+ enum spoolss_FormFlags flags;
+
+ /* TODO: do checks access here
+ * if (!(server->access_mask & desired_access)) {
+ * return WERR_FOOBAR;
+ * }
+ */
+
+ if (!r->in.form_name) {
+ return WERR_FOOBAR;
+ }
+
+ count = sptr_db_search(sptr_db, mem_ctx,
+ ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
+ &msgs, attrs, "(&(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;
+
+ flags = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN);
+ if (flags != SPOOLSS_FORM_USER) {
+ return WERR_FOOBAR;
+ }
+
+ ret = ldb_delete(sptr_db, msgs[0]->dn);
+ if (ret != 0) {
+ return WERR_FOOBAR;
+ }
+
+ 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;
+}
+
+/* Printer Form functions */
+static WERROR sptr_GetPrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
+ struct spoolss_GetForm *r)
+{
+ struct ldb_context *sptr_db = talloc_get_type(printer->ntptr->private_data, struct ldb_context);
+ struct ldb_message **msgs;
+ struct ldb_dn *base_dn;
+ int count;
+ union spoolss_FormInfo *info;
+
+ /* TODO: do checks access here
+ * if (!(printer->access_mask & desired_access)) {
+ * return WERR_FOOBAR;
+ * }
+ */
+
+ base_dn = ldb_dn_new_fmt(mem_ctx, sptr_db, "CN=Forms,CN=%s,CN=Printers", printer->object_name);
+ W_ERROR_HAVE_NO_MEMORY(base_dn);
+
+ count = sptr_db_search(sptr_db, mem_ctx, base_dn, &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_BUILTIN);
+
+ info->info1.form_name = samdb_result_string(msgs[0], "form-name", NULL);
+ W_ERROR_HAVE_NO_MEMORY(info->info1.form_name);
+
+ info->info1.size.width = samdb_result_uint(msgs[0], "size-width", 0);
+ info->info1.size.height = samdb_result_uint(msgs[0], "size-height", 0);
+
+ 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], "area-right", 0);
+ info->info1.area.bottom = samdb_result_uint(msgs[0], "area-bottom", 0);
+ break;
+ default:
+ return WERR_UNKNOWN_LEVEL;
+ }
+
+ r->out.info = info;
+ 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,
+/* .XcvDataPrintServer = sptr_XcvDataPrintServer,
+*/
+ /* PrintServer PrinterData functions */
+/* .EnumPrintServerData = sptr_EnumPrintServerData,
+*/ .GetPrintServerData = sptr_GetPrintServerData,
+/* .SetPrintServerData = sptr_SetPrintServerData,
+ .DeletePrintServerData = sptr_DeletePrintServerData,
+*/
+ /* PrintServer Form functions */
+ .EnumPrintServerForms = sptr_EnumPrintServerForms,
+ .AddPrintServerForm = sptr_AddPrintServerForm,
+ .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,
+ .XcvDataPort = sptr_XcvDataPort,
+*/
+ /* Monitor functions */
+ .EnumMonitors = sptr_EnumMonitors,
+/* .OpenMonitor = sptr_OpenMonitor,
+ .XcvDataMonitor = sptr_XcvDataMonitor,
+*/
+ /* 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,
+ .XcvDataPrinter = sptr_XcvDataPrinter,
+*/
+ /* 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;
+}