summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/config.list1
-rw-r--r--source4/include/structs.h35
-rw-r--r--source4/librpc/idl/spoolss.idl2
-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
-rw-r--r--source4/param/loadparm.c4
-rw-r--r--source4/rpc_server/config.mk8
-rw-r--r--source4/rpc_server/spoolss/dcesrv_spoolss.c803
-rw-r--r--source4/rpc_server/spoolss/dcesrv_spoolss.h38
-rw-r--r--source4/rpc_server/spoolss/spoolssdb.c113
13 files changed, 1839 insertions, 669 deletions
diff --git a/source4/config.list b/source4/config.list
index cc8262314c..69b79c11b0 100644
--- a/source4/config.list
+++ b/source4/config.list
@@ -38,6 +38,7 @@ utils/config.mk
ntvfs/posix/config.mk
ntvfs/config.mk
ntvfs/unixuid/config.mk
+ntptr/config.mk
torture/config.mk
librpc/config.mk
client/config.mk
diff --git a/source4/include/structs.h b/source4/include/structs.h
index 944f79225b..2c8003e791 100644
--- a/source4/include/structs.h
+++ b/source4/include/structs.h
@@ -37,8 +37,43 @@ union spoolss_FormInfo;
union spoolss_PortInfo;
union spoolss_MonitorInfo;
union spoolss_PrintProcessorInfo;
+
struct spoolss_GetPrinterData;
struct spoolss_SetPrinterData;
+struct spoolss_OpenPrinterEx;
+struct spoolss_EnumPrinterData;
+struct spoolss_DeletePrinterData;
+struct spoolss_AddForm;
+struct spoolss_GetForm;
+struct spoolss_SetForm;
+struct spoolss_DeleteForm;
+struct spoolss_AddPrinterDriver;
+struct spoolss_DeletePrinterDriver;
+struct spoolss_GetPrinterDriverDirectory;
+struct spoolss_AddPrinter;
+struct spoolss_GetPrinter;
+struct spoolss_SetPrinter;
+struct spoolss_DeletePrinter;
+struct spoolss_GetPrinterDriver;
+struct spoolss_EnumPrinterData;
+struct spoolss_DeletePrinterData;
+struct spoolss_AddForm;
+struct spoolss_GetForm;
+struct spoolss_SetForm;
+struct spoolss_DeleteForm;
+struct spoolss_AddJob;
+struct spoolss_ScheduleJob;
+struct spoolss_GetJob;
+struct spoolss_SetJob;
+struct spoolss_StartDocPrinter;
+struct spoolss_EndDocPrinter;
+struct spoolss_StartPagePrinter;
+struct spoolss_EndPagePrinter;
+struct spoolss_WritePrinter;
+struct spoolss_ReadPrinter;
+
+struct ntptr_context;
+struct ntptr_GenericHandle;
struct drsuapi_DsReplicaObjectListItem;
struct drsuapi_DsReplicaObjectListItemEx;
diff --git a/source4/librpc/idl/spoolss.idl b/source4/librpc/idl/spoolss.idl
index 0321ad16cb..33ae96caf5 100644
--- a/source4/librpc/idl/spoolss.idl
+++ b/source4/librpc/idl/spoolss.idl
@@ -878,7 +878,7 @@
[in,switch_is(level)] spoolss_SetFormInfo info
);
- typedef [nodiscriminant,relative_base,public] union {
+ typedef [nodiscriminant,relative_base,public,gensize] union {
[case(1)] spoolss_FormInfo1 info1;
[default];
} spoolss_FormInfo;
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;
+}
diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c
index deb7d2284f..92e98dcf7d 100644
--- a/source4/param/loadparm.c
+++ b/source4/param/loadparm.c
@@ -167,6 +167,7 @@ typedef struct
char *szWINSPartners;
char **dcerpc_ep_servers;
char **server_services;
+ char *ntptr_providor;
char *szWinbindUID;
char *szWinbindGID;
char *szNonUnixAccountRange;
@@ -528,6 +529,7 @@ static struct parm_struct parm_table[] = {
{"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
{"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
{"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
+ {"ntptr providor", P_STRING, P_GLOBAL, &Globals.ntptr_providor, NULL, NULL, FLAG_ADVANCED},
{"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
{"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
@@ -921,6 +923,7 @@ static void init_globals(void)
do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup");
do_parameter("server services", "smb rpc nbt ldap cldap web");
+ do_parameter("ntptr providor", "simple_ldb");
do_parameter("auth methods", "anonymous sam_ignoredomain");
do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
do_parameter("private dir", dyn_PRIVATE_DIR);
@@ -1175,6 +1178,7 @@ FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
+FN_GLOBAL_STRING(lp_ntptr_providor, &Globals.ntptr_providor)
FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk
index c6407e3e53..af3c61cb2e 100644
--- a/source4/rpc_server/config.mk
+++ b/source4/rpc_server/config.mk
@@ -161,12 +161,12 @@ REQUIRED_SUBSYSTEMS = \
INIT_FUNCTION = dcerpc_server_spoolss_init
SUBSYSTEM = DCERPC
INIT_OBJ_FILES = \
- rpc_server/spoolss/dcesrv_spoolss.o \
- rpc_server/spoolss/spoolssdb.o
+ rpc_server/spoolss/dcesrv_spoolss.o
REQUIRED_SUBSYSTEMS = \
DCERPC_COMMON \
- NDR_SPOOLSS
-# End MODULE dcerpc_lsa
+ NDR_SPOOLSS \
+ NTPTR
+# End MODULE dcerpc_spoolss
################################################
################################################
diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c
index 5c6506b7c2..7689f084a9 100644
--- a/source4/rpc_server/spoolss/dcesrv_spoolss.c
+++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c
@@ -25,138 +25,186 @@
#include "rpc_server/dcerpc_server.h"
#include "librpc/gen_ndr/ndr_spoolss.h"
#include "rpc_server/common/common.h"
-#include "rpc_server/spoolss/dcesrv_spoolss.h"
+#include "ntptr/ntptr.h"
#include "lib/socket/socket.h"
#include "smbd/service_stream.h"
-#define SPOOLSS_BUFFER_SIZE(fn,level,count,info) \
- ndr_size_##fn##_info(dce_call, level, count, info)
+#define SPOOLSS_BUFFER_UNION(fn,info,level) \
+ ((info)?ndr_size_##fn(info, level, 0):0)
+
+#define SPOOLSS_BUFFER_UNION_ARRAY(fn,info,level,count) \
+ ((info)?ndr_size_##fn##_info(dce_call, level, count, info):0)
#define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= r->out.needed)?val_true:val_false)
-/*
- spoolss_EnumPrinters
-*/
-static WERROR spoolss_EnumPrinters(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct spoolss_EnumPrinters *r)
+static WERROR spoolss_parse_printer_name(TALLOC_CTX *mem_ctx, const char *name,
+ const char **_server_name,
+ const char **_object_name,
+ enum ntptr_HandleType *_object_type)
{
- void *spoolss_ctx;
- struct ldb_message **msgs;
- int count;
- int i;
- union spoolss_PrinterInfo *info;
+ char *p;
+ char *server = NULL;
+ char *server_unc = NULL;
+ const char *object = name;
- spoolss_ctx = spoolssdb_connect();
- W_ERROR_HAVE_NO_MEMORY(spoolss_ctx);
+ /* no printername is there it's like open server */
+ if (!name) {
+ *_server_name = NULL;
+ *_object_name = NULL;
+ *_object_type = NTPTR_HANDLE_SERVER;
+ return WERR_OK;
+ }
- count = spoolssdb_search(spoolss_ctx, mem_ctx, NULL, &msgs, NULL,
- "(&(objectclass=printer))");
- spoolssdb_close(spoolss_ctx);
+ /* just "\\" is invalid */
+ if (strequal("\\\\", name)) {
+ return WERR_INVALID_PRINTER_NAME;
+ }
- if (count == 0) return WERR_OK;
- if (count < 0) return WERR_GENERAL_FAILURE;
+ if (strncmp("\\\\", name, 2) == 0) {
+ server_unc = talloc_strdup(mem_ctx, name);
+ W_ERROR_HAVE_NO_MEMORY(server_unc);
+ server = server_unc + 2;
- info = talloc_array(mem_ctx, union spoolss_PrinterInfo, count);
- W_ERROR_HAVE_NO_MEMORY(info);
+ /* here we know we have "\\" in front not followed
+ * by '\0', now see if we have another "\" in the string
+ */
+ p = strchr_m(server, '\\');
+ if (!p) {
+ /* there's no other "\", so it's ("\\%s",server)
+ */
+ *_server_name = server_unc;
+ *_object_name = NULL;
+ *_object_type = NTPTR_HANDLE_SERVER;
+ return WERR_OK;
+ }
+ /* here we know that we have ("\\%s\",server),
+ * if we have '\0' as next then it's an invalid name
+ * otherwise the printer_name
+ */
+ p[0] = '\0';
+ /* everything that follows is the printer name */
+ p++;
+ object = p;
- switch(r->in.level) {
- case 1:
- for (i = 0; i < count; i++) {
- info[i].info1.flags = samdb_result_uint(msgs[i], "flags", 0);
+ /* just "" as server is invalid */
+ if (strequal(server, "")) {
+ return WERR_INVALID_PRINTER_NAME;
+ }
+ }
- info[i].info1.name = samdb_result_string(msgs[i], "name", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info1.name);
+ /* just "" is invalid */
+ if (strequal(object, "")) {
+ return WERR_INVALID_PRINTER_NAME;
+ }
- info[i].info1.description = samdb_result_string(msgs[i], "description", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info1.description);
+#define XCV_PORT ",XcvPort "
+#define XCV_MONITOR ",XcvMonitor "
+ if (strncmp(object, XCV_PORT, strlen(XCV_PORT)) == 0) {
+ object += strlen(XCV_PORT);
- info[i].info1.comment = samdb_result_string(msgs[i], "comment", NULL);
+ /* just "" is invalid */
+ if (strequal(object, "")) {
+ return WERR_INVALID_PRINTER_NAME;
}
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinters, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- case 2:
- for (i = 0; i < count; i++) {
- info[i].info2.servername = samdb_result_string(msgs[i], "servername", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername);
- info[i].info2.printername = samdb_result_string(msgs[i], "printername", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername);
+ *_server_name = server_unc;
+ *_object_name = object;
+ *_object_type = NTPTR_HANDLE_PORT;
+ return WERR_OK;
+ } else if (strncmp(object, XCV_MONITOR, strlen(XCV_MONITOR)) == 0) {
+ object += strlen(XCV_MONITOR);
- info[i].info2.sharename = samdb_result_string(msgs[i], "sharename", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.sharename);
+ /* just "" is invalid */
+ if (strequal(object, "")) {
+ return WERR_INVALID_PRINTER_NAME;
+ }
- info[i].info2.portname = samdb_result_string(msgs[i], "portname", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.portname);
+ *_server_name = server_unc;
+ *_object_name = object;
+ *_object_type = NTPTR_HANDLE_MONITOR;
+ return WERR_OK;
+ }
- info[i].info2.drivername = samdb_result_string(msgs[i], "drivername", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.drivername);
+ *_server_name = server_unc;
+ *_object_name = object;
+ *_object_type = NTPTR_HANDLE_PRINTER;
+ return WERR_OK;
+}
- info[i].info2.comment = samdb_result_string(msgs[i], "comment", NULL);
+/*
+ * Check server_name is:
+ * - "" , functions that don't allow "",
+ * should check that on their own, before calling this function
+ * - our name (only netbios yet, TODO: need to test dns name!)
+ * - our ip address of the current use socket
+ * otherwise return WERR_INVALID_PRINTER_NAME
+ */
+static WERROR spoolss_check_server_name(struct dcesrv_call_state *dce_call,
+ TALLOC_CTX *mem_ctx,
+ const char *server_name)
+{
+ BOOL ret;
+ const char *ip_str;
- info[i].info2.location = samdb_result_string(msgs[i], "location", NULL);
+ if (!server_name) return WERR_OK;
- info[i].info2.devmode = NULL;
+ ret = strequal("",server_name);
+ if (ret) return WERR_OK;
- info[i].info2.sepfile = samdb_result_string(msgs[i], "sepfile", NULL);
+ if (strncmp("\\\\", server_name, 2) != 0) {
+ return WERR_INVALID_PRINTER_NAME;
+ }
- info[i].info2.printprocessor = samdb_result_string(msgs[i], "printprocessor", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.printprocessor);
+ server_name += 2;
- info[i].info2.datatype = samdb_result_string(msgs[i], "datatype", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.datatype);
+ ret = strequal(lp_netbios_name(), server_name);
+ if (ret) return WERR_OK;
- info[i].info2.parameters = samdb_result_string(msgs[i], "parameters", NULL);
+ /* TODO: check dns name here ? */
- info[i].info2.secdesc = NULL;
+ ip_str = socket_get_my_addr(dce_call->conn->srv_conn->socket, mem_ctx);
+ W_ERROR_HAVE_NO_MEMORY(ip_str);
- info[i].info2.attributes = samdb_result_uint(msgs[i], "attributes", 0);
- info[i].info2.priority = samdb_result_uint(msgs[i], "priority", 0);
- info[i].info2.defaultpriority = samdb_result_uint(msgs[i], "defaultpriority", 0);
- info[i].info2.starttime = samdb_result_uint(msgs[i], "starttime", 0);
- info[i].info2.untiltime = samdb_result_uint(msgs[i], "untiltime", 0);
- info[i].info2.status = samdb_result_uint(msgs[i], "status", 0);
- info[i].info2.cjobs = samdb_result_uint(msgs[i], "cjobs", 0);
- info[i].info2.averageppm = samdb_result_uint(msgs[i], "averageppm", 0);
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinters, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- case 4:
- for (i = 0; i < count; i++) {
- info[i].info4.printername = samdb_result_string(msgs[i], "printername", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername);
-
- info[i].info4.servername = samdb_result_string(msgs[i], "servername", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername);
-
- info[i].info4.attributes = samdb_result_uint(msgs[i], "attributes", 0);
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinters, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- case 5:
- for (i = 0; i < count; i++) {
- info[i].info5.printername = samdb_result_string(msgs[i], "name", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info5.printername);
-
- info[i].info5.portname = samdb_result_string(msgs[i], "port", "");
- W_ERROR_HAVE_NO_MEMORY(info[i].info5.portname);
-
- info[i].info5.attributes = samdb_result_uint(msgs[i], "attributes", 0);
- info[i].info5.device_not_selected_timeout = samdb_result_uint(msgs[i], "device_not_selected_timeout", 0);
- info[i].info5.transmission_retry_timeout = samdb_result_uint(msgs[i], "transmission_retry_timeout", 0);
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinters, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- }
+ ret = strequal(ip_str, server_name);
+ if (ret) return WERR_OK;
+
+ return WERR_INVALID_PRINTER_NAME;
+}
+
+static NTSTATUS dcerpc_spoolss_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface)
+{
+ NTSTATUS status;
+ struct ntptr_context *ntptr;
+
+ status = ntptr_init_context(dce_call->context, lp_ntptr_providor(), &ntptr);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ dce_call->context->private = ntptr;
+
+ return NT_STATUS_OK;
+}
+
+#define DCESRV_INTERFACE_SPOOLSS_BIND dcerpc_spoolss_bind
+
+/*
+ spoolss_EnumPrinters
+*/
+static WERROR spoolss_EnumPrinters(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct spoolss_EnumPrinters *r)
+{
+ struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
+ WERROR status;
- return WERR_UNKNOWN_LEVEL;
+ status = spoolss_check_server_name(dce_call, mem_ctx, r->in.server);
+ W_ERROR_NOT_OK_RETURN(status);
+
+ status = ntptr_EnumPrinters(ntptr, mem_ctx, r);
+ W_ERROR_NOT_OK_RETURN(status);
+
+ r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinters, r->out.info, r->in.level, r->out.count);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+ r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0);
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
static WERROR spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
@@ -279,64 +327,19 @@ static WERROR spoolss_AddPrinterDriver(struct dcesrv_call_state *dce_call, TALLO
static WERROR spoolss_EnumPrinterDrivers(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_EnumPrinterDrivers *r)
{
- union spoolss_DriverInfo *info;
- int count;
- int i;
-
- count = 0;
-
- if (count == 0) return WERR_OK;
- if (count < 0) return WERR_GENERAL_FAILURE;
+ struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
+ WERROR status;
- info = talloc_array(mem_ctx, union spoolss_DriverInfo, count);
- W_ERROR_HAVE_NO_MEMORY(info);
+ status = spoolss_check_server_name(dce_call, mem_ctx, r->in.server);
+ W_ERROR_NOT_OK_RETURN(status);
- switch (r->in.level) {
- case 1:
- for (i=0; i < count; i++) {
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- case 2:
- for (i=0; i < count; i++) {
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- case 3:
- for (i=0; i < count; i++) {
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- case 4:
- for (i=0; i < count; i++) {
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- case 5:
- for (i=0; i < count; i++) {
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- case 6:
- for (i=0; i < count; i++) {
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPrinterDrivers, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- }
+ status = ntptr_EnumPrinterDrivers(ntptr, mem_ctx, r);
+ W_ERROR_NOT_OK_RETURN(status);
- return WERR_UNKNOWN_LEVEL;
+ r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinterDrivers, r->out.info, r->in.level, r->out.count);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+ r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0);
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
@@ -356,42 +359,17 @@ static WERROR spoolss_GetPrinterDriver(struct dcesrv_call_state *dce_call, TALLO
static WERROR spoolss_GetPrinterDriverDirectory(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
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 (strcmp("", r->in.server) == 0) {
- prefix = "C:\\DRIVERS";
- } else {
- prefix = talloc_asprintf(mem_ctx, "%s\\print$", r->in.server);
- W_ERROR_HAVE_NO_MEMORY(prefix);
- }
-
- if (strcmp(SPOOLSS_ARCHITECTURE_NT_X86, r->in.environment) == 0) {
- postfix = "W32X86";
- } else {
- return WERR_INVALID_ENVIRONMENT;
- }
+ struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
+ WERROR status;
- info = talloc(mem_ctx, union spoolss_DriverDirectoryInfo);
- W_ERROR_HAVE_NO_MEMORY(info);
+ status = spoolss_check_server_name(dce_call, mem_ctx, r->in.server);
+ W_ERROR_NOT_OK_RETURN(status);
- info->info1.directory_name = talloc_asprintf(mem_ctx, "%s\\%s", prefix, postfix);
- W_ERROR_HAVE_NO_MEMORY(info->info1.directory_name);
+ status = ntptr_GetPrinterDriverDirectory(ntptr, mem_ctx, r);
+ W_ERROR_NOT_OK_RETURN(status);
- r->out.needed = ndr_size_spoolss_DriverDirectoryInfo(info, r->in.level, 0);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
+ r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, r->out.info, r->in.level);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
@@ -532,67 +510,28 @@ static WERROR spoolss_ScheduleJob(struct dcesrv_call_state *dce_call, TALLOC_CTX
static WERROR spoolss_GetPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_GetPrinterData *r)
{
+ struct ntptr_GenericHandle *handle;
struct dcesrv_handle *h;
- WERROR status = WERR_INVALID_PARAM;
- enum spoolss_PrinterDataType type = SPOOLSS_PRINTER_DATA_TYPE_NULL;
- union spoolss_PrinterData data;
+ WERROR status;
DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
-
- if (h->wire_handle.handle_type == SPOOLSS_HANDLE_SERVER) {
- /* TODO: do access check here */
-
- if (strcmp("W3SvcInstalled", r->in.value_name) == 0) {
- type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- data.value = 0;
- status = WERR_OK;
- } else if (strcmp("BeepEnabled", r->in.value_name) == 0) {
- type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- data.value = 0;
- status = WERR_OK;
- } else if (strcmp("EventLog", r->in.value_name) == 0) {
- type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- data.value = 0;
- status = WERR_OK;
- } else if (strcmp("NetPopup", r->in.value_name) == 0) {
- type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- data.value = 0;
- status = WERR_OK;
- } else if (strcmp("NetPopupToComputer", r->in.value_name) == 0) {
- type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- data.value = 0;
- status = WERR_OK;
- } else if (strcmp("MajorVersion", r->in.value_name) == 0) {
- type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- data.value = 3;
- status = WERR_OK;
- } else if (strcmp("MinorVersion", r->in.value_name) == 0) {
- type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- data.value = 0;
- status = WERR_OK;
- } else if (strcmp("DefaultSpoolDirectory", r->in.value_name) == 0) {
- type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
- data.string = "C:\\PRINTERS";
- status = WERR_OK;
- } else if (strcmp("Architecture", r->in.value_name) == 0) {
- type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
- data.string = SPOOLSS_ARCHITECTURE_NT_X86;
- status = WERR_OK;
- } else if (strcmp("DsPresent", r->in.value_name) == 0) {
- type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- data.value = 1;
- status = WERR_OK;
- }
+ handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
+
+ switch (handle->type) {
+ case NTPTR_HANDLE_SERVER:
+ status = ntptr_GetPrintServerData(handle, mem_ctx, r);
+ break;
+ default:
+ status = WERR_FOOBAR;
+ break;
}
- if (W_ERROR_IS_OK(status)) {
- r->out.needed = ndr_size_spoolss_PrinterData(&data, type, 0);
- r->out.type = SPOOLSS_BUFFER_OK(type, SPOOLSS_PRINTER_DATA_TYPE_NULL);
- r->out.data = SPOOLSS_BUFFER_OK(data, data);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
- }
+ W_ERROR_NOT_OK_RETURN(status);
- return status;
+ r->out.needed = ndr_size_spoolss_PrinterData(&r->out.data, r->out.type, 0);
+ r->out.type = SPOOLSS_BUFFER_OK(r->out.type, SPOOLSS_PRINTER_DATA_TYPE_NULL);
+ r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
}
@@ -662,7 +601,29 @@ static WERROR spoolss_DeleteForm(struct dcesrv_call_state *dce_call, TALLOC_CTX
static WERROR spoolss_GetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_GetForm *r)
{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ struct ntptr_GenericHandle *handle;
+ struct dcesrv_handle *h;
+ WERROR status;
+
+ DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
+ handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
+
+ switch (handle->type) {
+ case NTPTR_HANDLE_SERVER:
+ status = ntptr_GetPrintServerForm(handle, mem_ctx, r);
+ W_ERROR_NOT_OK_RETURN(status);
+ break;
+ case NTPTR_HANDLE_PRINTER:
+ status = ntptr_GetPrinterForm(handle, mem_ctx, r);
+ W_ERROR_NOT_OK_RETURN(status);
+ break;
+ default:
+ return WERR_FOOBAR;
+ }
+
+ r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, r->out.info, r->in.level);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
@@ -682,44 +643,30 @@ static WERROR spoolss_SetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
static WERROR spoolss_EnumForms(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_EnumForms *r)
{
- union spoolss_FormInfo *info;
- int count;
- int i;
+ struct ntptr_GenericHandle *handle;
struct dcesrv_handle *h;
+ WERROR status;
DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
-
- count = 1;
-
- 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 = SPOOLSS_FORM_PRINTER;
-
- info[i].info1.form_name = talloc_strdup(mem_ctx, "Letter");
- W_ERROR_HAVE_NO_MEMORY(info[i].info1.form_name);
-
- info[i].info1.size.width = 0x34b5c;
- info[i].info1.size.height = 0x44368;
-
- info[i].info1.area.left = 0;
- info[i].info1.area.top = 0;
- info[i].info1.area.right = 0x34b5c;
- info[i].info1.area.bottom = 0x44368;
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumForms, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+ handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
+
+ switch (handle->type) {
+ case NTPTR_HANDLE_SERVER:
+ status = ntptr_EnumPrintServerForms(handle, mem_ctx, r);
+ W_ERROR_NOT_OK_RETURN(status);
+ break;
+ case NTPTR_HANDLE_PRINTER:
+ status = ntptr_EnumPrinterForms(handle, mem_ctx, r);
+ W_ERROR_NOT_OK_RETURN(status);
+ break;
+ default:
+ return WERR_FOOBAR;
}
- return WERR_UNKNOWN_LEVEL;
+ r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumForms, r->out.info, r->in.level, r->out.count);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+ r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0);
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
@@ -729,49 +676,19 @@ static WERROR spoolss_EnumForms(struct dcesrv_call_state *dce_call, TALLOC_CTX *
static WERROR spoolss_EnumPorts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_EnumPorts *r)
{
- union spoolss_PortInfo *info;
- int count;
- int i;
-
- count = 1;
+ struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
+ WERROR status;
- if (count == 0) return WERR_OK;
- if (count < 0) return WERR_GENERAL_FAILURE;
+ status = spoolss_check_server_name(dce_call, mem_ctx, r->in.servername);
+ W_ERROR_NOT_OK_RETURN(status);
- info = talloc_array(mem_ctx, union spoolss_PortInfo, count);
- W_ERROR_HAVE_NO_MEMORY(info);
+ status = ntptr_EnumPorts(ntptr, mem_ctx, r);
+ W_ERROR_NOT_OK_RETURN(status);
- switch (r->in.level) {
- case 1:
- for (i=0; i < count; i++) {
- info[i].info1.port_name = talloc_strdup(mem_ctx, "Samba Printer Port");
- W_ERROR_HAVE_NO_MEMORY(info[i].info1.port_name);
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPorts, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- case 2:
- for (i=0; i < count; i++) {
- info[i].info2.port_name = talloc_strdup(mem_ctx, "Samba Printer Port");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.port_name);
-
- info[i].info2.monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name);
-
- info[i].info2.description = talloc_strdup(mem_ctx, "Local Port");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.description);
-
- info[i].info2.port_type = SPOOLSS_PORT_TYPE_WRITE;
- info[i].info2.reserved = 0;
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumPorts, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- }
-
- return WERR_UNKNOWN_LEVEL;
+ r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPorts, r->out.info, r->in.level, r->out.count);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+ r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0);
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
@@ -781,46 +698,19 @@ static WERROR spoolss_EnumPorts(struct dcesrv_call_state *dce_call, TALLOC_CTX *
static WERROR spoolss_EnumMonitors(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_EnumMonitors *r)
{
- union spoolss_MonitorInfo *info;
- int count;
- int i;
-
- count = 1;
-
- if (count == 0) return WERR_OK;
- if (count < 0) return WERR_GENERAL_FAILURE;
+ struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
+ WERROR status;
- info = talloc_array(mem_ctx, union spoolss_MonitorInfo, count);
- W_ERROR_HAVE_NO_MEMORY(info);
+ status = spoolss_check_server_name(dce_call, mem_ctx, r->in.servername);
+ W_ERROR_NOT_OK_RETURN(status);
- switch (r->in.level) {
- case 1:
- for (i=0; i < count; i++) {
- info[i].info1.monitor_name = talloc_strdup(mem_ctx, "Standard TCP/IP Port");
- W_ERROR_HAVE_NO_MEMORY(info[i].info1.monitor_name);
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumMonitors, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- case 2:
- for (i=0; i < count; i++) {
- info[i].info2.monitor_name = talloc_strdup(mem_ctx, "Standard TCP/IP Port");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name);
-
- info[i].info2.environment = talloc_strdup(mem_ctx, SPOOLSS_ARCHITECTURE_NT_X86);
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.environment);
-
- info[i].info2.dll_name = talloc_strdup(mem_ctx, "tcpmon.dll");
- W_ERROR_HAVE_NO_MEMORY(info[i].info2.dll_name);
- }
- r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumMonitors, r->in.level, count, info);
- r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
- r->out.count = SPOOLSS_BUFFER_OK(count, 0);
- return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
- }
+ status = ntptr_EnumMonitors(ntptr, mem_ctx, r);
+ W_ERROR_NOT_OK_RETURN(status);
- return WERR_UNKNOWN_LEVEL;
+ r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumMonitors, r->out.info, r->in.level, r->out.count);
+ r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+ r->out.count = SPOOLSS_BUFFER_OK(r->out.count, 0);
+ return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
@@ -1110,7 +1000,12 @@ static WERROR spoolss_ResetPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_
static WERROR spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
{
- return WERR_NOT_SUPPORTED;
+ /*
+ * TODO: for now just return ok,
+ * to keep the w2k3 PrintServer
+ * happy to allow to open the Add Printer GUI
+ */
+ return WERR_OK;
}
@@ -1143,175 +1038,57 @@ static WERROR spoolss_44(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
-
-static WERROR spoolss_OpenPrinterEx_server(struct dcesrv_call_state *dce_call,
- TALLOC_CTX *mem_ctx,
- struct spoolss_OpenPrinterEx *r,
- const char *server_name)
-{
- struct spoolss_handle_server *state;
- struct dcesrv_handle *handle;
- BOOL ret;
-
- /* Check printername is our name or our ip address
- */
- ret = strequal(server_name, lp_netbios_name());
- if (!ret) {
- const char *ip = socket_get_my_addr(dce_call->conn->srv_conn->socket, mem_ctx);
- W_ERROR_HAVE_NO_MEMORY(ip);
-
- ret = strequal(server_name, ip);
- if (!ret) {
- return WERR_INVALID_PRINTER_NAME;
- }
- }
-
- /* TODO: do access check here */
-
- handle = dcesrv_handle_new(dce_call->context, SPOOLSS_HANDLE_SERVER);
- W_ERROR_HAVE_NO_MEMORY(handle);
-
- state = talloc(handle, struct spoolss_handle_server);
- W_ERROR_HAVE_NO_MEMORY(state);
-
- handle->data = state;
-
- state->access_mask = r->in.access_mask;
-
- *r->out.handle = handle->wire_handle;
-
- return WERR_OK;
-}
-
-static WERROR spoolss_OpenPrinterEx_port(struct dcesrv_call_state *dce_call,
- TALLOC_CTX *mem_ctx,
- struct spoolss_OpenPrinterEx *r,
- const char *server_name,
- const char *port_name)
-{
- DEBUG(1, ("looking for port [%s] (server[%s])\n", port_name, server_name));
-
- return WERR_INVALID_PRINTER_NAME;
-}
-
-static WERROR spoolss_OpenPrinterEx_monitor(struct dcesrv_call_state *dce_call,
- TALLOC_CTX *mem_ctx,
- struct spoolss_OpenPrinterEx *r,
- const char *server_name,
- const char *monitor_name)
-{
- if (strequal("Standard TCP/IP Port", monitor_name)) {
- struct dcesrv_handle *handle;
-
- handle = dcesrv_handle_new(dce_call->context, SPOOLSS_HANDLE_MONITOR);
- W_ERROR_HAVE_NO_MEMORY(handle);
-
- handle->data = NULL;
-
- *r->out.handle = handle->wire_handle;
-
- return WERR_OK;
- }
-
- DEBUG(1, ("looking for monitor [%s] (server[%s])\n", monitor_name, server_name));
-
- return WERR_INVALID_PRINTER_NAME;
-}
-
-static WERROR spoolss_OpenPrinterEx_printer(struct dcesrv_call_state *dce_call,
- TALLOC_CTX *mem_ctx,
- struct spoolss_OpenPrinterEx *r,
- const char *server_name,
- const char *printer_name)
-{
- DEBUG(3, ("looking for printer [%s] (server[%s])\n", printer_name, server_name));
-
- return WERR_INVALID_PRINTER_NAME;
-}
-
/*
spoolss_OpenPrinterEx
*/
static WERROR spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_OpenPrinterEx *r)
{
- char *p;
- char *server = NULL;
- const char *object = r->in.printername;
- ZERO_STRUCTP(r->out.handle);
-
- /* no printername is there it's like open server */
- if (!r->in.printername) {
- return spoolss_OpenPrinterEx_server(dce_call, mem_ctx, r, NULL);
- }
-
- /* just "\\" is invalid */
- if (strequal(r->in.printername, "\\\\")) {
- return WERR_INVALID_PRINTER_NAME;
- }
-
- if (strncmp(r->in.printername, "\\\\", 2) == 0) {
- server = talloc_strdup(mem_ctx, r->in.printername + 2);
- W_ERROR_HAVE_NO_MEMORY(server);
-
- /* here we know we have "\\" in front not followed
- * by '\0', now see if we have another "\" in the string
- */
- p = strchr_m(server, '\\');
- if (!p) {
- /* there's no other "\", so it's ("\\%s",server)
- */
- return spoolss_OpenPrinterEx_server(dce_call, mem_ctx, r, server);
- }
- /* here we know that we have ("\\%s\",server),
- * if we have '\0' as next then it's an invalid name
- * otherwise the printer_name
- */
- p[0] = '\0';
- /* everything that follows is the printer name */
- p++;
- object = p;
+ struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private, struct ntptr_context);
+ struct ntptr_GenericHandle *handle;
+ struct dcesrv_handle *h;
+ const char *server;
+ const char *object;
+ enum ntptr_HandleType type;
+ WERROR status;
- /* just "" as server is invalid */
- if (strequal(server, "")) {
- DEBUG(2,("OpenPrinterEx invalid print server: [%s][%s][%s]\n", r->in.printername, server, object));
- return WERR_INVALID_PRINTER_NAME;
- }
- }
+ ZERO_STRUCTP(r->out.handle);
- /* just "" is invalid */
- if (strequal(object, "")) {
- DEBUG(2,("OpenPrinterEx invalid object: [%s][%s][%s]\n", r->in.printername, server, object));
- return WERR_INVALID_PRINTER_NAME;
+ status = spoolss_parse_printer_name(mem_ctx, r->in.printername, &server, &object, &type);
+ W_ERROR_NOT_OK_RETURN(status);
+
+ status = spoolss_check_server_name(dce_call, mem_ctx, server);
+ W_ERROR_NOT_OK_RETURN(status);
+
+ switch (type) {
+ case NTPTR_HANDLE_SERVER:
+ status = ntptr_OpenPrintServer(ntptr, mem_ctx, r, server, &handle);
+ W_ERROR_NOT_OK_RETURN(status);
+ break;
+ case NTPTR_HANDLE_PORT:
+ status = ntptr_OpenPort(ntptr, mem_ctx, r, object, &handle);
+ W_ERROR_NOT_OK_RETURN(status);
+ break;
+ case NTPTR_HANDLE_MONITOR:
+ status = ntptr_OpenMonitor(ntptr, mem_ctx, r, object, &handle);
+ W_ERROR_NOT_OK_RETURN(status);
+ break;
+ case NTPTR_HANDLE_PRINTER:
+ status = ntptr_OpenPrinter(ntptr, mem_ctx, r, object, &handle);
+ W_ERROR_NOT_OK_RETURN(status);
+ break;
+ default:
+ return WERR_FOOBAR;
}
- DEBUG(3,("OpenPrinterEx object: [%s][%s][%s]\n", r->in.printername, server, object));
-
-#define XCV_PORT ",XcvPort "
-#define XCV_MONITOR ",XcvMonitor "
- if (strncmp(object, XCV_PORT, strlen(XCV_PORT)) == 0) {
- object += strlen(XCV_PORT);
-
- /* just "" is invalid */
- if (strequal(object, "")) {
- DEBUG(2,("OpenPrinterEx invalid port: [%s][%s][%s]\n", r->in.printername, server, object));
- return WERR_INVALID_PRINTER_NAME;
- }
+ h = dcesrv_handle_new(dce_call->context, handle->type);
+ W_ERROR_HAVE_NO_MEMORY(h);
- return spoolss_OpenPrinterEx_port(dce_call, mem_ctx, r, server, object);
- } else if (strncmp(object, XCV_MONITOR, strlen(XCV_MONITOR)) == 0) {
- object += strlen(XCV_MONITOR);
+ h->data = talloc_steal(h, handle);
- /* just "" is invalid */
- if (strequal(object, "")) {
- DEBUG(2,("OpenPrinterEx invalid monitor: [%s][%s][%s]\n", r->in.printername, server, object));
- return WERR_INVALID_PRINTER_NAME;
- }
+ *r->out.handle = h->wire_handle;
- return spoolss_OpenPrinterEx_monitor(dce_call, mem_ctx, r, server, object);
- }
-
- return spoolss_OpenPrinterEx_printer(dce_call, mem_ctx, r, server, object);
+ return WERR_OK;
}
/*
diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.h b/source4/rpc_server/spoolss/dcesrv_spoolss.h
deleted file mode 100644
index 0b3f69ca2a..0000000000
--- a/source4/rpc_server/spoolss/dcesrv_spoolss.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- endpoint server for the spoolss pipe - definitions
-
- Copyright (C) Tim Potter 2004
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- this type allows us to distinguish handle types
-*/
-enum spoolss_handle_type {
- SPOOLSS_HANDLE_SERVER,
- SPOOLSS_HANDLE_PRINTER,
- SPOOLSS_HANDLE_PORT,
- SPOOLSS_HANDLE_MONITOR
-};
-
-/*
- state asscoiated with a spoolss_OpenPrinter{,Ex}() operation
-*/
-struct spoolss_handle_server {
- uint32_t access_mask;
-};
diff --git a/source4/rpc_server/spoolss/spoolssdb.c b/source4/rpc_server/spoolss/spoolssdb.c
deleted file mode 100644
index cec9ade0d4..0000000000
--- a/source4/rpc_server/spoolss/spoolssdb.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- interface functions for the spoolss database
-
- Copyright (C) Andrew Tridgell 2004
- Copyright (C) Tim Potter 2004
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-#include "lib/ldb/include/ldb.h"
-
-struct spoolssdb_context {
- struct ldb_context *ldb;
-};
-
-/*
- this is used to catch debug messages from ldb
-*/
-static void spoolssdb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
-static void spoolssdb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
-{
- char *s = NULL;
- if (DEBUGLEVEL < 4 && level > LDB_DEBUG_WARNING) {
- return;
- }
- vasprintf(&s, fmt, ap);
- if (!s) return;
- DEBUG(level, ("spoolssdb: %s\n", s));
- free(s);
-}
-
-/*
- connect to the spoolss database
- return an opaque context pointer on success, or NULL on failure
- */
-void *spoolssdb_connect(void)
-{
- struct spoolssdb_context *ctx;
- /*
- the way that unix fcntl locking works forces us to have a
- static ldb handle here rather than a much more sensible
- approach of having the ldb handle as part of the
- spoolss_OpenPrinter() pipe state. Otherwise we would try to open
- the ldb more than once, and tdb would rightly refuse the
- second open due to the broken nature of unix locking.
- */
- static struct ldb_context *static_spoolss_db;
-
- if (static_spoolss_db == NULL) {
- static_spoolss_db = ldb_connect(lp_spoolss_url(), 0, NULL);
- if (static_spoolss_db == NULL) {
- return NULL;
- }
- }
-
- ldb_set_debug(static_spoolss_db, spoolssdb_debug, NULL);
-
- ctx = malloc_p(struct spoolssdb_context);
- if (!ctx) {
- errno = ENOMEM;
- return NULL;
- }
-
- ctx->ldb = static_spoolss_db;
-
- return ctx;
-}
-
-/* close a connection to the spoolss db */
-void spoolssdb_close(void *ctx)
-{
- struct spoolssdb_context *spoolss_ctx = ctx;
- /* we don't actually close due to broken posix locking semantics */
- spoolss_ctx->ldb = NULL;
- free(spoolss_ctx);
-}
-
-/*
- search the db for the specified attributes - varargs variant
-*/
-int spoolssdb_search(void *ctx,
- TALLOC_CTX *mem_ctx,
- const char *basedn,
- struct ldb_message ***res,
- const char * const *attrs,
- const char *format, ...) _PRINTF_ATTRIBUTE(6,7)
-{
- struct spoolssdb_context *spoolss_ctx = ctx;
- va_list ap;
- int count;
-
- va_start(ap, format);
- count = gendb_search_v(spoolss_ctx->ldb, mem_ctx, basedn, res, attrs, format, ap);
- va_end(ap);
-
- return count;
-}
-