Merge branch 'nodiscard' of /home/jelmer/samba4
authorJelmer Vernooij <jelmer@samba.org>
Sun, 15 Mar 2009 14:39:15 +0000 (15:39 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Sun, 15 Mar 2009 14:39:15 +0000 (15:39 +0100)
90 files changed:
docs-xml/manpages-3/vfs_preopen.8.xml [new file with mode: 0644]
lib/async_req/async_sock.c
lib/replace/libreplace_network.m4
lib/replace/system/network.h
lib/talloc/talloc.c
lib/talloc/talloc.h
lib/tdr/TODO [moved from source4/lib/tdr/TODO with 100% similarity]
lib/tdr/config.mk [moved from source4/lib/tdr/config.mk with 100% similarity]
lib/tdr/tdr.c [moved from source4/lib/tdr/tdr.c with 99% similarity]
lib/tdr/tdr.h [moved from source4/lib/tdr/tdr.h with 100% similarity]
lib/tdr/testsuite.c [moved from source4/lib/tdr/testsuite.c with 88% similarity]
lib/tevent/configure.ac
lib/tevent/tevent.c
lib/tevent/tevent.h
lib/tevent/tevent_epoll.c
lib/tevent/tevent_internal.h
lib/tevent/tevent_select.c
lib/tevent/tevent_standard.c
lib/util/fault.m4
librpc/gen_ndr/ndr_spoolss.c
librpc/gen_ndr/ndr_spoolss.h
librpc/gen_ndr/spoolss.h
librpc/idl/spoolss.idl
librpc/ndr/ndr_spoolss_buf.c
librpc/ndr/ndr_spoolss_buf.h
m4/pkg.m4 [new file with mode: 0644]
pidl/lib/Parse/Pidl/Samba4/TDR.pm
source3/Makefile.in
source3/autogen.sh
source3/client/client.c
source3/client/mount.cifs.c
source3/configure.in
source3/include/client.h
source3/include/proto.h
source3/include/rpc_spoolss.h
source3/include/smb.h
source3/include/smbprofile.h
source3/include/vfs.h
source3/include/vfs_macros.h
source3/include/wbc_async.h
source3/lib/events.c
source3/lib/netapi/cm.c
source3/lib/wb_reqtrans.c
source3/libsmb/cliconnect.c
source3/libsmb/clidfs.c
source3/libsmb/clientgen.c
source3/libsmb/clilist.c
source3/libsmb/clireadwrite.c
source3/libsmb/passchange.c
source3/libsmb/pwd_cache.c [deleted file]
source3/locking/locking.c
source3/modules/onefs.h
source3/modules/onefs_cbrl.c
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_onefs.c
source3/modules/vfs_preopen.c [new file with mode: 0644]
source3/nmbd/nmbd_nameregister.c
source3/passdb/pdb_wbc_sam.c
source3/printing/printing.c
source3/rpc_client/cli_pipe.c
source3/rpc_client/cli_spoolss.c
source3/rpc_parse/parse_spoolss.c
source3/rpc_server/srv_spoolss.c
source3/rpc_server/srv_spoolss_nt.c
source3/rpcclient/cmd_spoolss.c
source3/samba4.m4
source3/samba4.mk
source3/smbd/open.c
source3/smbd/reply.c
source3/torture/torture.c
source3/utils/net_rpc_printer.c
source3/winbindd/idmap_util.c
source3/winbindd/winbindd.c
source3/winbindd/winbindd_cache.c
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_group.c
source3/winbindd/winbindd_proto.h
source4/Makefile
source4/auth/config.m4
source4/build/m4/public.m4
source4/build/smb_build/main.pl
source4/configure.ac
source4/lib/events/tevent_s4.c
source4/lib/ldb/common/ldb.c
source4/main.mk
source4/scripting/python/samba/samdb.py
source4/torture/ldap/cldapbench.c
source4/torture/local/config.mk
source4/torture/rpc/spoolss.c

diff --git a/docs-xml/manpages-3/vfs_preopen.8.xml b/docs-xml/manpages-3/vfs_preopen.8.xml
new file mode 100644 (file)
index 0000000..a84d472
--- /dev/null
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
+<refentry id="vfs_preopen.8">
+
+<refmeta>
+       <refentrytitle>vfs_preopen</refentrytitle>
+       <manvolnum>8</manvolnum>
+       <refmiscinfo class="source">Samba</refmiscinfo>
+       <refmiscinfo class="manual">System Administration tools</refmiscinfo>
+       <refmiscinfo class="version">3.3</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+       <refname>vfs_preopen</refname>
+       <refpurpose>Hide read latencies for applications reading numbered files</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+       <cmdsynopsis>
+               <command>vfs objects = preopen</command>
+       </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+       <title>DESCRIPTION</title>
+
+       <para>This VFS module is part of the
+       <citerefentry><refentrytitle>samba</refentrytitle>
+       <manvolnum>7</manvolnum></citerefentry> suite.</para>
+
+       <para>This module assists applications that want to read numbered
+       files in sequence with very strict latency requirements. One area
+       where this happens in video streaming applications that want to read
+       one file per frame.</para>
+
+       <para>When you use this module, a number of helper processes is
+       started that speculatively open files and read a number of bytes to
+       prime the file system cache, so that later on when the real
+       application's request comes along, no disk access is necessary.</para>
+
+       <para>This module is stackable.</para>
+
+</refsect1>
+
+
+<refsect1>
+       <title>OPTIONS</title>
+
+       <variablelist>
+
+               <varlistentry>
+               <term>preopen:names = /pattern/</term>
+               <listitem>
+               <para>
+               preopen:names specifies the file name pattern which should
+               trigger the preopen helpers to do their work. We assume that
+               the files are numbered incrementally. So if your file names
+               are numbered FRAME00000.frm FRAME00001.frm and so on you would
+               list them as <command>preopen:names=/FRAME*.frm/</command>
+               </para>
+               </listitem>
+               </varlistentry>
+
+               <varlistentry>
+               <term>preopen:num_bytes = BYTES</term>
+               <listitem>
+               <para>
+               Specifies the number of bytes the helpers should speculatively
+               read, defaults to 1.
+               </para>
+               </listitem>
+               </varlistentry>
+
+               <varlistentry>
+               <term>preopen:helpers = NUM-PROCS</term>
+               <listitem>
+               <para>
+               Number of forked helper processes, defaults to 1.
+               </para>
+               </listitem>
+               </varlistentry>
+
+               <varlistentry>
+               <term>preopen:queuelen = NUM-FILES</term>
+               <listitem>
+               <para>
+               Number of files that should be speculatively opened. Defaults
+               to the 10 subsequent files.
+               </para>
+               </listitem>
+               </varlistentry>
+
+       </variablelist>
+</refsect1>
+
+<refsect1>
+       <title>VERSION</title>
+       <para>This man page is correct for version 3.3 of the Samba suite.
+       </para>
+</refsect1>
+
+<refsect1>
+       <title>AUTHOR</title>
+
+       <para>The original Samba software and related utilities
+       were created by Andrew Tridgell. Samba is now developed
+       by the Samba Team as an Open Source project similar
+       to the way the Linux kernel is developed.</para>
+
+       <para>The PREOPEN VFS module was created with contributions from
+       Volker Lendecke and the developers at IBM.
+       </para>
+</refsect1>
+
+</refentry>
index f803b9cc36bf683cfd749c74c2f82e77ac15a779..be24bae6dfd5b27ea9dc8c2b3aca7e39530b3192 100644 (file)
@@ -485,7 +485,7 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
                        state->iov[0].iov_len -= written;
                        break;
                }
-               written = state->iov[0].iov_len;
+               written -= state->iov[0].iov_len;
                state->iov += 1;
                state->count -= 1;
        }
index 78fb1abaf014e247808731cbd7085ac141a50753..1dc1c44ed8e4ec6b4e630109c3e16ec566b76693 100644 (file)
@@ -16,6 +16,7 @@ AC_CHECK_HEADERS([netinet/ip.h], [], [],[#ifdef HAVE_NETINET_IN_H
 #endif])
 AC_CHECK_HEADERS(netinet/tcp.h netinet/in_ip.h)
 AC_CHECK_HEADERS(sys/sockio.h sys/un.h)
+AC_CHECK_HEADERS(sys/uio.h)
 
 dnl we need to check that net/if.h really can be used, to cope with hpux
 dnl where including it always fails
index f135d175d43dcecfc6a2ec7bc92eb5d805528ce3..6add99c0db7cfc13b08e7d21eaa127f2e700d160 100644 (file)
 #include <sys/ioctl.h>
 #endif
 
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+
 #ifdef HAVE_STROPTS_H
 #include <stropts.h>
 #endif
index c472e9fda9c685e7bab11f1ff83f562662c0569e..60a48ad8112593754fe1729f2dc3e243924fc76d 100644 (file)
@@ -138,14 +138,30 @@ struct talloc_chunk {
 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
 
+static void (*talloc_abort_fn)(const char *reason);
+
+void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
+{
+       talloc_abort_fn = abort_fn;
+}
+
+static void talloc_abort(const char *reason)
+{
+       if (!talloc_abort_fn) {
+               TALLOC_ABORT(reason);
+       }
+
+       talloc_abort_fn(reason);
+}
+
 static void talloc_abort_double_free(void)
 {
-       TALLOC_ABORT("Bad talloc magic value - double free"); 
+       talloc_abort("Bad talloc magic value - double free");
 }
 
 static void talloc_abort_unknown_value(void)
 {
-       TALLOC_ABORT("Bad talloc magic value - unknown value"); 
+       talloc_abort("Bad talloc magic value - unknown value");
 }
 
 /* panic if we get a bad magic value */
@@ -564,7 +580,7 @@ static inline int _talloc_free(void *ptr)
                pool_object_count = talloc_pool_objectcount(pool);
 
                if (*pool_object_count == 0) {
-                       TALLOC_ABORT("Pool object count zero!");
+                       talloc_abort("Pool object count zero!");
                }
 
                *pool_object_count -= 1;
@@ -810,7 +826,18 @@ static void talloc_abort_type_missmatch(const char *location,
                                        const char *name,
                                        const char *expected)
 {
-       TALLOC_ABORT("Type missmatch");
+       const char *reason;
+
+       reason = talloc_asprintf(NULL,
+                                "%s: Type mismatch: name[%s] expected[%s]",
+                                location,
+                                name?name:"NULL",
+                                expected);
+       if (!reason) {
+               reason = "Type mismatch";
+       }
+
+       talloc_abort(reason);
 }
 
 void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
index 002e06e52da9e175f9f4e6e48be320efc03c79c0..b62393494b6cef28e98aaf8ef31d3f279c8e1be5 100644 (file)
@@ -182,4 +182,6 @@ char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3)
 char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
 char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
 
+void talloc_set_abort_fn(void (*abort_fn)(const char *reason));
+
 #endif
similarity index 100%
rename from source4/lib/tdr/TODO
rename to lib/tdr/TODO
similarity index 100%
rename from source4/lib/tdr/config.mk
rename to lib/tdr/config.mk
similarity index 99%
rename from source4/lib/tdr/tdr.c
rename to lib/tdr/tdr.c
index 8b62ea0c2b989b06171985a8bf7f947128d2645a..293436ed5e3474a942a1ab53efadbe65892aec3e 100644 (file)
@@ -23,7 +23,7 @@
 #include "includes.h"
 #include "system/filesys.h"
 #include "system/network.h"
-#include "tdr/tdr.h"
+#include "lib/tdr/tdr.h"
 
 #define TDR_BASE_MARSHALL_SIZE 1024
 
similarity index 100%
rename from source4/lib/tdr/tdr.h
rename to lib/tdr/tdr.h
similarity index 88%
rename from source4/lib/tdr/testsuite.c
rename to lib/tdr/testsuite.c
index 44c5810f90741a9528ddf7fb86ae7840975b2024..36bb164a9a3310dff30dee0fd47e8e5edbd64e9b 100644 (file)
 #include "includes.h"
 #include "torture/torture.h"
 #include "lib/tdr/tdr.h"
-#include "param/param.h"
 
 static bool test_push_uint8(struct torture_context *tctx)
 {
        uint8_t v = 4;
-       struct tdr_push *tdr = tdr_push_init(tctx, lp_iconv_convenience(tctx->lp_ctx));
+       struct tdr_push *tdr = tdr_push_init(tctx, global_iconv_convenience);
 
        torture_assert_ntstatus_ok(tctx, tdr_push_uint8(tdr, &v), "push failed");
        torture_assert_int_equal(tctx, tdr->data.length, 1, "length incorrect");
@@ -38,7 +37,7 @@ static bool test_pull_uint8(struct torture_context *tctx)
 {
        uint8_t d = 2;
        uint8_t l;
-       struct tdr_pull *tdr = tdr_pull_init(tctx, lp_iconv_convenience(tctx->lp_ctx));
+       struct tdr_pull *tdr = tdr_pull_init(tctx, global_iconv_convenience);
        tdr->data.data = &d;
        tdr->data.length = 1;
        tdr->offset = 0;
@@ -53,7 +52,7 @@ static bool test_pull_uint8(struct torture_context *tctx)
 static bool test_push_uint16(struct torture_context *tctx)
 {
        uint16_t v = 0xF32;
-       struct tdr_push *tdr = tdr_push_init(tctx, lp_iconv_convenience(tctx->lp_ctx));
+       struct tdr_push *tdr = tdr_push_init(tctx, global_iconv_convenience);
 
        torture_assert_ntstatus_ok(tctx, tdr_push_uint16(tdr, &v), "push failed");
        torture_assert_int_equal(tctx, tdr->data.length, 2, "length incorrect");
@@ -66,7 +65,7 @@ static bool test_pull_uint16(struct torture_context *tctx)
 {
        uint8_t d[2] = { 782 & 0xFF, (782 & 0xFF00) / 0x100 };
        uint16_t l;
-       struct tdr_pull *tdr = tdr_pull_init(tctx, lp_iconv_convenience(tctx->lp_ctx));
+       struct tdr_pull *tdr = tdr_pull_init(tctx, global_iconv_convenience);
        tdr->data.data = d;
        tdr->data.length = 2;
        tdr->offset = 0;
@@ -81,7 +80,7 @@ static bool test_pull_uint16(struct torture_context *tctx)
 static bool test_push_uint32(struct torture_context *tctx)
 {
        uint32_t v = 0x100F32;
-       struct tdr_push *tdr = tdr_push_init(tctx, lp_iconv_convenience(tctx->lp_ctx));
+       struct tdr_push *tdr = tdr_push_init(tctx, global_iconv_convenience);
 
        torture_assert_ntstatus_ok(tctx, tdr_push_uint32(tdr, &v), "push failed");
        torture_assert_int_equal(tctx, tdr->data.length, 4, "length incorrect");
@@ -96,7 +95,7 @@ static bool test_pull_uint32(struct torture_context *tctx)
 {
        uint8_t d[4] = { 782 & 0xFF, (782 & 0xFF00) / 0x100, 0, 0 };
        uint32_t l;
-       struct tdr_pull *tdr = tdr_pull_init(tctx, lp_iconv_convenience(tctx->lp_ctx));
+       struct tdr_pull *tdr = tdr_pull_init(tctx, global_iconv_convenience);
        tdr->data.data = d;
        tdr->data.length = 4;
        tdr->offset = 0;
@@ -110,7 +109,7 @@ static bool test_pull_uint32(struct torture_context *tctx)
 
 static bool test_pull_charset(struct torture_context *tctx)
 {
-       struct tdr_pull *tdr = tdr_pull_init(tctx, lp_iconv_convenience(tctx->lp_ctx));
+       struct tdr_pull *tdr = tdr_pull_init(tctx, global_iconv_convenience);
        const char *l = NULL;
        tdr->data.data = (uint8_t *)talloc_strdup(tctx, "bla");
        tdr->data.length = 4;
@@ -132,7 +131,7 @@ static bool test_pull_charset(struct torture_context *tctx)
 
 static bool test_pull_charset_empty(struct torture_context *tctx)
 {
-       struct tdr_pull *tdr = tdr_pull_init(tctx, lp_iconv_convenience(tctx->lp_ctx));
+       struct tdr_pull *tdr = tdr_pull_init(tctx, global_iconv_convenience);
        const char *l = NULL;
        tdr->data.data = (uint8_t *)talloc_strdup(tctx, "bla");
        tdr->data.length = 4;
@@ -151,7 +150,7 @@ static bool test_pull_charset_empty(struct torture_context *tctx)
 static bool test_push_charset(struct torture_context *tctx)
 {
        const char *l = "bloe";
-       struct tdr_push *tdr = tdr_push_init(tctx, lp_iconv_convenience(tctx->lp_ctx));
+       struct tdr_push *tdr = tdr_push_init(tctx, global_iconv_convenience);
        torture_assert_ntstatus_ok(tctx, tdr_push_charset(tdr, &l, 4, 1, CH_UTF8), 
                                                           "push failed");
        torture_assert_int_equal(tctx, 4, tdr->data.length, "offset invalid");
index 4333461110d6f52e2f7bb9b5f3d2ce3f455d05fc..69f65c6df7fae99da63240a424cf577309043edd 100644 (file)
@@ -1,5 +1,5 @@
 AC_PREREQ(2.50)
-AC_INIT(tevent, 0.9.3)
+AC_INIT(tevent, 0.9.4)
 AC_CONFIG_SRCDIR([tevent.c])
 AC_CONFIG_HEADER(config.h)
 
index fc8252960ae2d8c9b0efde71e1401e314246649f..867cfc08feff88c3532a98f76c94d1f5b8fb0e47 100644 (file)
@@ -59,6 +59,7 @@
 */
 #include "replace.h"
 #include "system/filesys.h"
+#define TEVENT_DEPRECATED 1
 #include "tevent.h"
 #include "tevent_internal.h"
 #include "tevent_util.h"
@@ -305,6 +306,33 @@ void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags)
        fde->event_ctx->ops->set_fd_flags(fde, flags);
 }
 
+bool tevent_signal_support(struct tevent_context *ev)
+{
+       if (ev->ops->add_signal) {
+               return true;
+       }
+       return false;
+}
+
+static void (*tevent_abort_fn)(const char *reason);
+
+void tevent_set_abort_fn(void (*abort_fn)(const char *reason))
+{
+       tevent_abort_fn = abort_fn;
+}
+
+static void tevent_abort(struct tevent_context *ev, const char *reason)
+{
+       tevent_debug(ev, TEVENT_DEBUG_FATAL,
+                    "abort: %s\n", reason);
+
+       if (!tevent_abort_fn) {
+               abort();
+       }
+
+       tevent_abort_fn(reason);
+}
+
 /*
   add a timer event
   return NULL on failure
@@ -341,18 +369,152 @@ struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
                                   handler_name, location);
 }
 
+void tevent_loop_allow_nesting(struct tevent_context *ev)
+{
+       ev->nesting.allowed = true;
+}
+
+void tevent_loop_set_nesting_hook(struct tevent_context *ev,
+                                 tevent_nesting_hook hook,
+                                 void *private_data)
+{
+       ev->nesting.hook_fn = hook;
+       ev->nesting.hook_private = private_data;
+}
+
+static void tevent_abort_nesting(struct tevent_context *ev, const char *location)
+{
+       const char *reason;
+
+       reason = talloc_asprintf(NULL, "tevent_loop_once() nesting at %s",
+                                location);
+       if (!reason) {
+               reason = "tevent_loop_once() nesting";
+       }
+
+       tevent_abort(ev, reason);
+}
+
 /*
   do a single event loop using the events defined in ev 
 */
-int tevent_loop_once(struct tevent_context *ev)
+int _tevent_loop_once(struct tevent_context *ev, const char *location)
 {
-       return ev->ops->loop_once(ev);
+       int ret;
+       void *nesting_stack_ptr = NULL;
+
+       ev->nesting.level++;
+
+       if (ev->nesting.level > 1) {
+               if (!ev->nesting.allowed) {
+                       tevent_abort_nesting(ev, location);
+                       errno = ELOOP;
+                       return -1;
+               }
+               if (ev->nesting.hook_fn) {
+                       int ret2;
+                       ret2 = ev->nesting.hook_fn(ev,
+                                                  ev->nesting.hook_private,
+                                                  ev->nesting.level,
+                                                  true,
+                                                  (void *)&nesting_stack_ptr,
+                                                  location);
+                       if (ret2 != 0) {
+                               ret = ret2;
+                               goto done;
+                       }
+               }
+       }
+
+       ret = ev->ops->loop_once(ev, location);
+
+       if (ev->nesting.level > 1) {
+               if (ev->nesting.hook_fn) {
+                       int ret2;
+                       ret2 = ev->nesting.hook_fn(ev,
+                                                  ev->nesting.hook_private,
+                                                  ev->nesting.level,
+                                                  false,
+                                                  (void *)&nesting_stack_ptr,
+                                                  location);
+                       if (ret2 != 0) {
+                               ret = ret2;
+                               goto done;
+                       }
+               }
+       }
+
+done:
+       ev->nesting.level--;
+       return ret;
+}
+
+/*
+  this is a performance optimization for the samba4 nested event loop problems
+*/
+int _tevent_loop_until(struct tevent_context *ev,
+                      bool (*finished)(void *private_data),
+                      void *private_data,
+                      const char *location)
+{
+       int ret = 0;
+       void *nesting_stack_ptr = NULL;
+
+       ev->nesting.level++;
+
+       if (ev->nesting.level > 1) {
+               if (!ev->nesting.allowed) {
+                       tevent_abort_nesting(ev, location);
+                       errno = ELOOP;
+                       return -1;
+               }
+               if (ev->nesting.hook_fn) {
+                       int ret2;
+                       ret2 = ev->nesting.hook_fn(ev,
+                                                  ev->nesting.hook_private,
+                                                  ev->nesting.level,
+                                                  true,
+                                                  (void *)&nesting_stack_ptr,
+                                                  location);
+                       if (ret2 != 0) {
+                               ret = ret2;
+                               goto done;
+                       }
+               }
+       }
+
+       while (!finished(private_data)) {
+               ret = ev->ops->loop_once(ev, location);
+               if (ret != 0) {
+                       break;
+               }
+       }
+
+       if (ev->nesting.level > 1) {
+               if (ev->nesting.hook_fn) {
+                       int ret2;
+                       ret2 = ev->nesting.hook_fn(ev,
+                                                  ev->nesting.hook_private,
+                                                  ev->nesting.level,
+                                                  false,
+                                                  (void *)&nesting_stack_ptr,
+                                                  location);
+                       if (ret2 != 0) {
+                               ret = ret2;
+                               goto done;
+                       }
+               }
+       }
+
+done:
+       ev->nesting.level--;
+       return ret;
 }
 
 /*
   return on failure or (with 0) if all fd events are removed
 */
-int tevent_loop_wait(struct tevent_context *ev)
+int _tevent_loop_wait(struct tevent_context *ev, const char *location)
 {
-       return ev->ops->loop_wait(ev);
+       return ev->ops->loop_wait(ev, location);
 }
index 2dadfc1abed31e082083619aa8f9eea34e86fd1c..4a3f51ae5eedb4fe90e253845c240118bf63910a 100644 (file)
@@ -99,8 +99,13 @@ struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
        _tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, \
                           #handler, __location__)
 
-int tevent_loop_once(struct tevent_context *ev);
-int tevent_loop_wait(struct tevent_context *ev);
+int _tevent_loop_once(struct tevent_context *ev, const char *location);
+#define tevent_loop_once(ev) \
+       _tevent_loop_once(ev, __location__) \
+
+int _tevent_loop_wait(struct tevent_context *ev, const char *location);
+#define tevent_loop_wait(ev) \
+       _tevent_loop_wait(ev, __location__) \
 
 void tevent_fd_set_close_fn(struct tevent_fd *fde,
                            tevent_fd_close_fn_t close_fn);
@@ -108,6 +113,10 @@ void tevent_fd_set_auto_close(struct tevent_fd *fde);
 uint16_t tevent_fd_get_flags(struct tevent_fd *fde);
 void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
 
+bool tevent_signal_support(struct tevent_context *ev);
+
+void tevent_set_abort_fn(void (*abort_fn)(const char *reason));
+
 /* bits for file descriptor event flags */
 #define TEVENT_FD_READ 1
 #define TEVENT_FD_WRITE 2
@@ -292,6 +301,32 @@ void tevent_queue_stop(struct tevent_queue *queue);
 
 size_t tevent_queue_length(struct tevent_queue *queue);
 
+typedef int (*tevent_nesting_hook)(struct tevent_context *ev,
+                                  void *private_data,
+                                  uint32_t level,
+                                  bool begin,
+                                  void *stack_ptr,
+                                  const char *location);
+#ifdef TEVENT_DEPRECATED
+#ifndef _DEPRECATED_
+#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 )
+#define _DEPRECATED_ __attribute__ ((deprecated))
+#else
+#define _DEPRECATED_
+#endif
+#endif
+void tevent_loop_allow_nesting(struct tevent_context *ev) _DEPRECATED_;
+void tevent_loop_set_nesting_hook(struct tevent_context *ev,
+                                 tevent_nesting_hook hook,
+                                 void *private_data) _DEPRECATED_;
+int _tevent_loop_until(struct tevent_context *ev,
+                      bool (*finished)(void *private_data),
+                      void *private_data,
+                      const char *location) _DEPRECATED_;
+#define tevent_loop_until(ev, finished, private_data) \
+       _tevent_loop_until(ev, finished, private_data, __location__)
+#endif
+
 #ifdef TEVENT_COMPAT_DEFINES
 
 #define event_context  tevent_context
index 0494f55060b713fd375e32620c006c9e910d4466..b63d299d94272efec09d28c06c89a02720a7ce22 100644 (file)
@@ -411,7 +411,7 @@ static void epoll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
 /*
   do a single event loop using the events defined in ev 
 */
-static int epoll_event_loop_once(struct tevent_context *ev)
+static int epoll_event_loop_once(struct tevent_context *ev, const char *location)
 {
        struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data,
                                                           struct epoll_event_context);
@@ -430,12 +430,12 @@ static int epoll_event_loop_once(struct tevent_context *ev)
 /*
   return on failure or (with 0) if all fd events are removed
 */
-static int epoll_event_loop_wait(struct tevent_context *ev)
+static int epoll_event_loop_wait(struct tevent_context *ev, const char *location)
 {
        struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data,
                                                           struct epoll_event_context);
        while (epoll_ev->ev->fd_events) {
-               if (epoll_event_loop_once(ev) != 0) {
+               if (epoll_event_loop_once(ev, location) != 0) {
                        break;
                }
        }
index 5a645ecb6082d1e5ddbce1ef140283cc437ed16b..f10485398f147315d6c71e3058734795f4fb38f7 100644 (file)
@@ -153,8 +153,8 @@ struct tevent_ops {
                                            const char *location);
 
        /* loop functions */
-       int (*loop_once)(struct tevent_context *ev);
-       int (*loop_wait)(struct tevent_context *ev);
+       int (*loop_once)(struct tevent_context *ev, const char *location);
+       int (*loop_wait)(struct tevent_context *ev, const char *location);
 };
 
 struct tevent_fd {
@@ -233,6 +233,14 @@ struct tevent_context {
 
        /* debugging operations */
        struct tevent_debug_ops debug_ops;
+
+       /* info about the nesting status */
+       struct {
+               bool allowed;
+               uint32_t level;
+               tevent_nesting_hook hook_fn;
+               void *hook_private;
+       } nesting;
 };
 
 
index 32678f0a156ccbd517e709f0810f9846ac12a751..cdddb601c42ce78094a46280d869958e8e660ea7 100644 (file)
@@ -213,7 +213,7 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
 /*
   do a single event loop using the events defined in ev 
 */
-static int select_event_loop_once(struct tevent_context *ev)
+static int select_event_loop_once(struct tevent_context *ev, const char *location)
 {
        struct select_event_context *select_ev = talloc_get_type(ev->additional_data,
                                                           struct select_event_context);
@@ -230,14 +230,14 @@ static int select_event_loop_once(struct tevent_context *ev)
 /*
   return on failure or (with 0) if all fd events are removed
 */
-static int select_event_loop_wait(struct tevent_context *ev)
+static int select_event_loop_wait(struct tevent_context *ev, const char *location)
 {
        struct select_event_context *select_ev = talloc_get_type(ev->additional_data,
                                                           struct select_event_context);
        select_ev->exit_code = 0;
 
        while (ev->fd_events && select_ev->exit_code == 0) {
-               if (select_event_loop_once(ev) != 0) {
+               if (select_event_loop_once(ev, location) != 0) {
                        break;
                }
        }
index bbd5c5d78577f7d2b1486a1113b57491b4063375..73a45e8c20fe327d75d35b1b0fd1149c860f0f04 100644 (file)
@@ -534,7 +534,7 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
 /*
   do a single event loop using the events defined in ev 
 */
-static int std_event_loop_once(struct tevent_context *ev)
+static int std_event_loop_once(struct tevent_context *ev, const char *location)
 {
        struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
                                                           struct std_event_context);
@@ -557,14 +557,14 @@ static int std_event_loop_once(struct tevent_context *ev)
 /*
   return on failure or (with 0) if all fd events are removed
 */
-static int std_event_loop_wait(struct tevent_context *ev)
+static int std_event_loop_wait(struct tevent_context *ev, const char *location)
 {
        struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
                                                           struct std_event_context);
        std_ev->exit_code = 0;
 
        while (ev->fd_events && std_ev->exit_code == 0) {
-               if (std_event_loop_once(ev) != 0) {
+               if (std_event_loop_once(ev, location) != 0) {
                        break;
                }
        }
index da077af31da91dd9c156cf14c8b2e076fab7e8ef..bac553a1583c3dd63522ee2a7658766073f61240 100644 (file)
@@ -8,6 +8,7 @@ if test x"$ac_cv_header_execinfo_h" = x"yes" -a x"$ac_cv_func_ext_backtrace" = x
        EXECINFO_CFLAGS="$CFLAGS"
        EXECINFO_CPPFLAGS="$CPPFLAGS"
        EXECINFO_LDFLAGS="$LDFLAGS"
+       LIB_REMOVE_USR_LIB(EXECINFO_LDFLAGS)
 else
        SMB_ENABLE(EXECINFO,NO)
 fi
index 3d1237cc8be4261ddfa2055c6d82a2a06a67f6ab..8c8b687a015fda537bae19b5df62a47dd18c2502 100644 (file)
@@ -304,7 +304,7 @@ _PUBLIC_ void ndr_print_spoolss_JobStatus(struct ndr_print *ndr, const char *nam
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_PrinterInfo0(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo0 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterInfo0(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo0 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -371,7 +371,7 @@ static enum ndr_err_code ndr_push_spoolss_PrinterInfo0(struct ndr_push *ndr, int
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PrinterInfo0(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo0 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterInfo0(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo0 *r)
 {
        uint32_t _ptr_printername;
        TALLOC_CTX *_mem_save_printername_0;
@@ -512,6 +512,11 @@ _PUBLIC_ void ndr_print_spoolss_PrinterInfo0(struct ndr_print *ndr, const char *
        ndr->depth--;
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_PrinterInfo0(const struct spoolss_PrinterInfo0 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterInfo0, ic);
+}
+
 static enum ndr_err_code ndr_push_spoolss_DeviceModeFields(struct ndr_push *ndr, int ndr_flags, uint32_t r)
 {
        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
@@ -758,7 +763,7 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterFlags(struct ndr_print *ndr, const ch
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_PrinterInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo1 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo1 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -814,7 +819,7 @@ static enum ndr_err_code ndr_push_spoolss_PrinterInfo1(struct ndr_push *ndr, int
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PrinterInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo1 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo1 *r)
 {
        uint32_t _ptr_name;
        TALLOC_CTX *_mem_save_name_0;
@@ -938,6 +943,11 @@ _PUBLIC_ void ndr_print_spoolss_PrinterInfo1(struct ndr_print *ndr, const char *
        ndr->depth--;
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_PrinterInfo1(const struct spoolss_PrinterInfo1 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterInfo1, ic);
+}
+
 static enum ndr_err_code ndr_push_spoolss_PrinterAttributes(struct ndr_push *ndr, int ndr_flags, uint32_t r)
 {
        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
@@ -975,7 +985,7 @@ _PUBLIC_ void ndr_print_spoolss_PrinterAttributes(struct ndr_print *ndr, const c
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_PrinterInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo2 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo2 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -1178,7 +1188,7 @@ static enum ndr_err_code ndr_push_spoolss_PrinterInfo2(struct ndr_push *ndr, int
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PrinterInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo2 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo2 *r)
 {
        uint32_t _ptr_servername;
        TALLOC_CTX *_mem_save_servername_0;
@@ -1656,7 +1666,12 @@ _PUBLIC_ void ndr_print_spoolss_PrinterInfo2(struct ndr_print *ndr, const char *
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_PrinterInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo3 *r)
+_PUBLIC_ size_t ndr_size_spoolss_PrinterInfo2(const struct spoolss_PrinterInfo2 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterInfo2, ic);
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo3 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -1676,7 +1691,7 @@ static enum ndr_err_code ndr_push_spoolss_PrinterInfo3(struct ndr_push *ndr, int
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PrinterInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo3 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo3 *r)
 {
        uint32_t _ptr_secdesc;
        TALLOC_CTX *_mem_save_secdesc_0;
@@ -1723,7 +1738,12 @@ _PUBLIC_ void ndr_print_spoolss_PrinterInfo3(struct ndr_print *ndr, const char *
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_PrinterInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo4 *r)
+_PUBLIC_ size_t ndr_size_spoolss_PrinterInfo3(const struct spoolss_PrinterInfo3 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterInfo3, ic);
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo4 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -1764,7 +1784,7 @@ static enum ndr_err_code ndr_push_spoolss_PrinterInfo4(struct ndr_push *ndr, int
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PrinterInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo4 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo4 *r)
 {
        uint32_t _ptr_printername;
        TALLOC_CTX *_mem_save_printername_0;
@@ -1853,7 +1873,12 @@ _PUBLIC_ void ndr_print_spoolss_PrinterInfo4(struct ndr_print *ndr, const char *
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_PrinterInfo5(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo5 *r)
+_PUBLIC_ size_t ndr_size_spoolss_PrinterInfo4(const struct spoolss_PrinterInfo4 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterInfo4, ic);
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterInfo5(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo5 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -1896,7 +1921,7 @@ static enum ndr_err_code ndr_push_spoolss_PrinterInfo5(struct ndr_push *ndr, int
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PrinterInfo5(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo5 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterInfo5(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo5 *r)
 {
        uint32_t _ptr_printername;
        TALLOC_CTX *_mem_save_printername_0;
@@ -1989,7 +2014,12 @@ _PUBLIC_ void ndr_print_spoolss_PrinterInfo5(struct ndr_print *ndr, const char *
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_PrinterInfo6(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo6 *r)
+_PUBLIC_ size_t ndr_size_spoolss_PrinterInfo5(const struct spoolss_PrinterInfo5 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterInfo5, ic);
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterInfo6(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo6 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -2000,7 +2030,7 @@ static enum ndr_err_code ndr_push_spoolss_PrinterInfo6(struct ndr_push *ndr, int
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PrinterInfo6(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo6 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterInfo6(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo6 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_pull_align(ndr, 4));
@@ -2019,6 +2049,11 @@ _PUBLIC_ void ndr_print_spoolss_PrinterInfo6(struct ndr_print *ndr, const char *
        ndr->depth--;
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_PrinterInfo6(const struct spoolss_PrinterInfo6 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterInfo6, ic);
+}
+
 static enum ndr_err_code ndr_push_spoolss_DsPrintAction(struct ndr_push *ndr, int ndr_flags, uint32_t r)
 {
        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
@@ -2045,7 +2080,7 @@ _PUBLIC_ void ndr_print_spoolss_DsPrintAction(struct ndr_print *ndr, const char
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_PrinterInfo7(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo7 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterInfo7(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo7 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -2071,7 +2106,7 @@ static enum ndr_err_code ndr_push_spoolss_PrinterInfo7(struct ndr_push *ndr, int
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PrinterInfo7(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo7 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterInfo7(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo7 *r)
 {
        uint32_t _ptr_guid;
        TALLOC_CTX *_mem_save_guid_0;
@@ -2125,6 +2160,11 @@ _PUBLIC_ void ndr_print_spoolss_PrinterInfo7(struct ndr_print *ndr, const char *
        ndr->depth--;
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_PrinterInfo7(const struct spoolss_PrinterInfo7 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterInfo7, ic);
+}
+
 static enum ndr_err_code ndr_push_spoolss_DeviceModeInfo(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DeviceModeInfo *r)
 {
        if (ndr_flags & NDR_SCALARS) {
@@ -2490,6 +2530,11 @@ _PUBLIC_ void ndr_print_spoolss_PrinterInfo(struct ndr_print *ndr, const char *n
        }
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_PrinterInfo(const union spoolss_PrinterInfo *r, uint32_t level, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_union(r, flags, level, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterInfo, ic);
+}
+
 static enum ndr_err_code ndr_push_spoolss_DevmodeContainer(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DevmodeContainer *r)
 {
        if (ndr_flags & NDR_SCALARS) {
@@ -2554,7 +2599,7 @@ _PUBLIC_ void ndr_print_spoolss_DevmodeContainer(struct ndr_print *ndr, const ch
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_JobInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo1 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_JobInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo1 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -2661,7 +2706,7 @@ static enum ndr_err_code ndr_push_spoolss_JobInfo1(struct ndr_push *ndr, int ndr
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo1 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo1 *r)
 {
        uint32_t _ptr_printer_name;
        TALLOC_CTX *_mem_save_printer_name_0;
@@ -2902,7 +2947,12 @@ _PUBLIC_ void ndr_print_spoolss_JobInfo1(struct ndr_print *ndr, const char *name
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_JobInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo2 *r)
+_PUBLIC_ size_t ndr_size_spoolss_JobInfo1(const struct spoolss_JobInfo1 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_JobInfo1, ic);
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_JobInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo2 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -3083,7 +3133,7 @@ static enum ndr_err_code ndr_push_spoolss_JobInfo2(struct ndr_push *ndr, int ndr
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_JobInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo2 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_JobInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo2 *r)
 {
        uint32_t _ptr_printer_name;
        TALLOC_CTX *_mem_save_printer_name_0;
@@ -3522,7 +3572,12 @@ _PUBLIC_ void ndr_print_spoolss_JobInfo2(struct ndr_print *ndr, const char *name
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_JobInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo3 *r)
+_PUBLIC_ size_t ndr_size_spoolss_JobInfo2(const struct spoolss_JobInfo2 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_JobInfo2, ic);
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_JobInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo3 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -3535,7 +3590,7 @@ static enum ndr_err_code ndr_push_spoolss_JobInfo3(struct ndr_push *ndr, int ndr
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_JobInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo3 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_JobInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo3 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_pull_align(ndr, 4));
@@ -3558,7 +3613,12 @@ _PUBLIC_ void ndr_print_spoolss_JobInfo3(struct ndr_print *ndr, const char *name
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_JobInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo4 *r)
+_PUBLIC_ size_t ndr_size_spoolss_JobInfo3(const struct spoolss_JobInfo3 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_JobInfo3, ic);
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_JobInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo4 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -3740,7 +3800,7 @@ static enum ndr_err_code ndr_push_spoolss_JobInfo4(struct ndr_push *ndr, int ndr
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_JobInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo4 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_JobInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo4 *r)
 {
        uint32_t _ptr_printer_name;
        TALLOC_CTX *_mem_save_printer_name_0;
@@ -4181,6 +4241,11 @@ _PUBLIC_ void ndr_print_spoolss_JobInfo4(struct ndr_print *ndr, const char *name
        ndr->depth--;
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_JobInfo4(const struct spoolss_JobInfo4 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_JobInfo4, ic);
+}
+
 _PUBLIC_ enum ndr_err_code ndr_push_spoolss_JobInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_JobInfo *r)
 {
        uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);
@@ -4335,6 +4400,11 @@ _PUBLIC_ void ndr_print_spoolss_JobInfo(struct ndr_print *ndr, const char *name,
        }
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_JobInfo(const union spoolss_JobInfo *r, uint32_t level, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_union(r, flags, level, (ndr_push_flags_fn_t)ndr_push_spoolss_JobInfo, ic);
+}
+
 static enum ndr_err_code ndr_push_spoolss_SetJobInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_SetJobInfo1 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
@@ -13610,6 +13680,11 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo(struct ndr_print *ndr, const char *na
        }
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_DriverInfo(const union spoolss_DriverInfo *r, uint32_t level, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_union(r, flags, level, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo, ic);
+}
+
 _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverDirectoryInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverDirectoryInfo1 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
index c45b796b60b085ce9dc3120924a0b739acd17e58..b6418f59005314e0bd3af00002bbc487582b1071 100644 (file)
@@ -213,7 +213,10 @@ void ndr_print_spoolss_MajorVersion(struct ndr_print *ndr, const char *name, enu
 void ndr_print_spoolss_MinorVersion(struct ndr_print *ndr, const char *name, enum spoolss_MinorVersion r);
 void ndr_print_spoolss_PrinterStatus(struct ndr_print *ndr, const char *name, uint32_t r);
 void ndr_print_spoolss_JobStatus(struct ndr_print *ndr, const char *name, uint32_t r);
+enum ndr_err_code ndr_push_spoolss_PrinterInfo0(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo0 *r);
+enum ndr_err_code ndr_pull_spoolss_PrinterInfo0(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo0 *r);
 void ndr_print_spoolss_PrinterInfo0(struct ndr_print *ndr, const char *name, const struct spoolss_PrinterInfo0 *r);
+size_t ndr_size_spoolss_PrinterInfo0(const struct spoolss_PrinterInfo0 *r, struct smb_iconv_convenience *ic, int flags);
 void ndr_print_spoolss_DeviceModeFields(struct ndr_print *ndr, const char *name, uint32_t r);
 enum ndr_err_code ndr_push_spoolss_DeviceMode(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DeviceMode *r);
 enum ndr_err_code ndr_pull_spoolss_DeviceMode(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DeviceMode *r);
@@ -222,27 +225,62 @@ size_t ndr_size_spoolss_DeviceMode(const struct spoolss_DeviceMode *r, struct sm
 enum ndr_err_code ndr_push_spoolss_EnumPrinterFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r);
 enum ndr_err_code ndr_pull_spoolss_EnumPrinterFlags(struct ndr_pull *ndr, int ndr_flags, uint32_t *r);
 void ndr_print_spoolss_EnumPrinterFlags(struct ndr_print *ndr, const char *name, uint32_t r);
+enum ndr_err_code ndr_push_spoolss_PrinterInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo1 *r);
+enum ndr_err_code ndr_pull_spoolss_PrinterInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo1 *r);
 void ndr_print_spoolss_PrinterInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_PrinterInfo1 *r);
+size_t ndr_size_spoolss_PrinterInfo1(const struct spoolss_PrinterInfo1 *r, struct smb_iconv_convenience *ic, int flags);
 void ndr_print_spoolss_PrinterAttributes(struct ndr_print *ndr, const char *name, uint32_t r);
+enum ndr_err_code ndr_push_spoolss_PrinterInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo2 *r);
+enum ndr_err_code ndr_pull_spoolss_PrinterInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo2 *r);
 void ndr_print_spoolss_PrinterInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_PrinterInfo2 *r);
+size_t ndr_size_spoolss_PrinterInfo2(const struct spoolss_PrinterInfo2 *r, struct smb_iconv_convenience *ic, int flags);
+enum ndr_err_code ndr_push_spoolss_PrinterInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo3 *r);
+enum ndr_err_code ndr_pull_spoolss_PrinterInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo3 *r);
 void ndr_print_spoolss_PrinterInfo3(struct ndr_print *ndr, const char *name, const struct spoolss_PrinterInfo3 *r);
+size_t ndr_size_spoolss_PrinterInfo3(const struct spoolss_PrinterInfo3 *r, struct smb_iconv_convenience *ic, int flags);
+enum ndr_err_code ndr_push_spoolss_PrinterInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo4 *r);
+enum ndr_err_code ndr_pull_spoolss_PrinterInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo4 *r);
 void ndr_print_spoolss_PrinterInfo4(struct ndr_print *ndr, const char *name, const struct spoolss_PrinterInfo4 *r);
+size_t ndr_size_spoolss_PrinterInfo4(const struct spoolss_PrinterInfo4 *r, struct smb_iconv_convenience *ic, int flags);
+enum ndr_err_code ndr_push_spoolss_PrinterInfo5(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo5 *r);
+enum ndr_err_code ndr_pull_spoolss_PrinterInfo5(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo5 *r);
 void ndr_print_spoolss_PrinterInfo5(struct ndr_print *ndr, const char *name, const struct spoolss_PrinterInfo5 *r);
+size_t ndr_size_spoolss_PrinterInfo5(const struct spoolss_PrinterInfo5 *r, struct smb_iconv_convenience *ic, int flags);
+enum ndr_err_code ndr_push_spoolss_PrinterInfo6(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo6 *r);
+enum ndr_err_code ndr_pull_spoolss_PrinterInfo6(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo6 *r);
 void ndr_print_spoolss_PrinterInfo6(struct ndr_print *ndr, const char *name, const struct spoolss_PrinterInfo6 *r);
+size_t ndr_size_spoolss_PrinterInfo6(const struct spoolss_PrinterInfo6 *r, struct smb_iconv_convenience *ic, int flags);
 void ndr_print_spoolss_DsPrintAction(struct ndr_print *ndr, const char *name, uint32_t r);
+enum ndr_err_code ndr_push_spoolss_PrinterInfo7(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo7 *r);
+enum ndr_err_code ndr_pull_spoolss_PrinterInfo7(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterInfo7 *r);
 void ndr_print_spoolss_PrinterInfo7(struct ndr_print *ndr, const char *name, const struct spoolss_PrinterInfo7 *r);
+size_t ndr_size_spoolss_PrinterInfo7(const struct spoolss_PrinterInfo7 *r, struct smb_iconv_convenience *ic, int flags);
 void ndr_print_spoolss_DeviceModeInfo(struct ndr_print *ndr, const char *name, const struct spoolss_DeviceModeInfo *r);
 enum ndr_err_code ndr_push_spoolss_PrinterInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_PrinterInfo *r);
 enum ndr_err_code ndr_pull_spoolss_PrinterInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_PrinterInfo *r);
 void ndr_print_spoolss_PrinterInfo(struct ndr_print *ndr, const char *name, const union spoolss_PrinterInfo *r);
+size_t ndr_size_spoolss_PrinterInfo(const union spoolss_PrinterInfo *r, uint32_t level, struct smb_iconv_convenience *ic, int flags);
 void ndr_print_spoolss_DevmodeContainer(struct ndr_print *ndr, const char *name, const struct spoolss_DevmodeContainer *r);
+enum ndr_err_code ndr_push_spoolss_JobInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo1 *r);
+enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo1 *r);
 void ndr_print_spoolss_JobInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo1 *r);
+size_t ndr_size_spoolss_JobInfo1(const struct spoolss_JobInfo1 *r, struct smb_iconv_convenience *ic, int flags);
+enum ndr_err_code ndr_push_spoolss_JobInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo2 *r);
+enum ndr_err_code ndr_pull_spoolss_JobInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo2 *r);
 void ndr_print_spoolss_JobInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo2 *r);
+size_t ndr_size_spoolss_JobInfo2(const struct spoolss_JobInfo2 *r, struct smb_iconv_convenience *ic, int flags);
+enum ndr_err_code ndr_push_spoolss_JobInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo3 *r);
+enum ndr_err_code ndr_pull_spoolss_JobInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo3 *r);
 void ndr_print_spoolss_JobInfo3(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo3 *r);
+size_t ndr_size_spoolss_JobInfo3(const struct spoolss_JobInfo3 *r, struct smb_iconv_convenience *ic, int flags);
+enum ndr_err_code ndr_push_spoolss_JobInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo4 *r);
+enum ndr_err_code ndr_pull_spoolss_JobInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo4 *r);
 void ndr_print_spoolss_JobInfo4(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo4 *r);
+size_t ndr_size_spoolss_JobInfo4(const struct spoolss_JobInfo4 *r, struct smb_iconv_convenience *ic, int flags);
 enum ndr_err_code ndr_push_spoolss_JobInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_JobInfo *r);
 enum ndr_err_code ndr_pull_spoolss_JobInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_JobInfo *r);
 void ndr_print_spoolss_JobInfo(struct ndr_print *ndr, const char *name, const union spoolss_JobInfo *r);
+size_t ndr_size_spoolss_JobInfo(const union spoolss_JobInfo *r, uint32_t level, struct smb_iconv_convenience *ic, int flags);
 void ndr_print_spoolss_SetJobInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_SetJobInfo1 *r);
 void ndr_print_spoolss_SetJobInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_SetJobInfo2 *r);
 void ndr_print_spoolss_SetJobInfo4(struct ndr_print *ndr, const char *name, const struct spoolss_SetJobInfo4 *r);
@@ -315,6 +353,7 @@ size_t ndr_size_spoolss_DriverInfo101(const struct spoolss_DriverInfo101 *r, str
 enum ndr_err_code ndr_push_spoolss_DriverInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_DriverInfo *r);
 enum ndr_err_code ndr_pull_spoolss_DriverInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_DriverInfo *r);
 void ndr_print_spoolss_DriverInfo(struct ndr_print *ndr, const char *name, const union spoolss_DriverInfo *r);
+size_t ndr_size_spoolss_DriverInfo(const union spoolss_DriverInfo *r, uint32_t level, struct smb_iconv_convenience *ic, int flags);
 enum ndr_err_code ndr_push_spoolss_DriverDirectoryInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverDirectoryInfo1 *r);
 enum ndr_err_code ndr_pull_spoolss_DriverDirectoryInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverDirectoryInfo1 *r);
 void ndr_print_spoolss_DriverDirectoryInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_DriverDirectoryInfo1 *r);
index 83a582efb214e1a586877ff070264a73c8c73a67..77fb03ac898aee39dfb6dbfb6165934caa34806c 100644 (file)
@@ -193,7 +193,7 @@ struct spoolss_PrinterInfo0 {
        uint32_t ref_ic;
        uint32_t reserved2;
        uint32_t reserved3;
-};
+}/* [gensize,public] */;
 
 /* bitmap spoolss_DeviceModeFields */
 #define DEVMODE_ORIENTATION ( 0x00000001 )
@@ -289,7 +289,7 @@ struct spoolss_PrinterInfo1 {
        const char * name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        const char * description;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        const char * comment;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
-};
+}/* [gensize,public] */;
 
 /* bitmap spoolss_PrinterAttributes */
 #define PRINTER_ATTRIBUTE_QUEUED ( 0x00000001 )
@@ -331,17 +331,17 @@ struct spoolss_PrinterInfo2 {
        uint32_t status;
        uint32_t cjobs;
        uint32_t averageppm;
-};
+}/* [gensize,public] */;
 
 struct spoolss_PrinterInfo3 {
        struct security_descriptor *secdesc;/* [relative,subcontext(0)] */
-};
+}/* [gensize,public] */;
 
 struct spoolss_PrinterInfo4 {
        const char * printername;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        const char * servername;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        uint32_t attributes;
-};
+}/* [gensize,public] */;
 
 struct spoolss_PrinterInfo5 {
        const char * printername;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
@@ -349,11 +349,11 @@ struct spoolss_PrinterInfo5 {
        uint32_t attributes;
        uint32_t device_not_selected_timeout;
        uint32_t transmission_retry_timeout;
-};
+}/* [gensize,public] */;
 
 struct spoolss_PrinterInfo6 {
        uint32_t status;
-};
+}/* [gensize,public] */;
 
 /* bitmap spoolss_DsPrintAction */
 #define DSPRINT_PUBLISH ( 0x00000001 )
@@ -365,7 +365,7 @@ struct spoolss_PrinterInfo6 {
 struct spoolss_PrinterInfo7 {
        const char * guid;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        uint32_t action;
-};
+}/* [gensize,public] */;
 
 struct spoolss_DeviceModeInfo {
        struct spoolss_DeviceMode *devmode;/* [relative,subcontext(0)] */
@@ -382,7 +382,7 @@ union spoolss_PrinterInfo {
        struct spoolss_PrinterInfo7 info7;/* [case(7)] */
        struct spoolss_DeviceModeInfo info8;/* [case(8)] */
        struct spoolss_DeviceModeInfo info9;/* [case(9)] */
-}/* [relative_base,nodiscriminant,public] */;
+}/* [relative_base,gensize,public,nodiscriminant] */;
 
 struct spoolss_DevmodeContainer {
        uint32_t _ndr_size;/* [value(_ndr_size_spoolss_DeviceMode(devmode,ndr->iconv_convenience,ndr->flags))] */
@@ -403,7 +403,7 @@ struct spoolss_JobInfo1 {
        uint32_t total_pages;
        uint32_t pages_printed;
        struct spoolss_Time submitted;
-};
+}/* [gensize,public] */;
 
 struct spoolss_JobInfo2 {
        uint32_t job_id;
@@ -429,13 +429,13 @@ struct spoolss_JobInfo2 {
        struct spoolss_Time submitted;
        uint32_t time;
        uint32_t pages_printed;
-};
+}/* [gensize,public] */;
 
 struct spoolss_JobInfo3 {
        uint32_t job_id;
        uint32_t next_job_id;
        uint32_t reserved;
-};
+}/* [gensize,public] */;
 
 struct spoolss_JobInfo4 {
        uint32_t job_id;
@@ -462,14 +462,14 @@ struct spoolss_JobInfo4 {
        uint32_t time;
        uint32_t pages_printed;
        uint32_t size_high;
-};
+}/* [gensize,public] */;
 
 union spoolss_JobInfo {
        struct spoolss_JobInfo1 info1;/* [case] */
        struct spoolss_JobInfo2 info2;/* [case(2)] */
        struct spoolss_JobInfo3 info3;/* [case(3)] */
        struct spoolss_JobInfo4 info4;/* [case(4)] */
-}/* [relative_base,nodiscriminant,public] */;
+}/* [relative_base,gensize,public,nodiscriminant] */;
 
 struct spoolss_SetJobInfo1 {
        uint32_t job_id;
@@ -1002,7 +1002,7 @@ union spoolss_DriverInfo {
        struct spoolss_DriverInfo6 info6;/* [case(6)] */
        struct spoolss_DriverInfo8 info8;/* [case(8)] */
        struct spoolss_DriverInfo101 info101;/* [case(101)] */
-}/* [relative_base,nodiscriminant,public] */;
+}/* [relative_base,gensize,public,nodiscriminant] */;
 
 struct spoolss_DriverDirectoryInfo1 {
        const char * directory_name;/* [flag(LIBNDR_FLAG_STR_NULLTERM)] */
index 9765fd3969b6dc9ddcb0c484230144eb54b69ea3..f837afbd5d353f707d84c618907dc842af7df3b0 100644 (file)
@@ -116,7 +116,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                JOB_STATUS_COMPLETE             = 0x00001000
        } spoolss_JobStatus;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                [relative] nstring *printername;
                [relative] nstring *servername;
                uint32 cjobs;
@@ -248,7 +248,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                                           PRINTER_ENUM_ICON7 |
                                           PRINTER_ENUM_ICON8); /* 0x00ff0000 */
 
-       typedef struct {
+       typedef [public,gensize] struct {
                spoolss_EnumPrinterFlags flags;
                [relative] nstring *name;
                [relative] nstring *description;
@@ -274,7 +274,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                PRINTER_ATTRIBUTE_TS                    = 0x00008000
        } spoolss_PrinterAttributes;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                [relative] nstring *servername;
                [relative] nstring *printername;
                [relative] nstring *sharename;
@@ -298,17 +298,17 @@ import "misc.idl", "security.idl", "winreg.idl";
                uint32 averageppm;
        } spoolss_PrinterInfo2;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                [relative,subcontext(0)] security_descriptor *secdesc;
        } spoolss_PrinterInfo3;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                [relative] nstring *printername;
                [relative] nstring *servername;
                spoolss_PrinterAttributes attributes;
        } spoolss_PrinterInfo4;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                [relative] nstring *printername;
                [relative] nstring *portname;
                spoolss_PrinterAttributes attributes;
@@ -316,7 +316,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                uint32 transmission_retry_timeout;
        } spoolss_PrinterInfo5;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                spoolss_PrinterStatus status;
        } spoolss_PrinterInfo6;
 
@@ -328,7 +328,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                DSPRINT_PENDING         = 0x80000000
        } spoolss_DsPrintAction;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                [relative] nstring *guid; /* text form of printer guid */
                spoolss_DsPrintAction action;
        } spoolss_PrinterInfo7;
@@ -337,7 +337,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [relative,subcontext(0)] spoolss_DeviceMode *devmode;
        } spoolss_DeviceModeInfo;
 
-       typedef [nodiscriminant,relative_base,public] union {
+       typedef [nodiscriminant,relative_base,public,gensize] union {
                [case(0)] spoolss_PrinterInfo0 info0;
                [case(1)] spoolss_PrinterInfo1 info1;
                [case(2)] spoolss_PrinterInfo2 info2;
@@ -401,7 +401,7 @@ import "misc.idl", "security.idl", "winreg.idl";
        /******************/
        /* Function: 0x02 */
 
-       typedef struct {
+       typedef [public,gensize] struct {
                uint32 job_id;
                [relative] nstring *printer_name;
                [relative] nstring *server_name;
@@ -417,7 +417,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                spoolss_Time submitted;
        } spoolss_JobInfo1;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                uint32 job_id;
                [relative] nstring *printer_name;
                [relative] nstring *server_name;
@@ -443,13 +443,13 @@ import "misc.idl", "security.idl", "winreg.idl";
                uint32 pages_printed;
        } spoolss_JobInfo2;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                uint32 job_id;
                uint32 next_job_id;
                uint32 reserved;
        } spoolss_JobInfo3;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                uint32 job_id;
                [relative] nstring *printer_name;
                [relative] nstring *server_name;
@@ -476,7 +476,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                uint32 size_high;
        } spoolss_JobInfo4;
 
-       typedef [nodiscriminant,relative_base,public] union {
+       typedef [nodiscriminant,relative_base,public,gensize] union {
                [case(1)] spoolss_JobInfo1 info1;
                [case(2)] spoolss_JobInfo2 info2;
                [case(3)] spoolss_JobInfo3 info3;
@@ -1052,7 +1052,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [relative] nstring *provider;
        } spoolss_DriverInfo101;
 
-       typedef [nodiscriminant,relative_base,public] union {
+       typedef [nodiscriminant,relative_base,public,gensize] union {
                [case(1)] spoolss_DriverInfo1 info1;
                [case(2)] spoolss_DriverInfo2 info2;
                [case(3)] spoolss_DriverInfo3 info3;
index 8fa018b1126825d09b5708278df7c3d279916fe8..351dbf701622040b227cd0d2bc1f4a0ac1a12ee1 100644 (file)
@@ -250,7 +250,7 @@ enum ndr_err_code ndr_pull_spoolss_EnumJobs(struct ndr_pull *ndr, int flags, str
        return NDR_ERR_SUCCESS;
 }
 
-uint32_t ndr_size_spoolss_EnumJobss_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, uint32_t level, uint32_t count, union spoolss_JobInfo *info)
+uint32_t ndr_size_spoolss_EnumJobs_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, uint32_t level, uint32_t count, union spoolss_JobInfo *info)
 {
        NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumJobs);
 }
@@ -398,8 +398,8 @@ enum ndr_err_code ndr_pull_spoolss_EnumPrintProcessors(struct ndr_pull *ndr, int
        return NDR_ERR_SUCCESS;
 }
 
-uint32_t ndr_size_spoolss_EnumPrinterProcessors_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience,
-                                                                                                        uint32_t level, uint32_t count, union spoolss_PrintProcessorInfo *info)
+uint32_t ndr_size_spoolss_EnumPrintProcessors_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience,
+                                                  uint32_t level, uint32_t count, union spoolss_PrintProcessorInfo *info)
 {
        NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPrintProcessors);
 }
index 352a14b731cdfd686e87c412456bb9d37a5d24d0..04a84bfb628d4433b8fe3d2df16e270c0a4c739e 100644 (file)
@@ -17,7 +17,7 @@ enum ndr_err_code ndr_pull_spoolss_EnumPrinters(struct ndr_pull *ndr, int flags,
 uint32_t ndr_size_spoolss_EnumPrinters_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, uint32_t level, uint32_t count, union spoolss_PrinterInfo *info);
 enum ndr_err_code ndr_push_spoolss_EnumJobs(struct ndr_push *ndr, int flags, const struct spoolss_EnumJobs *r);
 enum ndr_err_code ndr_pull_spoolss_EnumJobs(struct ndr_pull *ndr, int flags, struct spoolss_EnumJobs *r);
-uint32_t ndr_size_spoolss_EnumJobss_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, uint32_t level, uint32_t count, union spoolss_JobInfo *info);
+uint32_t ndr_size_spoolss_EnumJobs_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, uint32_t level, uint32_t count, union spoolss_JobInfo *info);
 enum ndr_err_code ndr_push_spoolss_EnumPrinterDrivers(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrinterDrivers *r);
 enum ndr_err_code ndr_pull_spoolss_EnumPrinterDrivers(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinterDrivers *r);
 uint32_t ndr_size_spoolss_EnumPrinterDrivers_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, uint32_t level, uint32_t count, union spoolss_DriverInfo *info);
@@ -32,8 +32,8 @@ enum ndr_err_code ndr_pull_spoolss_EnumMonitors(struct ndr_pull *ndr, int flags,
 uint32_t ndr_size_spoolss_EnumMonitors_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, uint32_t level, uint32_t count, union spoolss_MonitorInfo *info);
 enum ndr_err_code ndr_push_spoolss_EnumPrintProcessors(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrintProcessors *r);
 enum ndr_err_code ndr_pull_spoolss_EnumPrintProcessors(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrintProcessors *r);
-uint32_t ndr_size_spoolss_EnumPrinterProcessors_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience,
-                                                                                                uint32_t level, uint32_t count, union spoolss_PrintProcessorInfo *info);
+uint32_t ndr_size_spoolss_EnumPrintProcessors_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience,
+                                                  uint32_t level, uint32_t count, union spoolss_PrintProcessorInfo *info);
 enum ndr_err_code ndr_push_spoolss_EnumPrintProcDataTypes(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrintProcDataTypes *r);
 enum ndr_err_code ndr_pull_spoolss_EnumPrintProcDataTypes(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrintProcDataTypes *r);
 uint32_t ndr_size_spoolss_EnumPrintProcDataTypes_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience,
diff --git a/m4/pkg.m4 b/m4/pkg.m4
new file mode 100644 (file)
index 0000000..a8b3d06
--- /dev/null
+++ b/m4/pkg.m4
@@ -0,0 +1,156 @@
+# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-
+# 
+# Copyright Â© 2004 Scott James Remnant <scott@netsplit.com>.
+#
+# 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/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+       AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+       _pkg_min_version=m4_default([$1], [0.9.0])
+       AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+       if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+               AC_MSG_RESULT([yes])
+       else
+               AC_MSG_RESULT([no])
+               PKG_CONFIG=""
+       fi
+               
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists.  Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+#
+# Similar to PKG_CHECK_MODULES, make sure that the first instance of
+# this or PKG_CHECK_MODULES is called, or make sure to call
+# PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+  m4_ifval([$2], [$2], [:])
+m4_ifvaln([$3], [else
+  $3])dnl
+fi])
+
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$PKG_CONFIG"; then
+    if test -n "$$1"; then
+        pkg_cv_[]$1="$$1"
+    else
+        PKG_CHECK_EXISTS([$3],
+                         [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+                        [pkg_failed=yes])
+    fi
+else
+       pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+        _PKG_SHORT_ERRORS_SUPPORTED
+        if test $_pkg_short_errors_supported = yes; then
+               $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
+        else 
+               $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+       ifelse([$4], , [AC_MSG_ERROR(dnl
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT
+])],
+               [AC_MSG_RESULT([no])
+                $4])
+elif test $pkg_failed = untried; then
+       ifelse([$4], , [AC_MSG_FAILURE(dnl
+[The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])],
+               [$4])
+else
+       $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+       $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+        AC_MSG_RESULT([yes])
+       ifelse([$3], , :, [$3])
+fi[]dnl
+])# PKG_CHECK_MODULES
index 568dff5adf541a54b05b29270b12f1e32ea2db91..a6b74a0ba45d0d51265ae832d7ca9d82113ea577 100644 (file)
@@ -271,7 +271,7 @@ sub Parser($$$$)
        $self->pidl("");
        $self->pidl_hdr("/* autogenerated by pidl */");
        $self->pidl_hdr("#include \"$baseheader\"");
-       $self->pidl_hdr(choose_header("tdr/tdr.h", "tdr.h"));
+       $self->pidl_hdr(choose_header("lib/tdr/tdr.h", "tdr.h"));
        $self->pidl_hdr("");
 
        foreach (@$idl) { $self->ParserInterface($_) if ($_->{TYPE} eq "INTERFACE"); }  
index 6aabcf0c8d215ded7559fa0dc52627f12da3290d..f69c39b6e46af06f7fcf9352e58e7ed2384ccb92 100644 (file)
@@ -88,12 +88,11 @@ UNINSTALLLIBCMD_A=@UNINSTALLLIBCMD_A@
 VPATH=@srcdir@
 srcdir=@abs_srcdir@
 builddir=@abs_builddir@
-SHELL=/bin/sh
-DESTDIR=/
-
 # XXX: Perhaps this should be @SHELL@ instead -- apparently autoconf
 # will search for a POSIX-compliant shell, and that might not be
 # /bin/sh on some platforms.  I guess it's not a big problem -- mbp
+SHELL=/bin/sh
+DESTDIR=/
 
 # See the autoconf manual "Installation Directory Variables" for a
 # discussion of the subtle use of these variables.
@@ -457,7 +456,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
             libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \
             libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \
             libsmb/clistr.o libsmb/cliquota.o libsmb/clifsinfo.o libsmb/clidfs.o \
-             libsmb/credentials.o libsmb/pwd_cache.o \
+             libsmb/credentials.o \
             libsmb/clioplock.o libsmb/clirap2.o \
             libsmb/smb_seal.o libsmb/async_smb.o \
             $(LIBSAMBA_OBJ) \
@@ -667,6 +666,7 @@ VFS_READAHEAD_OBJ = modules/vfs_readahead.o
 VFS_TSMSM_OBJ = modules/vfs_tsmsm.o
 VFS_FILEID_OBJ = modules/vfs_fileid.o
 VFS_AIO_FORK_OBJ = modules/vfs_aio_fork.o
+VFS_PREOPEN_OBJ = modules/vfs_preopen.o
 VFS_SYNCOPS_OBJ = modules/vfs_syncops.o
 VFS_ACL_XATTR_OBJ = modules/vfs_acl_xattr.o
 VFS_ACL_TDB_OBJ = modules/vfs_acl_tdb.o
@@ -2567,6 +2567,10 @@ bin/aio_fork.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_AIO_FORK_OBJ)
        @echo "Building plugin $@"
        @$(SHLD_MODULE) $(VFS_AIO_FORK_OBJ)
 
+bin/preopen.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_PREOPEN_OBJ)
+       @echo "Building plugin $@"
+       @$(SHLD_MODULE) $(VFS_PREOPEN_OBJ)
+
 bin/acl_xattr.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ACL_XATTR_OBJ)
        @echo "Building plugin $@"
        @$(SHLD_MODULE) $(VFS_ACL_XATTR_OBJ)
index 1a33eb22cc467b823ef807e1b474825102f0cf64..9ade370cd4d1463680373923f6e12d6aee5d1624 100755 (executable)
@@ -65,7 +65,7 @@ echo "$0: running script/mkversion.sh"
 rm -rf autom4te*.cache
 rm -f configure include/config.h*
 
-IPATHS="-Im4 -I../lib/replace -I../source4"
+IPATHS="-Im4 -I../m4 -I../lib/replace -I../source4"
 
 echo "$0: running $AUTOHEADER $IPATHS"
 $AUTOHEADER $IPATHS || exit 1
index 67a2458a94c860a9f146541e0ea55b756bbf52d3..6491f39ed0d1e3a243986720e852d9f297e8df27 100644 (file)
@@ -220,9 +220,7 @@ struct push_state {
        SMB_OFF_T nread;
 };
 
-static size_t push_source(uint8_t *inbuf, size_t n,
-                         const uint8_t **outbuf,
-                         void *priv)
+static size_t push_source(uint8_t *buf, size_t n, void *priv)
 {
        struct push_state *state = (struct push_state *)priv;
        int result;
@@ -231,7 +229,7 @@ static size_t push_source(uint8_t *inbuf, size_t n,
                return 0;
        }
 
-       result = readfile(inbuf, n, state->f);
+       result = readfile(buf, n, state->f);
        state->nread += result;
        return result;
 }
@@ -1421,7 +1419,7 @@ static bool do_altname(const char *name)
 
 static int cmd_quit(void)
 {
-       cli_cm_shutdown();
+       cli_shutdown(cli);
        exit(0);
        /* NOTREACHED */
        return 0;
@@ -1683,8 +1681,8 @@ static int do_put(const char *rname, const char *lname, bool reput)
        state.f = f;
        state.nread = 0;
 
-       status = cli_push(targetcli, fnum, 0, 0, io_bufsize,
-                         false, push_source, &state);
+       status = cli_push(targetcli, fnum, 0, 0, io_bufsize, push_source,
+                         &state);
        if (!NT_STATUS_IS_OK(status)) {
                d_fprintf(stderr, "cli_push returned %s\n", nt_errstr(status));
        }
@@ -1716,7 +1714,7 @@ static int do_put(const char *rname, const char *lname, bool reput)
        }
 
        if (f == x_stdin) {
-               cli_cm_shutdown();
+               cli_shutdown(cli);
                exit(0);
        }
 
@@ -3817,7 +3815,7 @@ static int cmd_logon(void)
 
 static int cmd_list_connect(void)
 {
-       cli_cm_display();
+       cli_cm_display(cli);
        return 0;
 }
 
@@ -4528,7 +4526,7 @@ static int process(const char *base_directory)
        if (base_directory && *base_directory) {
                rc = do_cd(base_directory);
                if (rc) {
-                       cli_cm_shutdown();
+                       cli_shutdown(cli);
                        return rc;
                }
        }
@@ -4539,7 +4537,7 @@ static int process(const char *base_directory)
                process_stdin();
        }
 
-       cli_cm_shutdown();
+       cli_shutdown(cli);
        return rc;
 }
 
@@ -4570,7 +4568,7 @@ static int do_host_query(const char *query_host)
                /* Workgroups simply don't make sense over anything
                   else but port 139... */
 
-               cli_cm_shutdown();
+               cli_shutdown(cli);
                cli = cli_cm_open(talloc_tos(), NULL,
                                query_host, "IPC$", true, smb_encrypt,
                                max_protocol, 139, name_type);
@@ -4583,7 +4581,7 @@ static int do_host_query(const char *query_host)
 
        list_servers(lp_workgroup());
 
-       cli_cm_shutdown();
+       cli_shutdown(cli);
 
        return(0);
 }
@@ -4611,14 +4609,14 @@ static int do_tar_op(const char *base_directory)
        if (base_directory && *base_directory)  {
                ret = do_cd(base_directory);
                if (ret) {
-                       cli_cm_shutdown();
+                       cli_shutdown(cli);
                        return ret;
                }
        }
 
        ret=process_tar();
 
-       cli_cm_shutdown();
+       cli_shutdown(cli);
 
        return(ret);
 }
@@ -4665,12 +4663,12 @@ static int do_message_op(struct user_auth_info *auth_info)
 
        if (!cli_session_request(cli, &calling, &called)) {
                d_printf("session request failed\n");
-               cli_cm_shutdown();
+               cli_shutdown(cli);
                return 1;
        }
 
        send_message(get_cmdline_auth_info_username(auth_info));
-       cli_cm_shutdown();
+       cli_shutdown(cli);
 
        return 0;
 }
index 8623d3c04b537d3022f23b62e2da3aaca40f29ef..0c551cce7556932f6e00f9c48299697fb7563cd6 100644 (file)
@@ -1463,7 +1463,8 @@ mount_retry:
                        }
                }
                printf("mount error(%d): %s\n", errno, strerror(errno));
-               printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n");
+               printf("Refer to the mount.cifs(8) manual page (e.g. man "
+                      "mount.cifs)\n");
                rc = EX_FAIL;
                goto mount_exit;
        }
index e48ff345540782ffe2dc9201757ca4b2ed4c335d..98f41d61e547158047f55d063369e544ffc541dc 100644 (file)
@@ -20,10 +20,29 @@ AC_SUBST(builddir)
 
 m4_include(m4/samba_version.m4)
 m4_include(m4/check_path.m4)
+m4_include(pkg.m4)
 
 AC_LIBREPLACE_CC_CHECKS
 
-m4_include(../lib/talloc/libtalloc.m4)
+AC_ARG_ENABLE(external_libtalloc, [AS_HELP_STRING([--enable-external-libtalloc], [Enable external talloc [default=auto]])], 
+[ enable_external_libtalloc=$enableval ], [ enable_external_libtalloc=auto ])
+
+if test "x$enable_external_libtalloc" != xno
+then
+       PKG_CHECK_MODULES(TALLOC, talloc >= 1.3.0, 
+               [ enable_external_libtalloc=yes ],
+               [ if x$enable_external_libtalloc = xyes; then 
+                       AC_MSG_ERROR([Unable to find libtalloc])
+             else 
+                       enable_external_libtalloc=no
+                 fi
+               ])
+fi
+
+if test "x$enable_external_libtalloc" = xno
+then
+       m4_include(../lib/talloc/libtalloc.m4)
+fi
 
 LIBTALLOC_OBJ0=""
 for obj in ${TALLOC_OBJ}; do
@@ -417,7 +436,7 @@ dnl These have to be built static:
 default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_wbc_sam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss2 rpc_eventlog auth_sam auth_unix auth_winbind auth_wbc auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template"
 
 dnl These are preferably build shared, and static if dlopen() is not available
-default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer"
+default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer vfs_preopen"
 
 if test "x$developer" = xyes; then
    default_static_modules="$default_static_modules rpc_rpcecho"
@@ -1177,13 +1196,10 @@ if test x"$LIBUNWIND_PTRACE" != x"" ; then
 #endif
            ],
            [
-               int main(int argc, const char ** argv)
-               {
-                       pid_t me = (pid_t)-1;
-                       ptrace(PTRACE_ATTACH, me, 0, 0);
-                       ptrace(PTRACE_DETACH, me, 0, 0);
-                       return 0;
-               }
+               pid_t me = (pid_t)-1;
+               ptrace(PTRACE_ATTACH, me, 0, 0);
+               ptrace(PTRACE_DETACH, me, 0, 0);
+               return 0;
            ],
            [
                AC_MSG_RESULT(yes)
@@ -6185,6 +6201,7 @@ SMB_MODULE(vfs_readahead, \$(VFS_READAHEAD_OBJ), "bin/readahead.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_tsmsm, \$(VFS_TSMSM_OBJ), "bin/tsmsm.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_fileid, \$(VFS_FILEID_OBJ), "bin/fileid.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_aio_fork, \$(VFS_AIO_FORK_OBJ), "bin/aio_fork.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_preopen, \$(VFS_PREOPEN_OBJ), "bin/preopen.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_syncops, \$(VFS_SYNCOPS_OBJ), "bin/syncops.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_zfsacl, \$(VFS_ZFSACL_OBJ), "bin/zfsacl.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_notify_fam, \$(VFS_NOTIFY_FAM_OBJ), "bin/notify_fam.$SHLIBEXT", VFS)
index 646d54aa05d979eb9d9e5fb07a94606d5fc98d63..320a90e66bf2c44861e095cdb4e17f7ba6d642fe 100644 (file)
@@ -167,6 +167,10 @@ struct smb_trans_enc_state {
 };
 
 struct cli_state {
+       /**
+        * A list of subsidiary connections for DFS.
+        */
+        struct cli_state *prev, *next;
        int port;
        int fd;
        /* Last read or write error. */
@@ -183,9 +187,9 @@ struct cli_state {
        fstring desthost;
 
        /* The credentials used to open the cli_state connection. */
-       fstring domain;
-       fstring user_name;
-       struct pwd_info pwd;
+       char *domain;
+       char *user_name;
+       char *password; /* Can be null to force use of zero NTLMSSP session key. */
 
        /*
         * The following strings are the
@@ -276,6 +280,9 @@ struct cli_state {
         * chained async_req.
         */
        struct cli_request *chain_accumulator;
+
+       /* Where (if anywhere) this is mounted under DFS. */
+       char *dfs_mountpoint;
 };
 
 typedef struct file_info {
index 794a006a687a6d839c0cde79d1d01ffe44c6b245..f992f0686a910c6fc1cdb22346e8ba1d79159896 100644 (file)
@@ -2355,7 +2355,6 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c,
                        const char *password,
                        const char *domain,
                        const char *sharename);
-const char *cli_cm_get_mntpoint(struct cli_state *c);
 struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
                                struct cli_state *referring_cli,
                                const char *server,
@@ -2365,8 +2364,7 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
                                int max_protocol,
                                int port,
                                int name_type);
-void cli_cm_shutdown(void);
-void cli_cm_display(void);
+void cli_cm_display(const struct cli_state *c);
 void cli_cm_set_credentials(struct user_auth_info *auth_info);
 void cli_cm_set_port(int port_number);
 void cli_cm_set_dest_name_type(int type);
@@ -2426,7 +2424,10 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli,
 void cli_setup_packet_buf(struct cli_state *cli, char *buf);
 void cli_setup_packet(struct cli_state *cli);
 void cli_setup_bcc(struct cli_state *cli, void *p);
-void cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password);
+NTSTATUS cli_set_domain(struct cli_state *cli, const char *domain);
+NTSTATUS cli_set_username(struct cli_state *cli, const char *username);
+NTSTATUS cli_set_password(struct cli_state *cli, const char *password);
+NTSTATUS cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password);
 struct cli_state *cli_initialise(void);
 struct cli_state *cli_initialise_ex(int signing_state);
 void cli_nt_pipes_close(struct cli_state *cli);
@@ -2790,18 +2791,13 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
                                struct cli_state *cli,
                                uint16_t fnum, uint16_t mode,
                                off_t start_offset, size_t window_size,
-                               bool caller_buffers,
-                               size_t (*source)(uint8_t *inbuf, size_t n,
-                                                const uint8_t **outbuf,
+                               size_t (*source)(uint8_t *buf, size_t n,
                                                 void *priv),
                                void *priv);
 NTSTATUS cli_push_recv(struct async_req *req);
 NTSTATUS cli_push(struct cli_state *cli, uint16_t fnum, uint16_t mode,
                  off_t start_offset, size_t window_size,
-                 bool caller_buffers,
-                 size_t (*source)(uint8_t *inbuf, size_t n,
-                                  const uint8_t **outbuf,
-                                  void *priv),
+                 size_t (*source)(uint8_t *buf, size_t n, void *priv),
                  void *priv);
 
 /* The following definitions come from libsmb/clisecdesc.c  */
@@ -3161,11 +3157,6 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
                                const char *old_passwd, const char *new_passwd,
                                char **err_str);
 
-/* The following definitions come from libsmb/pwd_cache.c  */
-
-void pwd_set_cleartext(struct pwd_info *pwd, const char *clr);
-void pwd_get_cleartext(struct pwd_info *pwd, fstring clr);
-
 /* The following definitions come from libsmb/samlogon_cache.c  */
 
 bool netsamlogon_cache_init(void);
@@ -3416,11 +3407,16 @@ void brl_register_msgs(struct messaging_context *msg_ctx);
 
 const char *lock_type_name(enum brl_type lock_type);
 const char *lock_flav_name(enum brl_flavour lock_flav);
-bool is_locked(files_struct *fsp,
-               uint32 smbpid,
-               uint64_t count,
-               uint64_t offset, 
-               enum brl_type lock_type);
+void init_strict_lock_struct(files_struct *fsp,
+                               uint32 smbpid,
+                               br_off start,
+                               br_off size,
+                               enum brl_type lock_type,
+                               struct lock_struct *plock);
+bool strict_lock_default(files_struct *fsp,
+                               struct lock_struct *plock);
+void strict_unlock_default(files_struct *fsp,
+                               struct lock_struct *plock);
 NTSTATUS query_lock(files_struct *fsp,
                        uint32 *psmbpid,
                        uint64_t *pcount,
@@ -4933,7 +4929,7 @@ bool print_job_resume(struct auth_serversupplied_info *server_info, int snum,
 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size);
 int print_queue_length(int snum, print_status_struct *pstatus);
 uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum,
-                      char *jobname, NT_DEVICEMODE *nt_devmode );
+                      const char *jobname, NT_DEVICEMODE *nt_devmode );
 void print_job_endpage(int snum, uint32 jobid);
 bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type);
 int print_queue_status(int snum, 
@@ -5513,17 +5509,31 @@ WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli,
                                   uint32_t offered,
                                   uint32_t *count,
                                   union spoolss_MonitorInfo **info);
-WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                char *name, uint32 flags, uint32 level,
-                                uint32 *num_printers, PRINTER_INFO_CTR *ctr);
-WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, 
-                                      TALLOC_CTX *mem_ctx,
-                                      uint32 level, const char *env,
-                                      uint32 *num_drivers,
-                                      PRINTER_DRIVER_CTR *ctr);
-WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                           POLICY_HND *hnd, uint32 level, uint32 firstjob, 
-                           uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr);
+WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli,
+                              TALLOC_CTX *mem_ctx,
+                              struct policy_handle *handle,
+                              uint32_t firstjob,
+                              uint32_t numjobs,
+                              uint32_t level,
+                              uint32_t offered,
+                              uint32_t *count,
+                              union spoolss_JobInfo **info);
+WERROR rpccli_spoolss_enumprinterdrivers(struct rpc_pipe_client *cli,
+                                        TALLOC_CTX *mem_ctx,
+                                        const char *server,
+                                        const char *environment,
+                                        uint32_t level,
+                                        uint32_t offered,
+                                        uint32_t *count,
+                                        union spoolss_DriverInfo **info);
+WERROR rpccli_spoolss_enumprinters(struct rpc_pipe_client *cli,
+                                  TALLOC_CTX *mem_ctx,
+                                  uint32_t flags,
+                                  const char *server,
+                                  uint32_t level,
+                                  uint32_t offered,
+                                  uint32_t *count,
+                                  union spoolss_PrinterInfo **info);
 WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                  POLICY_HND *hnd, const char *valuename, 
                                  REGISTRY_VALUE *value);
@@ -5831,66 +5841,7 @@ bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
                                   const char *valuename, uint32 size);
 bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth);
 bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth);
-bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth);
-bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth);
-bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth);
-bool smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth);
-bool smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth);
-bool smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth);
-bool smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer,
-                          PRINTER_INFO_6 *info, int depth);
-bool smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth);
-bool smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) ;
-bool smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) ;
-bool smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth);
-bool smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth);
-bool smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth);
-bool smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth);
-uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info);
-uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info);
-uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info);
-uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info);
-uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info);
-uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info);
-uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info);
-uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info);
-uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info);
-uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info);
-uint32 spoolss_size_string_array(uint16 *string);
-uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info);
-uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info);
-uint32 spoolss_size_job_info_1(JOB_INFO_1 *info);
-uint32 spoolss_size_job_info_2(JOB_INFO_2 *info);
 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p);
-bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth);
-bool make_spoolss_q_enumprinters(
-       SPOOL_Q_ENUMPRINTERS *q_u, 
-       uint32 flags, 
-       char *servername, 
-       uint32 level, 
-       RPC_BUFFER *buffer, 
-       uint32 offered
-);
-bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth);
-bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth);
-bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth);
-bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
-                               uint32 firstjob,
-                               uint32 numofjobs,
-                               uint32 level,
-                               RPC_BUFFER *buffer,
-                               uint32 offered);
-bool spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth);
-bool make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
-                                const char *name,
-                                const char *environment,
-                                uint32 level,
-                                RPC_BUFFER *buffer, uint32 offered);
-bool spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth);
 bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src);
 bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth);
 bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth);
@@ -5904,17 +5855,6 @@ bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND
                                   char* value, uint32 data_type, char* data, uint32 data_size);
 bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth);
 bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth);
-bool spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth);
-bool spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth);
-void free_devmode(DEVICEMODE *devmode);
-void free_printer_info_1(PRINTER_INFO_1 *printer);
-void free_printer_info_2(PRINTER_INFO_2 *printer);
-void free_printer_info_3(PRINTER_INFO_3 *printer);
-void free_printer_info_4(PRINTER_INFO_4 *printer);
-void free_printer_info_5(PRINTER_INFO_5 *printer);
-void free_printer_info_6(PRINTER_INFO_6 *printer);
-void free_printer_info_7(PRINTER_INFO_7 *printer);
-void free_job_info_2(JOB_INFO_2 *job);
 bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
                                   POLICY_HND *hnd, const char *key, 
                                   uint32 size);
@@ -6117,17 +6057,13 @@ void construct_info_data(struct spoolss_Notify *info_data,
                         enum spoolss_Field field,
                         int id);
 DEVICEMODE *construct_dev_mode(const char *servicename);
-WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u);
-WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u);
-WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u);
+struct spoolss_DeviceMode *construct_dev_mode_new(TALLOC_CTX *mem_ctx,
+                                                 const char *servicename);
 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri );
 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer);
-WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u);
-WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u);
 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines );
 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u);
 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u);
-WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u);
 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u);
 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u);
 
index fdce63aba3187fee7854bfc8a80aa4df568c6568..eb2fdd53090c6caacc10e8fe1812e0c307043ff2 100644 (file)
@@ -311,274 +311,6 @@ typedef struct spool_r_getprinterdata
 }
 SPOOL_R_GETPRINTERDATA;
 
-typedef struct printer_info_0
-{
-       UNISTR printername;
-       UNISTR servername;
-       uint32 cjobs;
-       uint32 total_jobs;
-       uint32 total_bytes;
-       
-       uint16 year;
-       uint16 month;
-       uint16 dayofweek;
-       uint16 day;
-       uint16 hour;
-       uint16 minute;
-       uint16 second;
-       uint16 milliseconds;
-
-       uint32 global_counter;
-       uint32 total_pages;
-
-       uint16 major_version;
-       uint16 build_version;
-
-       uint32 unknown7;
-       uint32 unknown8;
-       uint32 unknown9;
-       uint32 session_counter;
-       uint32 unknown11;
-       uint32 printer_errors;
-       uint32 unknown13;
-       uint32 unknown14;
-       uint32 unknown15;
-       uint32 unknown16;
-       uint32 change_id;
-       uint32 unknown18;
-       uint32 status;
-       uint32 unknown20;
-       uint32 c_setprinter;
-
-       uint16 unknown22;
-       uint16 unknown23;
-       uint16 unknown24;
-       uint16 unknown25;
-       uint16 unknown26;
-       uint16 unknown27;
-       uint16 unknown28;
-       uint16 unknown29;
-} PRINTER_INFO_0;
-
-typedef struct printer_info_1
-{
-       uint32 flags;
-       UNISTR description;
-       UNISTR name;
-       UNISTR comment;
-}
-PRINTER_INFO_1;
-
-typedef struct printer_info_2
-{
-       UNISTR servername;
-       UNISTR printername;
-       UNISTR sharename;
-       UNISTR portname;
-       UNISTR drivername;
-       UNISTR comment;
-       UNISTR location;
-       DEVICEMODE *devmode;
-       UNISTR sepfile;
-       UNISTR printprocessor;
-       UNISTR datatype;
-       UNISTR parameters;
-       SEC_DESC *secdesc;
-       uint32 attributes;
-       uint32 priority;
-       uint32 defaultpriority;
-       uint32 starttime;
-       uint32 untiltime;
-       uint32 status;
-       uint32 cjobs;
-       uint32 averageppm;
-}
-PRINTER_INFO_2;
-
-typedef struct printer_info_3
-{
-       SEC_DESC *secdesc;
-}
-PRINTER_INFO_3;
-
-typedef struct printer_info_4
-{
-       UNISTR printername;
-       UNISTR servername;
-       uint32 attributes;
-}
-PRINTER_INFO_4;
-
-typedef struct printer_info_5
-{
-       UNISTR printername;
-       UNISTR portname;
-       uint32 attributes;
-       uint32 device_not_selected_timeout;
-       uint32 transmission_retry_timeout;
-}
-PRINTER_INFO_5;
-
-typedef struct printer_info_6
-{
-       uint32 status;
-}
-PRINTER_INFO_6;
-
-typedef struct printer_info_7
-{
-       UNISTR guid; /* text form of printer guid */
-       uint32 action;
-}
-PRINTER_INFO_7;
-
-typedef struct spool_q_enumprinters
-{
-       uint32 flags;
-       uint32 servername_ptr;
-       UNISTR2 servername;
-       uint32 level;
-       RPC_BUFFER *buffer;
-       uint32 offered;
-}
-SPOOL_Q_ENUMPRINTERS;
-
-typedef struct printer_info_ctr_info
-{
-       PRINTER_INFO_0 *printers_0;
-       PRINTER_INFO_1 *printers_1;
-       PRINTER_INFO_2 *printers_2;
-       PRINTER_INFO_3 *printers_3;
-       PRINTER_INFO_4 *printers_4;
-       PRINTER_INFO_5 *printers_5;
-       PRINTER_INFO_7 *printers_7;
-}
-PRINTER_INFO_CTR;
-
-typedef struct spool_r_enumprinters
-{
-       RPC_BUFFER *buffer;
-       uint32 needed;          /* bytes needed */
-       uint32 returned;        /* number of printers */
-       WERROR status;
-}
-SPOOL_R_ENUMPRINTERS;
-
-
-typedef struct spool_q_getprinter
-{
-       POLICY_HND handle;
-       uint32 level;
-       RPC_BUFFER *buffer;
-       uint32 offered;
-}
-SPOOL_Q_GETPRINTER;
-
-typedef struct printer_info_info
-{
-       union
-       {
-               PRINTER_INFO_0 *info0;
-               PRINTER_INFO_1 *info1;
-               PRINTER_INFO_2 *info2;
-               void *info;
-       } printer;
-} PRINTER_INFO;
-
-typedef struct spool_r_getprinter
-{
-       RPC_BUFFER *buffer;
-       uint32 needed;
-       WERROR status;
-} SPOOL_R_GETPRINTER;
-
-typedef struct driver_info_1
-{
-       UNISTR name;
-} DRIVER_INFO_1;
-
-typedef struct driver_info_2
-{
-       uint32 version;
-       UNISTR name;
-       UNISTR architecture;
-       UNISTR driverpath;
-       UNISTR datafile;
-       UNISTR configfile;
-} DRIVER_INFO_2;
-
-typedef struct driver_info_3
-{
-       uint32 version;
-       UNISTR name;
-       UNISTR architecture;
-       UNISTR driverpath;
-       UNISTR datafile;
-       UNISTR configfile;
-       UNISTR helpfile;
-       uint16 *dependentfiles;
-       UNISTR monitorname;
-       UNISTR defaultdatatype;
-}
-DRIVER_INFO_3;
-
-typedef struct driver_info_6
-{
-       uint32 version;
-       UNISTR name;
-       UNISTR architecture;
-       UNISTR driverpath;
-       UNISTR datafile;
-       UNISTR configfile;
-       UNISTR helpfile;
-       uint16 *dependentfiles;
-       UNISTR monitorname;
-       UNISTR defaultdatatype;
-       uint16* previousdrivernames;
-       NTTIME driver_date;
-       uint32 padding;
-       uint32 driver_version_low;
-       uint32 driver_version_high;
-       UNISTR mfgname;
-       UNISTR oem_url;
-       UNISTR hardware_id;
-       UNISTR provider;
-}
-DRIVER_INFO_6;
-
-typedef struct driver_info_info
-{
-       DRIVER_INFO_1 *info1;
-       DRIVER_INFO_2 *info2;
-       DRIVER_INFO_3 *info3;
-       DRIVER_INFO_6 *info6;
-}
-PRINTER_DRIVER_CTR;
-
-typedef struct spool_q_getprinterdriver2
-{
-       POLICY_HND handle;
-       uint32 architecture_ptr;
-       UNISTR2 architecture;
-       uint32 level;
-       RPC_BUFFER *buffer;
-       uint32 offered;
-       uint32 clientmajorversion;
-       uint32 clientminorversion;
-}
-SPOOL_Q_GETPRINTERDRIVER2;
-
-typedef struct spool_r_getprinterdriver2
-{
-       RPC_BUFFER *buffer;
-       uint32 needed;
-       uint32 servermajorversion;
-       uint32 serverminorversion;
-       WERROR status;
-}
-SPOOL_R_GETPRINTERDRIVER2;
-
-
 typedef struct add_jobinfo_1
 {
        UNISTR path;
@@ -606,116 +338,6 @@ typedef struct systemtime
 }
 SYSTEMTIME;
 
-typedef struct s_job_info_1
-{
-       uint32 jobid;
-       UNISTR printername;
-       UNISTR machinename;
-       UNISTR username;
-       UNISTR document;
-       UNISTR datatype;
-       UNISTR text_status;
-       uint32 status;
-       uint32 priority;
-       uint32 position;
-       uint32 totalpages;
-       uint32 pagesprinted;
-       SYSTEMTIME submitted;
-}
-JOB_INFO_1;
-
-typedef struct s_job_info_2
-{
-       uint32 jobid;
-       UNISTR printername;
-       UNISTR machinename;
-       UNISTR username;
-       UNISTR document;
-       UNISTR notifyname;
-       UNISTR datatype;
-       UNISTR printprocessor;
-       UNISTR parameters;
-       UNISTR drivername;
-       DEVICEMODE *devmode;
-       UNISTR text_status;
-/*     SEC_DESC sec_desc;*/
-       uint32 status;
-       uint32 priority;
-       uint32 position;
-       uint32 starttime;
-       uint32 untiltime;
-       uint32 totalpages;
-       uint32 size;
-       SYSTEMTIME submitted;
-       uint32 timeelapsed;
-       uint32 pagesprinted;
-}
-JOB_INFO_2;
-
-typedef struct spool_q_enumjobs
-{
-       POLICY_HND handle;
-       uint32 firstjob;
-       uint32 numofjobs;
-       uint32 level;
-       RPC_BUFFER *buffer;
-       uint32 offered;
-}
-SPOOL_Q_ENUMJOBS;
-
-typedef struct job_info_ctr_info
-{
-       union
-       {
-               JOB_INFO_1 *job_info_1;
-               JOB_INFO_2 *job_info_2;
-               void *info;
-       } job;
-
-} JOB_INFO_CTR;
-
-typedef struct spool_r_enumjobs
-{
-       RPC_BUFFER *buffer;
-       uint32 needed;
-       uint32 returned;
-       WERROR status;
-}
-SPOOL_R_ENUMJOBS;
-
-typedef struct job_info_info
-{
-       union
-       {
-               JOB_INFO_1 job_info_1;
-               JOB_INFO_2 job_info_2;
-       }
-       job;
-
-}
-JOB_INFO;
-
-typedef struct spool_q_enumprinterdrivers
-{
-       uint32 name_ptr;
-       UNISTR2 name;
-       uint32 environment_ptr;
-       UNISTR2 environment;
-       uint32 level;
-       RPC_BUFFER *buffer;
-       uint32 offered;
-}
-SPOOL_Q_ENUMPRINTERDRIVERS;
-
-typedef struct spool_r_enumprinterdrivers
-{
-       RPC_BUFFER *buffer;
-       uint32 needed;
-       uint32 returned;
-       WERROR status;
-}
-SPOOL_R_ENUMPRINTERDRIVERS;
-
 /********************************************/
 
 typedef struct spool_q_enumprinterdata
@@ -772,37 +394,6 @@ typedef struct _form
 }
 FORM;
 
-typedef struct spool_q_getjob
-{
-       POLICY_HND handle;
-       uint32 jobid;
-       uint32 level;
-       RPC_BUFFER *buffer;
-       uint32 offered;
-}
-SPOOL_Q_GETJOB;
-
-typedef struct pjob_info_info
-{
-       union
-       {
-               JOB_INFO_1 *job_info_1;
-               JOB_INFO_2 *job_info_2;
-               void *info;
-       }
-       job;
-
-}
-PJOB_INFO;
-
-typedef struct spool_r_getjob
-{
-       RPC_BUFFER *buffer;
-       uint32 needed;
-       WERROR status;
-}
-SPOOL_R_GETJOB;
-
 typedef struct spool_q_enumprinterkey
 {
        POLICY_HND handle;
index a0140fe0819f6eb9af66639043f129af29a4482c..281a218256f5d83fa1089cff2a0297e4b7dddd99 100644 (file)
@@ -1759,13 +1759,6 @@ struct node_status_extra {
        /* There really is more here ... */ 
 };
 
-struct pwd_info {
-       bool null_pwd;
-       bool cleartext;
-
-       fstring password;
-};
-
 /* For split krb5 SPNEGO blobs. */
 struct pending_auth_data {
        struct pending_auth_data *prev, *next;
index f9a0436546fa52355b43b427d529cec215114750..5b52bad8c1aea5d39b8b635c218a4caf0818f2f1 100644 (file)
@@ -243,6 +243,14 @@ enum profile_stats_values
 #define syscall_brl_cancel_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, count)
 #define syscall_brl_cancel_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, time)
 
+       PR_VALUE_SYSCALL_STRICT_LOCK,
+#define syscall_strict_lock_count __profile_stats_value(PR_VALUE_SYSCALL_STRICT_LOCK, count)
+#define syscall_strict_lock_time __profile_stats_value(PR_VALUE_SYSCALL_STRICT_LOCK, time)
+
+       PR_VALUE_SYSCALL_STRICT_UNLOCK,
+#define syscall_strict_unlock_count __profile_stats_value(PR_VALUE_SYSCALL_STRICT_UNLOCK, count)
+#define syscall_strict_unlock_time __profile_stats_value(PR_VALUE_SYSCALL_STRICT_UNLOCK, time)
+
 /* counters for individual SMB types */
        PR_VALUE_SMBMKDIR,
 #define SMBmkdir_count __profile_stats_value(PR_VALUE_SMBMKDIR, count)
index 0ee7f236b07346d780f1401cbcb3ad78b1cbf9da..0c0e0938bd823fbaee9b43a1461ad79f171b2dcc 100644 (file)
 /* Leave at 25 - not yet released. Add SMB_STRUCT_STAT to readdir. - sdann */
 /* Leave at 25 - not yet released. Add init_search_op call. - sdann */
 /* Leave at 25 - not yet released. Add locking calls. -- zkirsch. */
+/* Leave at 25 - not yet released. Add strict locking calls. -- drichards. */
 
 #define SMB_VFS_INTERFACE_VERSION 25
 
@@ -223,6 +224,8 @@ typedef enum _vfs_op_type {
        SMB_VFS_OP_BRL_LOCK_WINDOWS,
        SMB_VFS_OP_BRL_UNLOCK_WINDOWS,
        SMB_VFS_OP_BRL_CANCEL_WINDOWS,
+       SMB_VFS_OP_STRICT_LOCK,
+       SMB_VFS_OP_STRICT_UNLOCK,
 
        /* NT ACL operations. */
 
@@ -415,6 +418,14 @@ struct vfs_ops {
                                           struct lock_struct *plock,
                                           struct blocking_lock_record *blr);
 
+               bool (*strict_lock)(struct vfs_handle_struct *handle,
+                                       struct files_struct *fsp,
+                                       struct lock_struct *plock);
+
+               void (*strict_unlock)(struct vfs_handle_struct *handle,
+                                       struct files_struct *fsp,
+                                       struct lock_struct *plock);
+
                /* NT ACL operations. */
 
                NTSTATUS (*fget_nt_acl)(struct vfs_handle_struct *handle,
@@ -556,6 +567,8 @@ struct vfs_ops {
                struct vfs_handle_struct *brl_lock_windows;
                struct vfs_handle_struct *brl_unlock_windows;
                struct vfs_handle_struct *brl_cancel_windows;
+               struct vfs_handle_struct *strict_lock;
+               struct vfs_handle_struct *strict_unlock;
 
                /* NT ACL operations. */
 
index 7dacd2319ab980ee932ba2614582d6975178f535..acb158e3a5a975d46a8b1410d1822cf4bd968ddf 100644 (file)
@@ -91,6 +91,8 @@
 #define SMB_VFS_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs.ops.brl_lock_windows((conn)->vfs.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
 #define SMB_VFS_BRL_UNLOCK_WINDOWS(conn, msg_ctx, br_lck, plock) ((conn)->vfs.ops.brl_unlock_windows((conn)->vfs.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock)))
 #define SMB_VFS_BRL_CANCEL_WINDOWS(conn, br_lck, plock, blr) ((conn)->vfs.ops.brl_cancel_windows((conn)->vfs.handles.brl_cancel_windows, (br_lck), (plock), (blr)))
+#define SMB_VFS_STRICT_LOCK(conn, fsp, plock) ((conn)->vfs.ops.strict_lock((conn)->vfs.handles.strict_lock, (fsp), (plock)))
+#define SMB_VFS_STRICT_UNLOCK(conn, fsp, plock) ((conn)->vfs.ops.strict_unlock((conn)->vfs.handles.strict_unlock, (fsp), (plock)))
 
 /* NT ACL operations. */
 #define SMB_VFS_FGET_NT_ACL(fsp, security_info, ppdesc) ((fsp)->conn->vfs.ops.fget_nt_acl((fsp)->conn->vfs.handles.fget_nt_acl, (fsp), (security_info), (ppdesc)))
 #define SMB_VFS_OPAQUE_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs_opaque.ops.brl_lock_windows((conn)->vfs_opaque.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
 #define SMB_VFS_OPAQUE_BRL_UNLOCK_WINDOWS(conn, msg_ctx, br_lck, plock) ((conn)->vfs_opaque.ops.brl_unlock_windows((conn)->vfs_opaque.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock)))
 #define SMB_VFS_OPAQUE_BRL_CANCEL_WINDOWS(conn, br_lck, plock, blr) ((conn)->vfs_opaque.ops.brl_cancel_windows((conn)->vfs_opaque.handles.brl_cancel_windows, (br_lck), (plock), (blr)))
+#define SMB_VFS_OPAQUE_STRICT_LOCK(conn, fsp, plock) ((conn)->vfs_opaque.ops.strict_lock((conn)->vfs_opaque.handles.strict_lock, (fsp), (plock)))
+#define SMB_VFS_OPAQUE_STRICT_UNLOCK(conn, fsp, plock) ((conn)->vfs_opaque.ops.strict_unlock((conn)->vfs_opaque.handles.strict_unlock, (fsp), (plock)))
 
 /* NT ACL operations. */
 #define SMB_VFS_OPAQUE_FGET_NT_ACL(fsp, security_info, ppdesc) ((fsp)->conn->vfs_opaque.ops.fget_nt_acl((fsp)->conn->vfs_opaque.handles.fget_nt_acl, (fsp), (security_info), (ppdesc)))
 #define SMB_VFS_NEXT_BRL_LOCK_WINDOWS(handle, br_lck, plock, blocking_lock, blr) ((handle)->vfs_next.ops.brl_lock_windows((handle)->vfs_next.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
 #define SMB_VFS_NEXT_BRL_UNLOCK_WINDOWS(handle, msg_ctx, br_lck, plock) ((handle)->vfs_next.ops.brl_unlock_windows((handle)->vfs_next.handles.brl_unlock_windows, (msg_ctx), (br_lck), (plock)))
 #define SMB_VFS_NEXT_BRL_CANCEL_WINDOWS(handle, br_lck, plock, blr) ((handle)->vfs_next.ops.brl_cancel_windows((handle)->vfs_next.handles.brl_cancel_windows, (br_lck), (plock), (blr)))
+#define SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock) ((handle)->vfs_next.ops.strict_lock((handle)->vfs_next.handles.strict_lock, (fsp), (plock)))
+#define SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock) ((handle)->vfs_next.ops.strict_unlock((handle)->vfs_next.handles.strict_unlock, (fsp), (plock)))
 
 /* NT ACL operations. */
 #define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc) ((handle)->vfs_next.ops.fget_nt_acl((handle)->vfs_next.handles.fget_nt_acl, (fsp), (security_info), (ppdesc)))
index b5e769f8c3871ca0bb76ea61cfd388036e47bfd4..fd9b669710c6ef534da367abc5095f591b19d57e 100644 (file)
@@ -61,7 +61,8 @@ wbcErr wb_resp_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                         struct winbindd_response **presp);
 
 struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
-                                     struct tevent_context *ev, int fd,
+                                     struct tevent_context *ev,
+                                     struct tevent_queue *queue, int fd,
                                      struct winbindd_response *wb_resp);
 wbcErr wb_resp_write_recv(struct tevent_req *req);
 
index f875e0dc0c564e68a015f993c91530e3c5ee3f4a..8c56941829002030cbb654beb1fcc7d030c1e37b 100644 (file)
@@ -145,7 +145,7 @@ struct timeval *get_timed_events_timeout(struct tevent_context *ev,
        return to_ret;
 }
 
-static int s3_event_loop_once(struct tevent_context *ev)
+static int s3_event_loop_once(struct tevent_context *ev, const char *location)
 {
        struct timeval now, to;
        fd_set r_fds, w_fds;
@@ -181,12 +181,12 @@ static int s3_event_loop_once(struct tevent_context *ev)
        return 0;
 }
 
-static int s3_event_loop_wait(struct tevent_context *ev)
+static int s3_event_loop_wait(struct tevent_context *ev, const char *location)
 {
        int ret = 0;
 
        while (ret == 0) {
-               ret = s3_event_loop_once(ev);
+               ret = s3_event_loop_once(ev, location);
        }
 
        return ret;
index 233255fed4fe8c075fab08203a5c22681697dff7..43ebed6c220d622c7d3a548ee2bf4da2e99f7ff9 100644 (file)
@@ -73,19 +73,10 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx,
 /********************************************************************
 ********************************************************************/
 
-WERROR libnetapi_shutdown_cm(struct libnetapi_ctx *ctx)
-{
-       cli_cm_shutdown();
-
-       return WERR_OK;
-}
-
-/********************************************************************
-********************************************************************/
-
 struct client_pipe_connection {
        struct client_pipe_connection *prev, *next;
        struct rpc_pipe_client *pipe;
+       struct cli_state *cli;
 };
 
 static struct client_pipe_connection *pipe_connections;
@@ -93,6 +84,20 @@ static struct client_pipe_connection *pipe_connections;
 /********************************************************************
 ********************************************************************/
 
+WERROR libnetapi_shutdown_cm(struct libnetapi_ctx *ctx)
+{
+       struct client_pipe_connection *p;
+
+       for (p = pipe_connections; p; p = p->next) {
+               cli_shutdown(p->cli);
+       }
+
+       return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
 static NTSTATUS pipe_cm_find(struct cli_state *cli,
                             const struct ndr_syntax_id *interface,
                             struct rpc_pipe_client **presult)
@@ -138,6 +143,7 @@ static NTSTATUS pipe_cm_connect(TALLOC_CTX *mem_ctx,
                return status;
        }
 
+       p->cli = cli;
        DLIST_ADD(pipe_connections, p);
 
        *presult = p->pipe;
@@ -193,5 +199,3 @@ WERROR libnetapi_open_pipe(struct libnetapi_ctx *ctx,
 
        return WERR_OK;
 }
-
-
index 6ae1d1bb9bb11d531775caa6893d185a1b93298c..e1c67491c0f43219cc7e3241f8511c25fc1adcf7 100644 (file)
@@ -372,7 +372,8 @@ struct resp_write_state {
 static void wb_resp_write_done(struct tevent_req *subreq);
 
 struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
-                                     struct tevent_context *ev, int fd,
+                                     struct tevent_context *ev,
+                                     struct tevent_queue *queue, int fd,
                                      struct winbindd_response *wb_resp)
 {
        struct tevent_req *result, *subreq;
@@ -394,7 +395,7 @@ struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
                count = 2;
        }
 
-       subreq = writev_send(state, ev, NULL, fd, state->iov, count);
+       subreq = writev_send(state, ev, queue, fd, state->iov, count);
        if (subreq == NULL) {
                goto fail;
        }
index ec2932488ead4b0a56e7ad961ab0d5c5ab0e7fde..43326e912cc49c33e6067dfc23d4d13f7e42aae0 100644 (file)
@@ -61,6 +61,7 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli,
 {
        DATA_BLOB session_key = data_blob_null;
        DATA_BLOB lm_response = data_blob_null;
+       NTSTATUS status;
        fstring pword;
        char *p;
 
@@ -129,7 +130,10 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli,
        
        /* use the returned vuid from now on */
        cli->vuid = SVAL(cli->inbuf,smb_uid);   
-       fstrcpy(cli->user_name, user);
+       status = cli_set_username(cli, user);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
        if (session_key.data) {
                /* Have plaintext orginal */
@@ -237,7 +241,10 @@ NTSTATUS cli_session_setup_guest_recv(struct async_req *req)
                cli->is_samba = True;
        }
 
-       fstrcpy(cli->user_name, "");
+       status = cli_set_username(cli, "");
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
        return NT_STATUS_OK;
 }
@@ -289,6 +296,7 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
 {
        uint32 capabilities = cli_session_setup_capabilities(cli);
        char *p;
+       NTSTATUS status;
        fstring lanman;
        
        fstr_sprintf( lanman, "Samba %s", samba_version_string());
@@ -349,8 +357,10 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
                         -1, STR_TERMINATE);
        p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
                         -1, STR_TERMINATE);
-       fstrcpy(cli->user_name, user);
-
+       status = cli_set_username(cli, user);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
        if (strstr(cli->server_type, "Samba")) {
                cli->is_samba = True;
        }
@@ -520,7 +530,10 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
                cli->is_samba = True;
        }
 
-       fstrcpy(cli->user_name, user);
+       result = cli_set_username(cli, user);
+       if (!NT_STATUS_IS_OK(result)) {
+               goto end;
+       }
 
        if (session_key.data) {
                /* Have plaintext orginal */
@@ -898,6 +911,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
        DATA_BLOB blob;
        const char *p = NULL;
        char *account = NULL;
+       NTSTATUS status;
 
        DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
 
@@ -936,7 +950,10 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
 
        DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
 
-       fstrcpy(cli->user_name, user);
+       status = cli_set_username(cli, user);
+       if (!NT_STATUS_IS_OK(status)) {
+               return ADS_ERROR_NT(status);
+       }
 
 #ifdef HAVE_KRB5
        /* If password is set we reauthenticate to kerberos server
@@ -2101,7 +2118,11 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
                }
        }
 
-       cli_init_creds(cli, user, domain, password);
+       nt_status = cli_init_creds(cli, user, domain, password);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               cli_shutdown(cli);
+               return nt_status;
+       }
 
        *output_cli = cli;
        return NT_STATUS_OK;
index 1153d8dc8994b9fe6bbd2e0bffd619fb669b48f4..8544d5520eac5825d95f1ca069ca8705b0171949 100644 (file)
@@ -3,7 +3,7 @@
    client connect/disconnect routines
    Copyright (C) Andrew Tridgell                  1994-1998
    Copyright (C) Gerald (Jerry) Carter            2004
-   Copyright (C) Jeremy Allison                   2007
+   Copyright (C) Jeremy Allison                   2007-2009
 
    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
    as a separator when looking at the pathname part.... JRA.
 ********************************************************************/
 
-struct client_connection {
-       struct client_connection *prev, *next;
-       struct cli_state *cli;
-       char *mount;
-};
-
 static struct cm_cred_struct {
        char *username;
        char *password;
@@ -49,8 +43,6 @@ static struct cm_cred_struct {
 
 static void cm_set_password(const char *newpass);
 
-static struct client_connection *connections;
-
 static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
                                struct cli_state *cli,
                                const char *sharename,
@@ -96,7 +88,7 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c,
 
        return status;
 }
-       
+
 /********************************************************************
  Return a connection to a server.
 ********************************************************************/
@@ -301,52 +293,20 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
 /****************************************************************************
 ****************************************************************************/
 
-static void cli_cm_set_mntpoint(struct cli_state *c, const char *mnt)
-{
-       struct client_connection *p;
-       int i;
-
-       for (p=connections,i=0; p; p=p->next,i++) {
-               if (strequal(p->cli->desthost, c->desthost) &&
-                               strequal(p->cli->share, c->share)) {
-                       break;
-               }
-       }
-
-       if (p) {
-               char *name = clean_name(NULL, mnt);
-               if (!name) {
-                       return;
-               }
-               TALLOC_FREE(p->mount);
-               p->mount = talloc_strdup(p, name);
-               TALLOC_FREE(name);
-       }
-}
-
-/****************************************************************************
-****************************************************************************/
-
-const char *cli_cm_get_mntpoint(struct cli_state *c)
+static void cli_set_mntpoint(struct cli_state *cli, const char *mnt)
 {
-       struct client_connection *p;
-       int i;
-
-       for (p=connections,i=0; p; p=p->next,i++) {
-               if (strequal(p->cli->desthost, c->desthost) &&
-                               strequal(p->cli->share, c->share)) {
-                       break;
-               }
-       }
-
-       if (p) {
-               return p->mount;
+       char *name = clean_name(NULL, mnt);
+       if (!name) {
+               return;
        }
-       return NULL;
+       TALLOC_FREE(cli->dfs_mountpoint);
+       cli->dfs_mountpoint = talloc_strdup(cli, name);
+       TALLOC_FREE(name);
 }
 
 /********************************************************************
- Add a new connection to the list
+ Add a new connection to the list.
+ referring_cli == NULL means a new initial connection.
 ********************************************************************/
 
 static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
@@ -359,53 +319,62 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
                                        int port,
                                        int name_type)
 {
-       struct client_connection *node;
-
-       /* NB This must be the null context here... JRA. */
-       node = TALLOC_ZERO_ARRAY(NULL, struct client_connection, 1);
-       if (!node) {
-               return NULL;
-       }
+       struct cli_state *cli;
 
-       node->cli = do_connect(ctx, server, share,
+       cli = do_connect(ctx, server, share,
                                show_hdr, force_encrypt, max_protocol,
                                port, name_type);
 
-       if ( !node->cli ) {
-               TALLOC_FREE( node );
+       if (!cli ) {
                return NULL;
        }
 
-       DLIST_ADD( connections, node );
-
-       cli_cm_set_mntpoint(node->cli, "");
+       /* Enter into the list. */
+       if (referring_cli) {
+               DLIST_ADD_END(referring_cli, cli, struct cli_state *);
+       }
 
        if (referring_cli && referring_cli->posix_capabilities) {
                uint16 major, minor;
                uint32 caplow, caphigh;
-               if (cli_unix_extensions_version(node->cli, &major,
+               if (cli_unix_extensions_version(cli, &major,
                                        &minor, &caplow, &caphigh)) {
-                       cli_set_unix_extensions_capabilities(node->cli,
+                       cli_set_unix_extensions_capabilities(cli,
                                        major, minor,
                                        caplow, caphigh);
                }
        }
 
-       return node->cli;
+       return cli;
 }
 
 /********************************************************************
- Return a connection to a server.
+ Return a connection to a server on a particular share.
 ********************************************************************/
 
-static struct cli_state *cli_cm_find(const char *server, const char *share)
+static struct cli_state *cli_cm_find(struct cli_state *cli,
+                               const char *server,
+                               const char *share)
 {
-       struct client_connection *p;
+       struct cli_state *p;
 
-       for (p=connections; p; p=p->next) {
-               if ( strequal(server, p->cli->desthost) &&
-                               strequal(share,p->cli->share)) {
-                       return p->cli;
+       if (cli == NULL) {
+               return NULL;
+       }
+
+       /* Search to the start of the list. */
+       for (p = cli; p; p = p->prev) {
+               if (strequal(server, p->desthost) &&
+                               strequal(share,p->share)) {
+                       return p;
+               }
+       }
+
+       /* Search to the end of the list. */
+       for (p = cli->next; p; p = p->next) {
+               if (strequal(server, p->desthost) &&
+                               strequal(share,p->share)) {
+                       return p;
                }
        }
 
@@ -413,8 +382,7 @@ static struct cli_state *cli_cm_find(const char *server, const char *share)
 }
 
 /****************************************************************************
- Open a client connection to a \\server\share.  Set's the current *cli
- global variable as a side-effect (but only if the connection is successful).
+ Open a client connection to a \\server\share.
 ****************************************************************************/
 
 struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
@@ -427,50 +395,28 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
                                int port,
                                int name_type)
 {
-       struct cli_state *c;
+       /* Try to reuse an existing connection in this list. */
+       struct cli_state *c = cli_cm_find(referring_cli, server, share);
 
-       /* try to reuse an existing connection */
+       if (c) {
+               return c;
+       }
 
-       c = cli_cm_find(server, share);
-       if (!c) {
-               c = cli_cm_connect(ctx, referring_cli,
+       return cli_cm_connect(ctx, referring_cli,
                                server, share, show_hdr, force_encrypt,
                                max_protocol, port, name_type);
-       }
-
-       return c;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_shutdown(void)
-{
-       struct client_connection *p, *x;
-
-       for (p=connections; p;) {
-               cli_shutdown(p->cli);
-               x = p;
-               p = p->next;
-
-               TALLOC_FREE(x);
-       }
-
-       connections = NULL;
-       return;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-void cli_cm_display(void)
+void cli_cm_display(const struct cli_state *cli)
 {
-       struct client_connection *p;
        int i;
 
-       for ( p=connections,i=0; p; p=p->next,i++ ) {
+       for (i=0; cli; cli = cli->next,i++ ) {
                d_printf("%d:\tserver=%s, share=%s\n",
-                       i, p->cli->desthost, p->cli->share );
+                       i, cli->desthost, cli->share );
        }
 }
 
@@ -998,7 +944,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
                return false;
        }
 
-       cli_cm_set_mntpoint(*targetcli, newmount);
+       cli_set_mntpoint(*targetcli, newmount);
 
        /* Check for another dfs referral, note that we are not
           checking for loops here. */
index 2983f7771aff8bb29ccaeaece51cbadb35e7663c..c1ba4e5c4f6909f325a10d73048573a3c06877c0 100644 (file)
@@ -408,24 +408,69 @@ void cli_setup_bcc(struct cli_state *cli, void *p)
        set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf)));
 }
 
+/****************************************************************************
+ Initialize Domain, user or password.
+****************************************************************************/
+
+NTSTATUS cli_set_domain(struct cli_state *cli, const char *domain)
+{
+       TALLOC_FREE(cli->domain);
+       cli->domain = talloc_strdup(cli, domain ? domain : "");
+       if (cli->domain == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       return NT_STATUS_OK;
+}
+
+NTSTATUS cli_set_username(struct cli_state *cli, const char *username)
+{
+       TALLOC_FREE(cli->user_name);
+       cli->user_name = talloc_strdup(cli, username ? username : "");
+       if (cli->user_name == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       return NT_STATUS_OK;
+}
+
+NTSTATUS cli_set_password(struct cli_state *cli, const char *password)
+{
+       TALLOC_FREE(cli->password);
+
+       /* Password can be NULL. */
+       if (password) {
+               cli->password = talloc_strdup(cli, password);
+               if (cli->password == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       } else {
+               /* Use zero NTLMSSP hashes and session key. */
+               cli->password = NULL;
+       }
+
+       return NT_STATUS_OK;
+}
+
 /****************************************************************************
  Initialise credentials of a client structure.
 ****************************************************************************/
 
-void cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password)
+NTSTATUS cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password)
 {
-       fstrcpy(cli->domain, domain);
-       fstrcpy(cli->user_name, username);
-       pwd_set_cleartext(&cli->pwd, password);
-       if (!*username) {
-               cli->pwd.null_pwd = true;
+       NTSTATUS status = cli_set_username(cli, username);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       status = cli_set_domain(cli, domain);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
+       DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain));
 
-        DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain));
+       return cli_set_password(cli, password);
 }
 
 /****************************************************************************
- Initialise a client structure. Always returns a malloc'ed struct.
+ Initialise a client structure. Always returns a talloc'ed struct.
  Set the signing state (used from the command line).
 ****************************************************************************/
 
@@ -446,6 +491,10 @@ struct cli_state *cli_initialise_ex(int signing_state)
                return NULL;
        }
 
+       cli->dfs_mountpoint = talloc_strdup(cli, "");
+       if (!cli->dfs_mountpoint) {
+               goto error;
+       }
        cli->port = 0;
        cli->fd = -1;
        cli->cnum = -1;
@@ -521,7 +570,7 @@ struct cli_state *cli_initialise_ex(int signing_state)
 
         SAFE_FREE(cli->inbuf);
         SAFE_FREE(cli->outbuf);
-       SAFE_FREE(cli);
+       TALLOC_FREE(cli);
         return NULL;
 }
 
@@ -550,6 +599,27 @@ void cli_nt_pipes_close(struct cli_state *cli)
 
 void cli_shutdown(struct cli_state *cli)
 {
+       if (cli->prev == NULL) {
+               /*
+                * Possible head of a DFS list,
+                * shutdown all subsidiary DFS
+                * connections.
+                */
+               struct cli_state *p, *next;
+
+               for (p = cli->next; p; p = next) {
+                       next = p->next;
+                       cli_shutdown(p);
+               }
+       } else {
+               /*
+                * We're a subsidiary connection.
+                * Just remove ourselves from the
+                * DFS list.
+                */
+               DLIST_REMOVE(cli->prev, cli);
+       }
+
        cli_nt_pipes_close(cli);
 
        /*
index e6047254930a8adefcf76f9113922643758f2f30..a84a64794b05e0cb51baaec1ac679974e5c44c01 100644 (file)
@@ -244,7 +244,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
        unsigned int param_len, data_len;
        uint16 setup;
        char *param;
-       const char *mnt;
        uint32 resume_key = 0;
        TALLOC_CTX *frame = talloc_stackframe();
        DATA_BLOB last_name_raw = data_blob(NULL, 0);
@@ -457,8 +456,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
                First = False;
        }
 
-       mnt = cli_cm_get_mntpoint( cli );
-
         /* see if the server disconnected or the connection otherwise failed */
         if (cli_is_error(cli)) {
                 total_received = -1;
@@ -479,7 +476,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
                                        info_level));
                                break;
                        }
-                        fn(mnt,&finfo, Mask, state);
+                        fn(cli->dfs_mountpoint, &finfo, Mask, state);
                 }
         }
 
index 7e7cf0d682129a26c173f99061a9cb671ff72704..f2f447b4c95661f7d87190473afd6f4b200cc073 100644 (file)
@@ -930,11 +930,8 @@ struct cli_push_state {
        uint16_t mode;
        off_t start_offset;
        size_t window_size;
-       bool caller_buffers;
 
-       size_t (*source)(uint8_t *inbuf, size_t n,
-                        const uint8_t **outbuf,
-                        void *priv);
+       size_t (*source)(uint8_t *buf, size_t n, void *priv);
        void *priv;
 
        bool eof;
@@ -966,21 +963,13 @@ static bool cli_push_write_setup(struct async_req *req,
        substate->req = req;
        substate->idx = idx;
        substate->ofs = state->next_offset;
-       if (state->caller_buffers) {
-               substate->buf = NULL;
-       } else {
-               substate->buf = talloc_array(substate, uint8_t,
-                                            state->chunk_size);
-               if (!substate->buf) {
-                       talloc_free(substate);
-                       return false;
-               }
+       substate->buf = talloc_array(substate, uint8_t, state->chunk_size);
+       if (!substate->buf) {
+               talloc_free(substate);
+               return false;
        }
-
-       /* source function can overwrite substate->buf... */
        substate->size = state->source(substate->buf,
                                       state->chunk_size,
-                                      (const uint8_t **)&substate->buf,
                                       state->priv);
        if (substate->size == 0) {
                state->eof = true;
@@ -1013,9 +1002,7 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
                                struct cli_state *cli,
                                uint16_t fnum, uint16_t mode,
                                off_t start_offset, size_t window_size,
-                               bool caller_buffers,
-                               size_t (*source)(uint8_t *inbuf, size_t n,
-                                                const uint8_t **outbuf,
+                               size_t (*source)(uint8_t *buf, size_t n,
                                                 void *priv),
                                void *priv)
 {
@@ -1032,7 +1019,6 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
        state->fnum = fnum;
        state->start_offset = start_offset;
        state->mode = mode;
-       state->caller_buffers = caller_buffers;
        state->source = source;
        state->priv = priv;
        state->eof = false;
@@ -1122,10 +1108,7 @@ NTSTATUS cli_push_recv(struct async_req *req)
 
 NTSTATUS cli_push(struct cli_state *cli, uint16_t fnum, uint16_t mode,
                  off_t start_offset, size_t window_size,
-                 bool caller_buffers,
-                 size_t (*source)(uint8_t *inbuf, size_t n,
-                                  const uint8_t **outbuf,
-                                  void *priv),
+                 size_t (*source)(uint8_t *buf, size_t n, void *priv),
                  void *priv)
 {
        TALLOC_CTX *frame = talloc_stackframe();
@@ -1146,7 +1129,7 @@ NTSTATUS cli_push(struct cli_state *cli, uint16_t fnum, uint16_t mode,
        }
 
        req = cli_push_send(frame, ev, cli, fnum, mode, start_offset,
-                           window_size, caller_buffers, source, priv);
+                           window_size, source, priv);
        if (req == NULL) {
                goto nomem;
        }
index f9ff4b3191ec83a43e4c5b030995501142fa0356..45cd392a5ae8fec7a79ab603fc370ab74f4cc595 100644 (file)
@@ -133,9 +133,17 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
                        return result;
                }
 
-               cli_init_creds(cli, "", "", NULL);
+               result = cli_init_creds(cli, "", "", NULL);
+               if (!NT_STATUS_IS_OK(result)) {
+                       cli_shutdown(cli);
+                       return result;
+               }
        } else {
-               cli_init_creds(cli, user_name, "", old_passwd);
+               result = cli_init_creds(cli, user_name, "", old_passwd);
+               if (!NT_STATUS_IS_OK(result)) {
+                       cli_shutdown(cli);
+                       return result;
+               }
        }
 
        result = cli_tcon_andx(cli, "IPC$", "IPC", "", 1);
@@ -222,7 +230,11 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
        TALLOC_FREE(pipe_hnd);
 
        /* Try anonymous NTLMSSP... */
-       cli_init_creds(cli, "", "", NULL);
+       result = cli_init_creds(cli, "", "", NULL);
+       if (!NT_STATUS_IS_OK(result)) {
+               cli_shutdown(cli);
+               return result;
+       }
 
        result = NT_STATUS_UNSUCCESSFUL;
 
diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c
deleted file mode 100644 (file)
index 071e729..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-   Password cacheing.  obfuscation is planned
-   Copyright (C) Luke Kenneth Casson Leighton 1996-1998
-   
-   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"
-
-/****************************************************************************
- Initialises a password structure.
-****************************************************************************/
-
-static void pwd_init(struct pwd_info *pwd)
-{
-       memset((char *)pwd->password  , '\0', sizeof(pwd->password  ));
-
-       pwd->null_pwd  = True; /* safest option... */
-}
-
-/****************************************************************************
- Stores a cleartext password.
-****************************************************************************/
-
-void pwd_set_cleartext(struct pwd_info *pwd, const char *clr)
-{
-       pwd_init(pwd);
-       if (clr) {
-               fstrcpy(pwd->password, clr);
-               pwd->null_pwd = False;
-       } else {
-               pwd->null_pwd = True;
-       }
-
-       pwd->cleartext = True;
-}
-
-/****************************************************************************
- Gets a cleartext password.
-****************************************************************************/
-
-void pwd_get_cleartext(struct pwd_info *pwd, fstring clr)
-{
-       if (pwd->cleartext)
-               fstrcpy(clr, pwd->password);
-       else
-               clr[0] = 0;
-
-}
index e9a5f757e517f20b65e47ca50812c20f7d7041e3..bafb89522affa7752921145fb829dd2f83b093e1 100644 (file)
@@ -75,69 +75,89 @@ const char *lock_flav_name(enum brl_flavour lock_flav)
  Called in the read/write codepath.
 ****************************************************************************/
 
-bool is_locked(files_struct *fsp,
-               uint32 smbpid,
-               uint64_t count,
-               uint64_t offset, 
-               enum brl_type lock_type)
+void init_strict_lock_struct(files_struct *fsp,
+                               uint32 smbpid,
+                               br_off start,
+                               br_off size,
+                               enum brl_type lock_type,
+                               struct lock_struct *plock)
+{
+       SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
+
+       plock->context.smbpid = smbpid;
+        plock->context.tid = fsp->conn->cnum;
+        plock->context.pid = procid_self();
+        plock->start = start;
+        plock->size = size;
+        plock->fnum = fsp->fnum;
+        plock->lock_type = lock_type;
+        plock->lock_flav = lp_posix_cifsu_locktype(fsp);
+}
+
+bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
 {
        int strict_locking = lp_strict_locking(fsp->conn->params);
-       enum brl_flavour lock_flav = lp_posix_cifsu_locktype(fsp);
-       bool ret = True;
-       
-       if (count == 0) {
-               return False;
+       bool ret = False;
+
+       if (plock->size == 0) {
+               return True;
        }
 
        if (!lp_locking(fsp->conn->params) || !strict_locking) {
-               return False;
+               return True;
        }
 
        if (strict_locking == Auto) {
-               if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
+               if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
                        DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
-                       ret = False;
+                       ret = True;
                } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
-                          (lock_type == READ_LOCK)) {
+                          (plock->lock_type == READ_LOCK)) {
                        DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
-                       ret = False;
+                       ret = True;
                } else {
                        struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
                        if (!br_lck) {
-                               return False;
+                               return True;
                        }
-                       ret = !brl_locktest(br_lck,
-                                       smbpid,
-                                       procid_self(),
-                                       offset,
-                                       count,
-                                       lock_type,
-                                       lock_flav);
+                       ret = brl_locktest(br_lck,
+                                       plock->context.smbpid,
+                                       plock->context.pid,
+                                       plock->start,
+                                       plock->size,
+                                       plock->lock_type,
+                                       plock->lock_flav);
                        TALLOC_FREE(br_lck);
                }
        } else {
                struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
                if (!br_lck) {
-                       return False;
+                       return True;
                }
-               ret = !brl_locktest(br_lck,
-                               smbpid,
-                               procid_self(),
-                               offset,
-                               count,
-                               lock_type,
-                               lock_flav);
+               ret = brl_locktest(br_lck,
+                               plock->context.smbpid,
+                               plock->context.pid,
+                               plock->start,
+                               plock->size,
+                               plock->lock_type,
+                               plock->lock_flav);
                TALLOC_FREE(br_lck);
        }
 
-       DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n",
-                       lock_flav_name(lock_flav),
-                       (double)offset, (double)count, ret ? "locked" : "unlocked",
-                       fsp->fnum, fsp->fsp_name ));
+       DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
+                       "len=%.0f %s for fnum %d file %s\n",
+                       lock_flav_name(plock->lock_flav),
+                       (double)plock->start, (double)plock->size,
+                       ret ? "unlocked" : "locked",
+                       plock->fnum, fsp->fsp_name ));
 
        return ret;
 }
 
+void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
+{
+}
+
 /****************************************************************************
  Find out if a lock could be granted - return who is blocking us if we can't.
 ****************************************************************************/
index ebeece40adbd2ce1e49ba3b99062f64ce920d02b..bb7695800ebd11051b5b08b6df531fd501a5beb5 100644 (file)
@@ -106,6 +106,14 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle,
                              struct lock_struct *plock,
                              struct blocking_lock_record *blr);
 
+bool onefs_strict_lock(vfs_handle_struct *handle,
+                       files_struct *fsp,
+                       struct lock_struct *plock);
+
+void onefs_strict_unlock(vfs_handle_struct *handle,
+                       files_struct *fsp,
+                       struct lock_struct *plock);
+
 NTSTATUS onefs_notify_watch(vfs_handle_struct *vfs_handle,
                            struct sys_notify_context *ctx,
                            struct notify_entry *e,
index 7311e1961e47ac9103667409657990fcb16452fa..a6178a9751d4305dd8a405e92f950e15b844cae4 100644 (file)
@@ -248,7 +248,7 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle,
 {
        int fd = br_lck->fsp->fh->fd;
        uint64_t id = 0;
-       bool exclusive = false;
+       enum cbrl_lock_type type;
        bool async = false;
        bool pending = false;
        bool pending_async = false;
@@ -268,20 +268,22 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle,
 
        switch (plock->lock_type) {
                case WRITE_LOCK:
-                       exclusive = true;
+                       type = CBRL_LK_EX;
                        break;
                case READ_LOCK:
+                       type = CBRL_LK_SH;
                        break;
                case PENDING_WRITE_LOCK:
                        /* Called when a blocking lock request is added - do an
                         * async lock. */
+                       type = CBRL_LK_EX;
                        pending = true;
                        async = true;
-                       exclusive = true;
                        break;
                case PENDING_READ_LOCK:
                        /* Called when a blocking lock request is added - do an
                         * async lock. */
+                       type = CBRL_LK_SH;
                        pending = true;
                        async = true;
                        break;
@@ -323,7 +325,7 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle,
        }
 
        DEBUG(10, ("Calling ifs_cbrl(LOCK)..."));
-       error = ifs_cbrl(fd, CBRL_OP_LOCK, exclusive, plock->start,
+       error = ifs_cbrl(fd, CBRL_OP_LOCK, type, plock->start,
            plock->size, async, id, plock->context.smbpid, plock->context.tid,
            plock->fnum);
        if (!error) {
@@ -373,8 +375,6 @@ success:
        return NT_STATUS_OK;
 }
 
-#define CBRL_NOTYPE true
-
 bool onefs_brl_unlock_windows(vfs_handle_struct *handle,
                              struct messaging_context *msg_ctx,
                              struct byte_range_lock *br_lck,
@@ -389,8 +389,8 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle,
        SMB_ASSERT(plock->lock_type == UNLOCK_LOCK);
 
        DEBUG(10, ("Calling ifs_cbrl(UNLOCK)..."));
-       error = ifs_cbrl(fd, CBRL_OP_UNLOCK, CBRL_NOTYPE,
-           plock->start, plock->size, CBRL_NOTYPE, 0, plock->context.smbpid,
+       error = ifs_cbrl(fd, CBRL_OP_UNLOCK, CBRL_LK_SH,
+           plock->start, plock->size, false, 0, plock->context.smbpid,
            plock->context.tid, plock->fnum);
 
        END_PROFILE(syscall_brl_unlock);
@@ -444,8 +444,8 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle,
 
        /* A real cancel. */
        DEBUG(10, ("Calling ifs_cbrl(CANCEL)..."));
-       error = ifs_cbrl(fd, CBRL_OP_CANCEL, CBRL_NOTYPE, plock->start,
-           plock->size, CBRL_NOTYPE, bs->id, plock->context.smbpid,
+       error = ifs_cbrl(fd, CBRL_OP_CANCEL, CBRL_LK_UNSPEC, plock->start,
+           plock->size, false, bs->id, plock->context.smbpid,
            plock->context.tid, plock->fnum);
 
        END_PROFILE(syscall_brl_cancel);
@@ -462,6 +462,79 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle,
        return true;
 }
 
+bool onefs_strict_lock(vfs_handle_struct *handle,
+                       files_struct *fsp,
+                       struct lock_struct *plock)
+{
+       int error;
+
+       START_PROFILE(syscall_strict_lock);
+
+       SMB_ASSERT(plock->lock_type == READ_LOCK ||
+           plock->lock_type == WRITE_LOCK);
+
+        if (!lp_locking(handle->conn->params) ||
+           !lp_strict_locking(handle->conn->params)) {
+               END_PROFILE(syscall_strict_lock);
+                return True;
+        }
+
+       if (plock->lock_flav == POSIX_LOCK) {
+               END_PROFILE(syscall_strict_lock);
+               return SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock);
+       }
+
+       if (plock->size == 0) {
+               END_PROFILE(syscall_strict_lock);
+                return True;
+       }
+
+       error = ifs_cbrl(fsp->fh->fd, CBRL_OP_LOCK,
+           plock->lock_type == READ_LOCK ? CBRL_LK_RD : CBRL_LK_WR,
+           plock->start, plock->size, 0, 0, plock->context.smbpid,
+           plock->context.tid, plock->fnum);
+
+       END_PROFILE(syscall_strict_lock);
+
+       return (error == 0);
+}
+
+void onefs_strict_unlock(vfs_handle_struct *handle,
+                       files_struct *fsp,
+                       struct lock_struct *plock)
+{
+       START_PROFILE(syscall_strict_unlock);
+
+       SMB_ASSERT(plock->lock_type == READ_LOCK ||
+           plock->lock_type == WRITE_LOCK);
+
+        if (!lp_locking(handle->conn->params) ||
+           !lp_strict_locking(handle->conn->params)) {
+               END_PROFILE(syscall_strict_unlock);
+               return;
+        }
+
+       if (plock->lock_flav == POSIX_LOCK) {
+               SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock);
+               END_PROFILE(syscall_strict_unlock);
+               return;
+       }
+
+       if (plock->size == 0) {
+               END_PROFILE(syscall_strict_unlock);
+               return;
+       }
+
+       if (fsp->fh) {
+               ifs_cbrl(fsp->fh->fd, CBRL_OP_UNLOCK,
+                   plock->lock_type == READ_LOCK ? CBRL_LK_RD : CBRL_LK_WR,
+                   plock->start, plock->size, 0, 0, plock->context.smbpid,
+                   plock->context.tid, plock->fnum);
+       }
+
+       END_PROFILE(syscall_strict_unlock);
+}
+
 /* TODO Optimization: Abstract out brl_get_locks() in the Windows case.
  * We'll malloc some memory or whatever (can't return NULL), but not actually
  * touch the TDB. */
index 7384268dae405587c9faa21e535760c57be3db82..bb01f9858817f21ec732226baa2b0f35a7388ba6 100644 (file)
@@ -1157,6 +1157,26 @@ static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct *handle,
        return brl_lock_cancel_default(br_lck, plock);
 }
 
+static bool vfswrap_strict_lock(struct vfs_handle_struct *handle,
+                               files_struct *fsp,
+                               struct lock_struct *plock)
+{
+       SMB_ASSERT(plock->lock_type == READ_LOCK ||
+           plock->lock_type == WRITE_LOCK);
+
+       return strict_lock_default(fsp, plock);
+}
+
+static void vfswrap_strict_unlock(struct vfs_handle_struct *handle,
+                               files_struct *fsp,
+                               struct lock_struct *plock)
+{
+       SMB_ASSERT(plock->lock_type == READ_LOCK ||
+           plock->lock_type == WRITE_LOCK);
+
+       strict_unlock_default(fsp, plock);
+}
+
 /* NT ACL operations. */
 
 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
@@ -1592,6 +1612,10 @@ static vfs_op_tuple vfs_default_ops[] = {
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_brl_cancel_windows),SMB_VFS_OP_BRL_CANCEL_WINDOWS,
         SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(vfswrap_strict_lock),       SMB_VFS_OP_STRICT_LOCK,
+        SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(vfswrap_strict_unlock),     SMB_VFS_OP_STRICT_UNLOCK,
+        SMB_VFS_LAYER_OPAQUE},
 
        /* NT ACL operations. */
 
index 3c159f10eb1ec1369873fe493134ad155e8a382d..ebe89ec5fd82a46aa275722eac44317914c40dc1 100644 (file)
@@ -234,6 +234,12 @@ static bool smb_full_audit_brl_cancel_windows(struct vfs_handle_struct *handle,
                                              struct byte_range_lock *br_lck,
                                              struct lock_struct *plock,
                                              struct blocking_lock_record *blr);
+static bool smb_full_audit_strict_lock(struct vfs_handle_struct *handle,
+                                      struct files_struct *fsp,
+                                      struct lock_struct *plock);
+static void smb_full_audit_strict_unlock(struct vfs_handle_struct *handle,
+                                        struct files_struct *fsp,
+                                        struct lock_struct *plock);
 static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                                uint32 security_info,
                                SEC_DESC **ppdesc);
@@ -483,6 +489,10 @@ static vfs_op_tuple audit_op_tuples[] = {
         SMB_VFS_LAYER_LOGGER},
        {SMB_VFS_OP(smb_full_audit_brl_cancel_windows), SMB_VFS_OP_BRL_CANCEL_WINDOWS,
         SMB_VFS_LAYER_LOGGER},
+       {SMB_VFS_OP(smb_full_audit_strict_lock), SMB_VFS_OP_STRICT_LOCK,
+        SMB_VFS_LAYER_LOGGER},
+       {SMB_VFS_OP(smb_full_audit_strict_unlock), SMB_VFS_OP_STRICT_UNLOCK,
+        SMB_VFS_LAYER_LOGGER},
 
        /* NT ACL operations. */
 
@@ -660,6 +670,8 @@ static struct {
        { SMB_VFS_OP_BRL_LOCK_WINDOWS,  "brl_lock_windows" },
        { SMB_VFS_OP_BRL_UNLOCK_WINDOWS, "brl_unlock_windows" },
        { SMB_VFS_OP_BRL_CANCEL_WINDOWS, "brl_cancel_windows" },
+       { SMB_VFS_OP_STRICT_LOCK, "strict_lock" },
+       { SMB_VFS_OP_STRICT_UNLOCK, "strict_unlock" },
        { SMB_VFS_OP_FGET_NT_ACL,       "fget_nt_acl" },
        { SMB_VFS_OP_GET_NT_ACL,        "get_nt_acl" },
        { SMB_VFS_OP_FSET_NT_ACL,       "fset_nt_acl" },
@@ -1766,6 +1778,34 @@ static bool smb_full_audit_brl_cancel_windows(struct vfs_handle_struct *handle,
        return result;
 }
 
+static bool smb_full_audit_strict_lock(struct vfs_handle_struct *handle,
+                                      struct files_struct *fsp,
+                                      struct lock_struct *plock)
+{
+       bool result;
+
+       result = SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock);
+
+       do_log(SMB_VFS_OP_STRICT_LOCK, result, handle,
+           "%s:%llu-%llu:%d", fsp->fsp_name, plock->start,
+           plock->size);
+
+       return result;
+}
+
+static void smb_full_audit_strict_unlock(struct vfs_handle_struct *handle,
+                                        struct files_struct *fsp,
+                                        struct lock_struct *plock)
+{
+       SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock);
+
+       do_log(SMB_VFS_OP_STRICT_UNLOCK, true, handle,
+           "%s:%llu-%llu:%d", fsp->fsp_name, plock->start,
+           plock->size);
+
+       return;
+}
+
 static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                                uint32 security_info,
                                SEC_DESC **ppdesc)
index 2ec6e069c3a523c4843704ee55a7e2bedebfcca2..ad59c2b32db22abf98afa365683074cb550e48c7 100644 (file)
@@ -289,6 +289,10 @@ static vfs_op_tuple onefs_ops[] = {
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(onefs_brl_cancel_windows), SMB_VFS_OP_BRL_CANCEL_WINDOWS,
         SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(onefs_strict_lock),         SMB_VFS_OP_STRICT_LOCK,
+        SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(onefs_strict_unlock),       SMB_VFS_OP_STRICT_UNLOCK,
+        SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(onefs_notify_watch), SMB_VFS_OP_NOTIFY_WATCH,
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(onefs_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL,
diff --git a/source3/modules/vfs_preopen.c b/source3/modules/vfs_preopen.c
new file mode 100644 (file)
index 0000000..25b9e7f
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * Force a readahead of files by opening them and reading the first bytes
+ *
+ * Copyright (C) Volker Lendecke 2008
+ *
+ * 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"
+
+struct preopen_state;
+
+struct preopen_helper {
+       struct preopen_state *state;
+       struct fd_event *fde;
+       pid_t pid;
+       int fd;
+       bool busy;
+};
+
+struct preopen_state {
+       int num_helpers;
+       struct preopen_helper *helpers;
+
+       size_t to_read;         /* How many bytes to read in children? */
+       int queue_max;
+
+       char *template_fname;   /* Filename to be sent to children */
+       size_t number_start;    /* start offset into "template_fname" */
+       int num_digits;         /* How many digits is the number long? */
+
+       int fnum_sent;          /* last fname sent to children */
+
+       int fnum_queue_end;     /* last fname to be sent, based on
+                                * last open call + preopen:queuelen
+                                */
+
+       name_compare_entry *preopen_names;
+};
+
+static void preopen_helper_destroy(struct preopen_helper *c)
+{
+       int status;
+       close(c->fd);
+       c->fd = -1;
+       kill(c->pid, SIGKILL);
+       waitpid(c->pid, &status, 0);
+       c->busy = true;
+}
+
+static void preopen_queue_run(struct preopen_state *state)
+{
+       char *pdelimiter;
+       char delimiter;
+
+       pdelimiter = state->template_fname + state->number_start
+               + state->num_digits;
+       delimiter = *pdelimiter;
+
+       while (state->fnum_sent < state->fnum_queue_end) {
+
+               ssize_t written;
+               size_t to_write;
+               int helper;
+
+               for (helper=0; helper<state->num_helpers; helper++) {
+                       if (state->helpers[helper].busy) {
+                               continue;
+                       }
+                       break;
+               }
+               if (helper == state->num_helpers) {
+                       /* everyone is busy */
+                       return;
+               }
+
+               snprintf(state->template_fname + state->number_start,
+                        state->num_digits + 1,
+                        "%.*lu", state->num_digits,
+                        (long unsigned int)(state->fnum_sent + 1));
+               *pdelimiter = delimiter;
+
+               to_write = talloc_get_size(state->template_fname);
+               written = write_data(state->helpers[helper].fd,
+                                    state->template_fname, to_write);
+               state->helpers[helper].busy = true;
+
+               if (written != to_write) {
+                       preopen_helper_destroy(&state->helpers[helper]);
+               }
+               state->fnum_sent += 1;
+       }
+}
+
+static void preopen_helper_readable(struct event_context *ev,
+                                   struct fd_event *fde, uint16_t flags,
+                                   void *priv)
+{
+       struct preopen_helper *helper = (struct preopen_helper *)priv;
+       struct preopen_state *state = helper->state;
+       ssize_t nread;
+       char c;
+
+       if ((flags & EVENT_FD_READ) == 0) {
+               return;
+       }
+
+       nread = read(helper->fd, &c, 1);
+       if (nread <= 0) {
+               preopen_helper_destroy(helper);
+               return;
+       }
+
+       helper->busy = false;
+
+       preopen_queue_run(state);
+}
+
+static int preopen_helpers_destructor(struct preopen_state *c)
+{
+       int i;
+
+       for (i=0; i<c->num_helpers; i++) {
+               if (c->helpers[i].fd == -1) {
+                       continue;
+               }
+               preopen_helper_destroy(&c->helpers[i]);
+       }
+
+       return 0;
+}
+
+static bool preopen_helper_open_one(int sock_fd, char **pnamebuf,
+                                   size_t to_read, void *filebuf)
+{
+       char *namebuf = *pnamebuf;
+       ssize_t nwritten, nread;
+       char c = 0;
+       int fd;
+
+       nread = 0;
+
+       while ((nread == 0) || (namebuf[nread-1] != '\0')) {
+               ssize_t thistime;
+
+               thistime = read(sock_fd, namebuf + nread,
+                               talloc_get_size(namebuf) - nread);
+               if (thistime <= 0) {
+                       return false;
+               }
+
+               nread += thistime;
+
+               if (nread == talloc_get_size(namebuf)) {
+                       namebuf = TALLOC_REALLOC_ARRAY(
+                               NULL, namebuf, char,
+                               talloc_get_size(namebuf) * 2);
+                       if (namebuf == NULL) {
+                               return false;
+                       }
+                       *pnamebuf = namebuf;
+               }
+       }
+
+       fd = open(namebuf, O_RDONLY);
+       if (fd == -1) {
+               goto done;
+       }
+       nread = read(fd, filebuf, to_read);
+       close(fd);
+
+ done:
+       nwritten = write(sock_fd, &c, 1);
+       return true;
+}
+
+static bool preopen_helper(int fd, size_t to_read)
+{
+       char *namebuf;
+       void *readbuf;
+
+       namebuf = TALLOC_ARRAY(NULL, char, 1024);
+       if (namebuf == NULL) {
+               return false;
+       }
+
+       readbuf = talloc_size(NULL, to_read);
+       if (readbuf == NULL) {
+               TALLOC_FREE(namebuf);
+               return false;
+       }
+
+       while (preopen_helper_open_one(fd, &namebuf, to_read, readbuf)) {
+               ;
+       }
+
+       TALLOC_FREE(readbuf);
+       TALLOC_FREE(namebuf);
+       return false;
+}
+
+static NTSTATUS preopen_init_helper(struct preopen_helper *h)
+{
+       int fdpair[2];
+       NTSTATUS status;
+
+       if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) == -1) {
+               status = map_nt_error_from_unix(errno);
+               DEBUG(10, ("socketpair() failed: %s\n", strerror(errno)));
+               return status;
+       }
+
+       h->pid = sys_fork();
+
+       if (h->pid == -1) {
+               return map_nt_error_from_unix(errno);
+       }
+
+       if (h->pid == 0) {
+               close(fdpair[0]);
+               preopen_helper(fdpair[1], h->state->to_read);
+               exit(0);
+       }
+       close(fdpair[1]);
+       h->fd = fdpair[0];
+       h->fde = event_add_fd(smbd_event_context(), h->state, h->fd,
+                             EVENT_FD_READ, preopen_helper_readable, h);
+       if (h->fde == NULL) {
+               close(h->fd);
+               h->fd = -1;
+               return NT_STATUS_NO_MEMORY;
+       }
+       h->busy = false;
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS preopen_init_helpers(TALLOC_CTX *mem_ctx, size_t to_read,
+                                    int num_helpers, int queue_max,
+                                    struct preopen_state **presult)
+{
+       struct preopen_state *result;
+       int i;
+
+       result = talloc(mem_ctx, struct preopen_state);
+       if (result == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       result->num_helpers = num_helpers;
+       result->helpers = TALLOC_ARRAY(result, struct preopen_helper,
+                                      num_helpers);
+       if (result->helpers == NULL) {
+               TALLOC_FREE(result);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       result->to_read = to_read;
+       result->queue_max = queue_max;
+       result->template_fname = NULL;
+       result->fnum_sent = 0;
+
+       for (i=0; i<num_helpers; i++) {
+               result->helpers[i].state = result;
+               result->helpers[i].fd = -1;
+       }
+
+       talloc_set_destructor(result, preopen_helpers_destructor);
+
+       for (i=0; i<num_helpers; i++) {
+               preopen_init_helper(&result->helpers[i]);
+       }
+
+       *presult = result;
+       return NT_STATUS_OK;
+}
+
+static void preopen_free_helpers(void **ptr)
+{
+       TALLOC_FREE(*ptr);
+}
+
+static struct preopen_state *preopen_state_get(vfs_handle_struct *handle)
+{
+       struct preopen_state *state;
+       NTSTATUS status;
+       const char *namelist;
+
+       if (SMB_VFS_HANDLE_TEST_DATA(handle)) {
+               SMB_VFS_HANDLE_GET_DATA(handle, state, struct preopen_state,
+                                       return NULL);
+               return state;
+       }
+
+       namelist = lp_parm_const_string(SNUM(handle->conn), "preopen", "names",
+                                       NULL);
+
+       if (namelist == NULL) {
+               return NULL;
+       }
+
+       status = preopen_init_helpers(
+               NULL,
+               lp_parm_int(SNUM(handle->conn), "preopen", "num_bytes", 1),
+               lp_parm_int(SNUM(handle->conn), "preopen", "helpers", 1),
+               lp_parm_int(SNUM(handle->conn), "preopen", "queuelen", 10),
+               &state);
+       if (!NT_STATUS_IS_OK(status)) {
+               return NULL;
+       }
+
+       set_namearray(&state->preopen_names, (char *)namelist);
+
+       if (state->preopen_names == NULL) {
+               TALLOC_FREE(state);
+               return NULL;
+       }
+
+       if (!SMB_VFS_HANDLE_TEST_DATA(handle)) {
+               SMB_VFS_HANDLE_SET_DATA(handle, state, preopen_free_helpers,
+                                       struct preopen_state, return NULL);
+       }
+
+       return state;
+}
+
+static bool preopen_parse_fname(const char *fname, unsigned long *pnum,
+                               size_t *pstart_idx, int *pnum_digits)
+{
+       const char *p, *q;
+       unsigned long num;
+
+       p = strrchr_m(fname, '/');
+       if (p == NULL) {
+               p = fname;
+       }
+
+       p += 1;
+       while (p[0] != '\0') {
+               if (isdigit(p[0]) && isdigit(p[1]) && isdigit(p[2])) {
+                       break;
+               }
+               p += 1;
+       }
+       if (*p == '\0') {
+               /* no digits around */
+               return false;
+       }
+
+       num = strtoul(p, (char **)&q, 10);
+
+       if (num+1 < num) {
+               /* overflow */
+               return false;
+       }
+
+       *pnum = num;
+       *pstart_idx = (p - fname);
+       *pnum_digits = (q - p);
+       return true;
+}
+
+static int preopen_open(vfs_handle_struct *handle, const char *fname,
+                       files_struct *fsp, int flags, mode_t mode)
+{
+       struct preopen_state *state;
+       int res;
+       unsigned long num;
+
+       DEBUG(10, ("preopen_open called on %s\n", fname));
+
+       state = preopen_state_get(handle);
+       if (state == NULL) {
+               return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+       }
+
+       res = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+       if (res == -1) {
+               return -1;
+       }
+
+       if (flags != O_RDONLY) {
+               return res;
+       }
+
+       if (!is_in_path(fname, state->preopen_names, true)) {
+               DEBUG(10, ("%s does not match the preopen:names list\n",
+                          fname));
+               return res;
+       }
+
+       TALLOC_FREE(state->template_fname);
+       state->template_fname = talloc_asprintf(
+               state, "%s/%s", fsp->conn->connectpath, fname);
+
+       if (state->template_fname == NULL) {
+               return res;
+       }
+
+       if (!preopen_parse_fname(state->template_fname, &num,
+                                &state->number_start, &state->num_digits)) {
+               TALLOC_FREE(state->template_fname);
+               return res;
+       }
+
+       if (num > state->fnum_sent) {
+               /*
+                * Helpers were too slow, there's no point in reading
+                * files in helpers that we already read in the
+                * parent.
+                */
+               state->fnum_sent = num;
+       }
+
+       if ((state->fnum_queue_end != 0) /* Something was started earlier */
+           && (num < (state->fnum_queue_end - state->queue_max))) {
+               /*
+                * "num" is before the queue we announced. This means
+                * a new run is started.
+                */
+               state->fnum_sent = num;
+       }
+
+       state->fnum_queue_end = num + state->queue_max;
+
+       preopen_queue_run(state);
+
+       return res;
+}
+
+/* VFS operations structure */
+
+static vfs_op_tuple preopen_ops[] = {
+       {SMB_VFS_OP(preopen_open),      SMB_VFS_OP_OPEN,
+        SMB_VFS_LAYER_TRANSPARENT},
+       {SMB_VFS_OP(NULL),              SMB_VFS_OP_NOOP,
+        SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_preopen_init(void);
+NTSTATUS vfs_preopen_init(void)
+{
+       return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
+                               "preopen", preopen_ops);
+}
index 98f129aa892d872774ddbd528cd57eef7b6041b0..d4359aab37d44153881e836231be3dbe2f4e8fc0 100644 (file)
@@ -104,6 +104,14 @@ static void register_name_response(struct subnet_record *subrec,
                         subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip)));
                success = False;
        } else {
+               if (!ip_equal_v4(rrec->packet->ip, p->ip)) {
+                       DEBUG(5,("register_name_response: Ignoring WINS server response "
+                               "from IP %s, for name %s. We sent to IP %s\n",
+                               inet_ntoa(p->ip),
+                               nmb_namestr(answer_name),
+                               inet_ntoa(rrec->packet->ip)));
+                       return;
+               }
                /* Unicast - check to see if the response allows us to have the name. */
                if (nmb->header.opcode == NMB_WACK_OPCODE) {
                        /* WINS server is telling us to wait. Pretend we didn't get
index d2c7fda2936c8d0451392de49eeec619a20c1751..e8116d0995210b969bcb3a27c3869ac15268b768 100644 (file)
@@ -150,7 +150,6 @@ static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods,
        NTSTATUS result = NT_STATUS_OK;
        char *domain = NULL;
        char **account_names = NULL;
-       char name[256];
        enum lsa_SidType *attr_list = NULL;
        int i;
 
@@ -168,16 +167,19 @@ static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods,
                if (attrs[i] == SID_NAME_UNKNOWN) {
                        names[i] = NULL;
                } else {
-                       snprintf(name, sizeof(name), "%s%c%s", domain,
-                                *lp_winbind_separator(), account_names[i]);
-                       names[i] = talloc_strdup(names, name);
+                       names[i] = talloc_strdup(names, account_names[i]);
+                       if (names[i] == NULL) {
+                               result = NT_STATUS_NO_MEMORY;
+                               goto done;
+                       }
+
                }
        }
 
 done:
        TALLOC_FREE(account_names);
        TALLOC_FREE(domain);
-       TALLOC_FREE(attrs);
+       TALLOC_FREE(attr_list);
        return result;
 }
 
index fc3667ea3a959ff5a0041ed28ab6a4d99be34d56..71c634442b325fc84f272e73da1a221659b3cffe 100644 (file)
@@ -2407,7 +2407,7 @@ static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
 ***************************************************************************/
 
 uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum,
-                      char *jobname, NT_DEVICEMODE *nt_devmode )
+                      const char *jobname, NT_DEVICEMODE *nt_devmode )
 {
        uint32 jobid;
        char *path;
index 24dbcb01931e9e0125e5e4b22e9d1119e37cd0b9..ef10c123f3fa62266737928c8cd9bf8f60a26eee 100644 (file)
@@ -2974,7 +2974,7 @@ bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
        if (cli == NULL) {
                return false;
        }
-       E_md4hash(cli->pwd.password, nt_hash);
+       E_md4hash(cli->password ? cli->password : "", nt_hash);
        return true;
 }
 
@@ -3699,7 +3699,7 @@ static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
 
        status = rpccli_ntlmssp_bind_data(
                result, auth_type, auth_level, domain, username,
-               cli->pwd.null_pwd ? NULL : password, &auth);
+               password, &auth);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
                          nt_errstr(status)));
index a83b0c53c639dc2d267d265f71319edce966e76c..76614c67eb90ae5f67f93be5faecd8b40d3f947b 100644 (file)
@@ -540,519 +540,174 @@ WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli,
        return werror;
 }
 
-/*********************************************************************
- Decode various spoolss rpc's and info levels
- ********************************************************************/
-
-/**********************************************************************
-**********************************************************************/
-
-static bool decode_printer_info_0(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
-                               uint32 returned, PRINTER_INFO_0 **info)
-{
-       uint32 i;
-       PRINTER_INFO_0  *inf;
-
-       if (returned) {
-               inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_0, returned);
-               if (!inf) {
-                       return False;
-               }
-               memset(inf, 0, returned*sizeof(PRINTER_INFO_0));
-       } else {
-               inf = NULL;
-       }
-
-       prs_set_offset(&buffer->prs,0);
-
-       for (i=0; i<returned; i++) {
-               if (!smb_io_printer_info_0("", buffer, &inf[i], 0)) {
-                       return False;
-               }
-       }
-
-       *info=inf;
-       return True;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static bool decode_printer_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
-                               uint32 returned, PRINTER_INFO_1 **info)
-{
-       uint32 i;
-       PRINTER_INFO_1  *inf;
-
-       if (returned) {
-               inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_1, returned);
-               if (!inf) {
-                       return False;
-               }
-               memset(inf, 0, returned*sizeof(PRINTER_INFO_1));
-       } else {
-               inf = NULL;
-       }
-
-       prs_set_offset(&buffer->prs,0);
-
-       for (i=0; i<returned; i++) {
-               if (!smb_io_printer_info_1("", buffer, &inf[i], 0)) {
-                       return False;
-               }
-       }
-
-       *info=inf;
-       return True;
-}
-
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumJobs
 **********************************************************************/
 
-static bool decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                               uint32 returned, PRINTER_INFO_2 **info)
+WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli,
+                              TALLOC_CTX *mem_ctx,
+                              struct policy_handle *handle,
+                              uint32_t firstjob,
+                              uint32_t numjobs,
+                              uint32_t level,
+                              uint32_t offered,
+                              uint32_t *count,
+                              union spoolss_JobInfo **info)
 {
-       uint32 i;
-       PRINTER_INFO_2  *inf;
-
-       if (returned) {
-               inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_2, returned);
-               if (!inf) {
-                       return False;
-               }
-               memset(inf, 0, returned*sizeof(PRINTER_INFO_2));
-       } else {
-               inf = NULL;
-       }
-
-       prs_set_offset(&buffer->prs,0);
-
-       for (i=0; i<returned; i++) {
-               /* a little initialization as we go */
-               inf[i].secdesc = NULL;
-               if (!smb_io_printer_info_2("", buffer, &inf[i], 0)) {
-                       return False;
-               }
-       }
-
-       *info=inf;
-       return True;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static bool decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                               uint32 returned, PRINTER_INFO_3 **info)
-{
-       uint32 i;
-       PRINTER_INFO_3  *inf;
-
-       if (returned) {
-               inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_3, returned);
-               if (!inf) {
-                       return False;
-               }
-               memset(inf, 0, returned*sizeof(PRINTER_INFO_3));
-       } else {
-               inf = NULL;
-       }
-
-       prs_set_offset(&buffer->prs,0);
-
-       for (i=0; i<returned; i++) {
-               inf[i].secdesc = NULL;
-               if (!smb_io_printer_info_3("", buffer, &inf[i], 0)) {
-                       return False;
-               }
-       }
-
-       *info=inf;
-       return True;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static bool decode_printer_driver_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                       uint32 returned, DRIVER_INFO_1 **info)
-{
-       uint32 i;
-       DRIVER_INFO_1 *inf;
-
-       if (returned) {
-               inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_1, returned);
-               if (!inf) {
-                       return False;
-               }
-               memset(inf, 0, returned*sizeof(DRIVER_INFO_1));
-       } else {
-               inf = NULL;
-       }
-
-       prs_set_offset(&buffer->prs,0);
-
-       for (i=0; i<returned; i++) {
-               if (!smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0)) {
-                       return False;
-               }
-       }
-
-       *info=inf;
-       return True;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static bool decode_printer_driver_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                       uint32 returned, DRIVER_INFO_2 **info)
-{
-       uint32 i;
-       DRIVER_INFO_2 *inf;
-
-       if (returned) {
-               inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_2, returned);
-               if (!inf) {
-                       return False;
-               }
-               memset(inf, 0, returned*sizeof(DRIVER_INFO_2));
-       } else {
-               inf = NULL;
-       }
-
-       prs_set_offset(&buffer->prs,0);
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
+       DATA_BLOB buffer;
 
-       for (i=0; i<returned; i++) {
-               if (!smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0)) {
-                       return False;
-               }
+       if (offered > 0) {
+               buffer = data_blob_talloc_zero(mem_ctx, offered);
+               W_ERROR_HAVE_NO_MEMORY(buffer.data);
        }
 
-       *info=inf;
-       return True;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static bool decode_printer_driver_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                       uint32 returned, DRIVER_INFO_3 **info)
-{
-       uint32 i;
-       DRIVER_INFO_3 *inf;
+       status = rpccli_spoolss_EnumJobs(cli, mem_ctx,
+                                        handle,
+                                        firstjob,
+                                        numjobs,
+                                        level,
+                                        (offered > 0) ? &buffer : NULL,
+                                        offered,
+                                        count,
+                                        info,
+                                        &needed,
+                                        &werror);
 
-       if (returned) {
-               inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_3, returned);
-               if (!inf) {
-                       return False;
-               }
-               memset(inf, 0, returned*sizeof(DRIVER_INFO_3));
-       } else {
-               inf = NULL;
-       }
-
-       prs_set_offset(&buffer->prs,0);
+       if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
+               offered = needed;
+               buffer = data_blob_talloc_zero(mem_ctx, needed);
+               W_ERROR_HAVE_NO_MEMORY(buffer.data);
 
-       for (i=0; i<returned; i++) {
-               if (!smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0)) {
-                       return False;
-               }
+               status = rpccli_spoolss_EnumJobs(cli, mem_ctx,
+                                                handle,
+                                                firstjob,
+                                                numjobs,
+                                                level,
+                                                (offered > 0) ? &buffer : NULL,
+                                                offered,
+                                                count,
+                                                info,
+                                                &needed,
+                                                &werror);
        }
 
-       *info=inf;
-       return True;
+       return werror;
 }
 
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumPrinterDrivers
 **********************************************************************/
 
-static bool decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                         uint32 num_jobs, JOB_INFO_1 **jobs)
+WERROR rpccli_spoolss_enumprinterdrivers(struct rpc_pipe_client *cli,
+                                        TALLOC_CTX *mem_ctx,
+                                        const char *server,
+                                        const char *environment,
+                                        uint32_t level,
+                                        uint32_t offered,
+                                        uint32_t *count,
+                                        union spoolss_DriverInfo **info)
 {
-       uint32 i;
-
-       if (num_jobs) {
-               *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_1, num_jobs);
-               if (*jobs == NULL) {
-                       return False;
-               }
-       } else {
-               *jobs = NULL;
-       }
-       prs_set_offset(&buffer->prs,0);
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
+       DATA_BLOB buffer;
 
-       for (i = 0; i < num_jobs; i++) {
-               if (!smb_io_job_info_1("", buffer, &((*jobs)[i]), 0)) {
-                       return False;
-               }
+       if (offered > 0) {
+               buffer = data_blob_talloc_zero(mem_ctx, offered);
+               W_ERROR_HAVE_NO_MEMORY(buffer.data);
        }
 
-       return True;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-static bool decode_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                         uint32 num_jobs, JOB_INFO_2 **jobs)
-{
-       uint32 i;
+       status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx,
+                                                  server,
+                                                  environment,
+                                                  level,
+                                                  (offered > 0) ? &buffer : NULL,
+                                                  offered,
+                                                  count,
+                                                  info,
+                                                  &needed,
+                                                  &werror);
 
-       if (num_jobs) {
-               *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_2, num_jobs);
-               if (*jobs == NULL) {
-                       return False;
-               }
-       } else {
-               *jobs = NULL;
-       }
-       prs_set_offset(&buffer->prs,0);
+       if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
+               offered = needed;
+               buffer = data_blob_talloc_zero(mem_ctx, needed);
+               W_ERROR_HAVE_NO_MEMORY(buffer.data);
 
-       for (i = 0; i < num_jobs; i++) {
-               if (!smb_io_job_info_2("", buffer, &((*jobs)[i]), 0)) {
-                       return False;
-               }
+               status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx,
+                                                  server,
+                                                  environment,
+                                                  level,
+                                                  (offered > 0) ? &buffer : NULL,
+                                                  offered,
+                                                  count,
+                                                  info,
+                                                  &needed,
+                                                  &werror);
        }
 
-       return True;
+       return werror;
 }
 
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumPrinters
 **********************************************************************/
 
-WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                char *name, uint32 flags, uint32 level,
-                                uint32 *num_printers, PRINTER_INFO_CTR *ctr)
+WERROR rpccli_spoolss_enumprinters(struct rpc_pipe_client *cli,
+                                  TALLOC_CTX *mem_ctx,
+                                  uint32_t flags,
+                                  const char *server,
+                                  uint32_t level,
+                                  uint32_t offered,
+                                  uint32_t *count,
+                                  union spoolss_PrinterInfo **info)
 {
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ENUMPRINTERS in;
-        SPOOL_R_ENUMPRINTERS out;
-       RPC_BUFFER buffer;
-       uint32 offered;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-       offered = 0;
-       if (!rpcbuf_init(&buffer, offered, mem_ctx))
-               return WERR_NOMEM;
-       make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered );
-
-       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_enumprinters,
-                   spoolss_io_r_enumprinters, 
-                   WERR_GENERAL_FAILURE );
-                   
-       if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
-               offered = out.needed;
-               
-               ZERO_STRUCT(in);
-               ZERO_STRUCT(out);
-
-               if (!rpcbuf_init(&buffer, offered, mem_ctx))
-                       return WERR_NOMEM;
-               make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered );
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
+       DATA_BLOB buffer;
 
-               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_enumprinters,
-                           spoolss_io_r_enumprinters, 
-                           WERR_GENERAL_FAILURE );
+       if (offered > 0) {
+               buffer = data_blob_talloc_zero(mem_ctx, offered);
+               W_ERROR_HAVE_NO_MEMORY(buffer.data);
        }
 
-       if ( !W_ERROR_IS_OK(out.status) )
-               return out.status;
-
-       switch (level) {
-       case 0:
-               if (!decode_printer_info_0(mem_ctx, out.buffer, out.returned, &ctr->printers_0)) {
-                       return WERR_GENERAL_FAILURE;
-               }
-               break;
-       case 1:
-               if (!decode_printer_info_1(mem_ctx, out.buffer, out.returned, &ctr->printers_1)) {
-                       return WERR_GENERAL_FAILURE;
-               }
-               break;
-       case 2:
-               if (!decode_printer_info_2(mem_ctx, out.buffer, out.returned, &ctr->printers_2)) {
-                       return WERR_GENERAL_FAILURE;
-               }
-               break;
-       case 3:
-               if (!decode_printer_info_3(mem_ctx, out.buffer, out.returned, &ctr->printers_3)) {
-                       return WERR_GENERAL_FAILURE;
-               }
-               break;
-       default:
-               return WERR_UNKNOWN_LEVEL;
-       }                       
-
-       *num_printers = out.returned;
-
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, 
-                                      TALLOC_CTX *mem_ctx,
-                                      uint32 level, const char *env,
-                                      uint32 *num_drivers,
-                                      PRINTER_DRIVER_CTR *ctr)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ENUMPRINTERDRIVERS in;
-        SPOOL_R_ENUMPRINTERDRIVERS out;
-       RPC_BUFFER buffer;
-       fstring server;
-       uint32 offered;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-        strupper_m(server);
-
-       offered = 0;
-       if (!rpcbuf_init(&buffer, offered, mem_ctx))
-               return WERR_NOMEM;
-       make_spoolss_q_enumprinterdrivers( &in, server, env, level, 
-               &buffer, offered);
-       
-       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_enumprinterdrivers,
-                   spoolss_io_r_enumprinterdrivers, 
-                   WERR_GENERAL_FAILURE );
+       status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,
+                                            flags,
+                                            server,
+                                            level,
+                                            (offered > 0) ? &buffer : NULL,
+                                            offered,
+                                            count,
+                                            info,
+                                            &needed,
+                                            &werror);
 
-       if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
-               offered = out.needed;
-               
-               ZERO_STRUCT(in);
-               ZERO_STRUCT(out);
-               
-               if (!rpcbuf_init(&buffer, offered, mem_ctx))
-                       return WERR_NOMEM;
-               make_spoolss_q_enumprinterdrivers( &in, server, env, level, 
-                       &buffer, offered);
-       
-               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_enumprinterdrivers,
-                           spoolss_io_r_enumprinterdrivers, 
-                           WERR_GENERAL_FAILURE );
-       }
-       
-       *num_drivers = out.returned;
+       if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
+               offered = needed;
+               buffer = data_blob_talloc_zero(mem_ctx, needed);
+               W_ERROR_HAVE_NO_MEMORY(buffer.data);
 
-       if ( !W_ERROR_IS_OK(out.status) )
-               return out.status;
-               
-       if ( out.returned ) {
-
-               switch (level) {
-               case 1:
-                       if (!decode_printer_driver_1(mem_ctx, out.buffer, out.returned, &ctr->info1)) {
-                               return WERR_GENERAL_FAILURE;
-                       }
-                       break;
-               case 2:
-                       if (!decode_printer_driver_2(mem_ctx, out.buffer, out.returned, &ctr->info2)) {
-                               return WERR_GENERAL_FAILURE;
-                       }
-                       break;
-               case 3:
-                       if (!decode_printer_driver_3(mem_ctx, out.buffer, out.returned, &ctr->info3)) {
-                               return WERR_GENERAL_FAILURE;
-                       }
-                       break;
-               default:
-                       return WERR_UNKNOWN_LEVEL;
-               }
+               status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,
+                                                    flags,
+                                                    server,
+                                                    level,
+                                                    (offered > 0) ? &buffer : NULL,
+                                                    offered,
+                                                    count,
+                                                    info,
+                                                    &needed,
+                                                    &werror);
        }
 
-       return out.status;
+       return werror;
 }
 
-/**********************************************************************
-**********************************************************************/
-
-WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                           POLICY_HND *hnd, uint32 level, uint32 firstjob, 
-                           uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ENUMJOBS in;
-       SPOOL_R_ENUMJOBS out;
-       RPC_BUFFER buffer;
-       uint32 offered;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-       offered = 0;
-       if (!rpcbuf_init(&buffer, offered, mem_ctx))
-               return WERR_NOMEM;
-       make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level, 
-               &buffer, offered );
-
-       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_enumjobs,
-                   spoolss_io_r_enumjobs, 
-                   WERR_GENERAL_FAILURE );
-
-       if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
-               offered = out.needed;
-               
-               ZERO_STRUCT(in);
-               ZERO_STRUCT(out);
-
-               if (!rpcbuf_init(&buffer, offered, mem_ctx))
-                       return WERR_NOMEM;
-               make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level, 
-                       &buffer, offered );
-
-               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_enumjobs,
-                           spoolss_io_r_enumjobs, 
-                           WERR_GENERAL_FAILURE );
-       }
-
-       if (!W_ERROR_IS_OK(out.status))
-               return out.status;
-               
-       switch(level) {
-       case 1:
-               if (!decode_jobs_1(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_1)) {
-                       return WERR_GENERAL_FAILURE;
-               }
-               break;
-       case 2:
-               if (!decode_jobs_2(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_2)) {
-                       return WERR_GENERAL_FAILURE;
-               }
-               break;
-       default:
-               DEBUG(3, ("unsupported info level %d", level));
-               return WERR_UNKNOWN_LEVEL;
-       }
-       
-       *returned = out.returned;
-
-       return out.status;
-}
+/*********************************************************************
+ Decode various spoolss rpc's and info levels
+ ********************************************************************/
 
 /**********************************************************************
 **********************************************************************/
index 337121d70dec21f20db2653a63fb118dafe8be51..e499607a4de50349f1fb7f66894c5cd7723547cd 100644 (file)
@@ -347,1517 +347,31 @@ bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u,
 }
 
 /*******************************************************************
- * return the length of a uint16 (obvious, but the code is clean)
- ********************************************************************/
-
-static uint32 size_of_uint16(uint16 *value)
-{
-       return (sizeof(*value));
-}
-
-/*******************************************************************
- * return the length of a uint32 (obvious, but the code is clean)
- ********************************************************************/
-
-static uint32 size_of_uint32(uint32 *value)
-{
-       return (sizeof(*value));
-}
-
-/*******************************************************************
- * return the length of a NTTIME (obvious, but the code is clean)
- ********************************************************************/
-
-static uint32 size_of_nttime(NTTIME *value)
-{
-       return (sizeof(*value));
-}
-
-/*******************************************************************
- * return the length of a uint32 (obvious, but the code is clean)
- ********************************************************************/
-
-static uint32 size_of_device_mode(DEVICEMODE *devmode)
-{
-       if (devmode==NULL)
-               return (4);
-       else 
-               return (4+devmode->size+devmode->driverextra);
-}
-
-/*******************************************************************
- * return the length of a uint32 (obvious, but the code is clean)
- ********************************************************************/
-
-static uint32 size_of_systemtime(SYSTEMTIME *systime)
-{
-       if (systime==NULL)
-               return (4);
-       else 
-               return (sizeof(SYSTEMTIME) +4);
-}
-
-/*******************************************************************
- Parse a DEVMODE structure and its relative pointer.
-********************************************************************/
-
-static bool smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_reldevmode");
-       depth++;
-
-       if (MARSHALLING(ps)) {
-               uint32 struct_offset = prs_offset(ps);
-               uint32 relative_offset;
-               
-               if (*devmode == NULL) {
-                       relative_offset=0;
-                       if (!prs_uint32("offset", ps, depth, &relative_offset))
-                               return False;
-                       DEBUG(8, ("boing, the devmode was NULL\n"));
-                       
-                       return True;
-               }
-               
-               buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
-
-               /* mz:  we have to align the device mode for VISTA */
-               if (buffer->string_at_end % 4) {
-                       buffer->string_at_end += 4 - (buffer->string_at_end % 4);
-               }
-
-               if(!prs_set_offset(ps, buffer->string_at_end))
-                       return False;
-               
-               /* write the DEVMODE */
-               if (!spoolss_io_devmode(desc, ps, depth, *devmode))
-                       return False;
-
-               if(!prs_set_offset(ps, struct_offset))
-                       return False;
-               
-               relative_offset=buffer->string_at_end - buffer->struct_start;
-               /* write its offset */
-               if (!prs_uint32("offset", ps, depth, &relative_offset))
-                       return False;
-       }
-       else {
-               uint32 old_offset;
-               
-               /* read the offset */
-               if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
-                       return False;
-               if (buffer->string_at_end == 0) {
-                       *devmode = NULL;
-                       return True;
-               }
-
-               old_offset = prs_offset(ps);
-               if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
-                       return False;
-
-               /* read the string */
-               if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
-                       return False;
-               if (!spoolss_io_devmode(desc, ps, depth, *devmode))
-                       return False;
-
-               if(!prs_set_offset(ps, old_offset))
-                       return False;
-       }
-       return True;
-}
-
-/*******************************************************************
- Parse a PRINTER_INFO_0 structure.
-********************************************************************/  
-
-bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printer_info_0");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-
-       if (!smb_io_relstr("printername", buffer, depth, &info->printername))
-               return False;
-       if (!smb_io_relstr("servername", buffer, depth, &info->servername))
-               return False;
-       
-       if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
-               return False;
-       if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
-               return False;
-       if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
-               return False;
-
-       if(!prs_uint16("year", ps, depth, &info->year))
-               return False;
-       if(!prs_uint16("month", ps, depth, &info->month))
-               return False;
-       if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
-               return False;
-       if(!prs_uint16("day", ps, depth, &info->day))
-               return False;
-       if(!prs_uint16("hour", ps, depth, &info->hour))
-               return False;
-       if(!prs_uint16("minute", ps, depth, &info->minute))
-               return False;
-       if(!prs_uint16("second", ps, depth, &info->second))
-               return False;
-       if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
-               return False;
-
-       if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
-               return False;
-       if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
-               return False;
-
-       if(!prs_uint16("major_version", ps, depth, &info->major_version))
-               return False;
-       if(!prs_uint16("build_version", ps, depth, &info->build_version))
-               return False;
-       if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
-               return False;
-       if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
-               return False;
-       if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
-               return False;
-       if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
-               return False;
-       if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
-               return False;
-       if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
-               return False;
-       if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
-               return False;
-       if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
-               return False;
-       if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
-               return False;
-       if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
-               return False;
-       if(!prs_uint32("change_id", ps, depth, &info->change_id))
-               return False;
-       if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
-               return False;
-       if(!prs_uint32("status"   , ps, depth, &info->status))
-               return False;
-       if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
-               return False;
-       if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
-               return False;
-       if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
-               return False;
-       if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
-               return False;
-       if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
-               return False;
-       if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
-               return False;
-       if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
-               return False;
-       if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
-               return False;
-       if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
-               return False;
-       if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a PRINTER_INFO_1 structure.
-********************************************************************/  
-
-bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printer_info_1");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-
-       if (!prs_uint32("flags", ps, depth, &info->flags))
-               return False;
-       if (!smb_io_relstr("description", buffer, depth, &info->description))
-               return False;
-       if (!smb_io_relstr("name", buffer, depth, &info->name))
-               return False;
-       if (!smb_io_relstr("comment", buffer, depth, &info->comment))
-               return False;   
-
-       return True;
-}
-
-/*******************************************************************
- Parse a PRINTER_INFO_2 structure.
-********************************************************************/  
-
-bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-       uint32 dm_offset, sd_offset, current_offset;
-       uint32 dummy_value = 0, has_secdesc = 0;
-
-       prs_debug(ps, depth, desc, "smb_io_printer_info_2");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-       
-       if (!smb_io_relstr("servername", buffer, depth, &info->servername))
-               return False;
-       if (!smb_io_relstr("printername", buffer, depth, &info->printername))
-               return False;
-       if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
-               return False;
-       if (!smb_io_relstr("portname", buffer, depth, &info->portname))
-               return False;
-       if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
-               return False;
-       if (!smb_io_relstr("comment", buffer, depth, &info->comment))
-               return False;
-       if (!smb_io_relstr("location", buffer, depth, &info->location))
-               return False;
-
-       /* save current offset and wind forwared by a uint32 */
-       dm_offset = prs_offset(ps);
-       if (!prs_uint32("devmode", ps, depth, &dummy_value))
-               return False;
-       
-       if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
-               return False;
-       if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
-               return False;
-       if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
-               return False;
-       if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
-               return False;
-
-       /* save current offset for the sec_desc */
-       sd_offset = prs_offset(ps);
-       if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
-               return False;
-
-       
-       /* save current location so we can pick back up here */
-       current_offset = prs_offset(ps);
-       
-       /* parse the devmode */
-       if (!prs_set_offset(ps, dm_offset))
-               return False;
-       if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
-               return False;
-       
-       /* parse the sec_desc */
-       if (info->secdesc) {
-               if (!prs_set_offset(ps, sd_offset))
-                       return False;
-               if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
-                       return False;
-       }
-
-       /* pick up where we left off */
-       if (!prs_set_offset(ps, current_offset))
-               return False;
-
-       if (!prs_uint32("attributes", ps, depth, &info->attributes))
-               return False;
-       if (!prs_uint32("priority", ps, depth, &info->priority))
-               return False;
-       if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
-               return False;
-       if (!prs_uint32("starttime", ps, depth, &info->starttime))
-               return False;
-       if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
-               return False;
-       if (!prs_uint32("status", ps, depth, &info->status))
-               return False;
-       if (!prs_uint32("jobs", ps, depth, &info->cjobs))
-               return False;
-       if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a PRINTER_INFO_3 structure.
-********************************************************************/  
-
-bool smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
-{
-       uint32 offset = 0;
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printer_info_3");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-       
-       if (MARSHALLING(ps)) {
-               /* Ensure the SD is 8 byte aligned in the buffer. */
-               uint32 start = prs_offset(ps); /* Remember the start position. */
-               uint32 off_val = 0;
-
-               /* Write a dummy value. */
-               if (!prs_uint32("offset", ps, depth, &off_val))
-                       return False;
-
-               /* 8 byte align. */
-               if (!prs_align_uint64(ps))
-                       return False;
-
-               /* Remember where we must seek back to write the SD. */
-               offset = prs_offset(ps);
-
-               /* Calculate the real offset for the SD. */
-
-               off_val = offset - start;
-
-               /* Seek back to where we store the SD offset & store. */
-               prs_set_offset(ps, start);
-               if (!prs_uint32("offset", ps, depth, &off_val))
-                       return False;
-
-               /* Return to after the 8 byte align. */
-               prs_set_offset(ps, offset);
-
-       } else {
-               if (!prs_uint32("offset", ps, depth, &offset))
-                       return False;
-               /* Seek within the buffer. */
-               if (!prs_set_offset(ps, offset))
-                       return False;
-       }
-       if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a PRINTER_INFO_4 structure.
-********************************************************************/  
-
-bool smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printer_info_4");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-       
-       if (!smb_io_relstr("printername", buffer, depth, &info->printername))
-               return False;
-       if (!smb_io_relstr("servername", buffer, depth, &info->servername))
-               return False;
-       if (!prs_uint32("attributes", ps, depth, &info->attributes))
-               return False;
-       return True;
-}
-
-/*******************************************************************
- Parse a PRINTER_INFO_5 structure.
-********************************************************************/  
-
-bool smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printer_info_5");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-       
-       if (!smb_io_relstr("printername", buffer, depth, &info->printername))
-               return False;
-       if (!smb_io_relstr("portname", buffer, depth, &info->portname))
-               return False;
-       if (!prs_uint32("attributes", ps, depth, &info->attributes))
-               return False;
-       if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
-               return False;
-       if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
-               return False;
-       return True;
-}
-
-/*******************************************************************
- Parse a PRINTER_INFO_6 structure.
-********************************************************************/  
-
-bool smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer,
-                          PRINTER_INFO_6 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printer_info_6");
-       depth++;        
-       
-       if (!prs_uint32("status", ps, depth, &info->status))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a PRINTER_INFO_7 structure.
-********************************************************************/  
-
-bool smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printer_info_7");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-       
-       if (!smb_io_relstr("guid", buffer, depth, &info->guid))
-               return False;
-       if (!prs_uint32("action", ps, depth, &info->action))
-               return False;
-       return True;
-}
-
-/*******************************************************************
- Parse a DRIVER_INFO_1 structure.
-********************************************************************/
-
-bool smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-
-       if (!smb_io_relstr("name", buffer, depth, &info->name))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a DRIVER_INFO_2 structure.
-********************************************************************/
-
-bool smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-
-       if (!prs_uint32("version", ps, depth, &info->version))
-               return False;
-       if (!smb_io_relstr("name", buffer, depth, &info->name))
-               return False;
-       if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
-               return False;
-       if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
-               return False;
-       if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
-               return False;
-       if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a DRIVER_INFO_3 structure.
-********************************************************************/
-
-bool smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-
-       if (!prs_uint32("version", ps, depth, &info->version))
-               return False;
-       if (!smb_io_relstr("name", buffer, depth, &info->name))
-               return False;
-       if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
-               return False;
-       if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
-               return False;
-       if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
-               return False;
-       if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
-               return False;
-       if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
-               return False;
-
-       if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
-               return False;
-
-       if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
-               return False;
-       if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a DRIVER_INFO_6 structure.
-********************************************************************/
-
-bool smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-
-       if (!prs_uint32("version", ps, depth, &info->version))
-               return False;
-       if (!smb_io_relstr("name", buffer, depth, &info->name))
-               return False;
-       if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
-               return False;
-       if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
-               return False;
-       if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
-               return False;
-       if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
-               return False;
-       if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
-               return False;
-
-       if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
-               return False;
-
-       if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
-               return False;
-       if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
-               return False;
-
-       if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
-               return False;
-
-       if (!prs_uint64("date", ps, depth, &info->driver_date))
-               return False;
-
-       if (!prs_uint32("padding", ps, depth, &info->padding))
-               return False;
-
-       if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
-               return False;
-
-       if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
-               return False;
-
-       if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
-               return False;
-       if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
-               return False;
-       if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
-               return False;
-       if (!smb_io_relstr("provider", buffer, depth, &info->provider))
-               return False;
-       
-       return True;
-}
-
-/*******************************************************************
- Parse a JOB_INFO_1 structure.
-********************************************************************/  
-
-bool smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_job_info_1");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-
-       if (!prs_uint32("jobid", ps, depth, &info->jobid))
-               return False;
-       if (!smb_io_relstr("printername", buffer, depth, &info->printername))
-               return False;
-       if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
-               return False;
-       if (!smb_io_relstr("username", buffer, depth, &info->username))
-               return False;
-       if (!smb_io_relstr("document", buffer, depth, &info->document))
-               return False;
-       if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
-               return False;
-       if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
-               return False;
-       if (!prs_uint32("status", ps, depth, &info->status))
-               return False;
-       if (!prs_uint32("priority", ps, depth, &info->priority))
-               return False;
-       if (!prs_uint32("position", ps, depth, &info->position))
-               return False;
-       if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
-               return False;
-       if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
-               return False;
-       if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a JOB_INFO_2 structure.
-********************************************************************/  
-
-bool smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth)
-{      
-       uint32 pipo=0;
-       prs_struct *ps=&buffer->prs;
-       
-       prs_debug(ps, depth, desc, "smb_io_job_info_2");
-       depth++;        
-
-       buffer->struct_start=prs_offset(ps);
-       
-       if (!prs_uint32("jobid",ps, depth, &info->jobid))
-               return False;
-       if (!smb_io_relstr("printername", buffer, depth, &info->printername))
-               return False;
-       if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
-               return False;
-       if (!smb_io_relstr("username", buffer, depth, &info->username))
-               return False;
-       if (!smb_io_relstr("document", buffer, depth, &info->document))
-               return False;
-       if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
-               return False;
-       if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
-               return False;
-
-       if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
-               return False;
-       if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
-               return False;
-       if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
-               return False;
-       if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
-               return False;
-       if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
-               return False;
-
-/*     SEC_DESC sec_desc;*/
-       if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
-               return False;
-
-       if (!prs_uint32("status",ps, depth, &info->status))
-               return False;
-       if (!prs_uint32("priority",ps, depth, &info->priority))
-               return False;
-       if (!prs_uint32("position",ps, depth, &info->position)) 
-               return False;
-       if (!prs_uint32("starttime",ps, depth, &info->starttime))
-               return False;
-       if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
-               return False;
-       if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
-               return False;
-       if (!prs_uint32("size",ps, depth, &info->size))
-               return False;
-       if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
-               return False;
-       if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
-               return False;
-       if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/  
-
-uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
-{
-       int size=0;
-       
-       size+=size_of_relative_string( &info->printername );
-       size+=size_of_relative_string( &info->servername );
-
-       size+=size_of_uint32( &info->cjobs);
-       size+=size_of_uint32( &info->total_jobs);
-       size+=size_of_uint32( &info->total_bytes);
-
-       size+=size_of_uint16( &info->year);
-       size+=size_of_uint16( &info->month);
-       size+=size_of_uint16( &info->dayofweek);
-       size+=size_of_uint16( &info->day);
-       size+=size_of_uint16( &info->hour);
-       size+=size_of_uint16( &info->minute);
-       size+=size_of_uint16( &info->second);
-       size+=size_of_uint16( &info->milliseconds);
-
-       size+=size_of_uint32( &info->global_counter);
-       size+=size_of_uint32( &info->total_pages);
-
-       size+=size_of_uint16( &info->major_version);
-       size+=size_of_uint16( &info->build_version);
-
-       size+=size_of_uint32( &info->unknown7);
-       size+=size_of_uint32( &info->unknown8);
-       size+=size_of_uint32( &info->unknown9);
-       size+=size_of_uint32( &info->session_counter);
-       size+=size_of_uint32( &info->unknown11);
-       size+=size_of_uint32( &info->printer_errors);
-       size+=size_of_uint32( &info->unknown13);
-       size+=size_of_uint32( &info->unknown14);
-       size+=size_of_uint32( &info->unknown15);
-       size+=size_of_uint32( &info->unknown16);
-       size+=size_of_uint32( &info->change_id);
-       size+=size_of_uint32( &info->unknown18);
-       size+=size_of_uint32( &info->status);
-       size+=size_of_uint32( &info->unknown20);
-       size+=size_of_uint32( &info->c_setprinter);
-       
-       size+=size_of_uint16( &info->unknown22);
-       size+=size_of_uint16( &info->unknown23);
-       size+=size_of_uint16( &info->unknown24);
-       size+=size_of_uint16( &info->unknown25);
-       size+=size_of_uint16( &info->unknown26);
-       size+=size_of_uint16( &info->unknown27);
-       size+=size_of_uint16( &info->unknown28);
-       size+=size_of_uint16( &info->unknown29);
-       
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/  
-
-uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
-{
-       int size=0;
-               
-       size+=size_of_uint32( &info->flags );   
-       size+=size_of_relative_string( &info->description );
-       size+=size_of_relative_string( &info->name );
-       size+=size_of_relative_string( &info->comment );
-
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-
-uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
-{
-       uint32 size=0;
-               
-       size += 4;
-       
-       size += ndr_size_security_descriptor( info->secdesc, NULL, 0 );
-
-       size+=size_of_device_mode( info->devmode );
-       
-       size+=size_of_relative_string( &info->servername );
-       size+=size_of_relative_string( &info->printername );
-       size+=size_of_relative_string( &info->sharename );
-       size+=size_of_relative_string( &info->portname );
-       size+=size_of_relative_string( &info->drivername );
-       size+=size_of_relative_string( &info->comment );
-       size+=size_of_relative_string( &info->location );
-       
-       size+=size_of_relative_string( &info->sepfile );
-       size+=size_of_relative_string( &info->printprocessor );
-       size+=size_of_relative_string( &info->datatype );
-       size+=size_of_relative_string( &info->parameters );
-
-       size+=size_of_uint32( &info->attributes );
-       size+=size_of_uint32( &info->priority );
-       size+=size_of_uint32( &info->defaultpriority );
-       size+=size_of_uint32( &info->starttime );
-       size+=size_of_uint32( &info->untiltime );
-       size+=size_of_uint32( &info->status );
-       size+=size_of_uint32( &info->cjobs );
-       size+=size_of_uint32( &info->averageppm );      
-               
-       /* 
-        * add any adjustments for alignment.  This is
-        * not optimal since we could be calling this
-        * function from a loop (e.g. enumprinters), but 
-        * it is easier to maintain the calculation here and
-        * not place the burden on the caller to remember.   --jerry
-        */
-       if ((size % 4) != 0)
-               size += 4 - (size % 4);
-       
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-
-uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
-{
-       uint32 size=0;
-               
-       size+=size_of_relative_string( &info->printername );
-       size+=size_of_relative_string( &info->servername );
-
-       size+=size_of_uint32( &info->attributes );
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-
-uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
-{
-       uint32 size=0;
-               
-       size+=size_of_relative_string( &info->printername );
-       size+=size_of_relative_string( &info->portname );
-
-       size+=size_of_uint32( &info->attributes );
-       size+=size_of_uint32( &info->device_not_selected_timeout );
-       size+=size_of_uint32( &info->transmission_retry_timeout );
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-
-uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info)
-{
-       return sizeof(uint32);
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-
-uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
-{
-       /* The 8 is for the self relative pointer - 8 byte aligned.. */
-       return 8 + (uint32)ndr_size_security_descriptor( info->secdesc, NULL, 0 );
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-
-uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
-{
-       uint32 size=0;
-               
-       size+=size_of_relative_string( &info->guid );
-       size+=size_of_uint32( &info->action );
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-
-uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
-{
-       int size=0;
-       size+=size_of_relative_string( &info->name );
-
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-
-uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
-{
-       int size=0;
-       size+=size_of_uint32( &info->version ); 
-       size+=size_of_relative_string( &info->name );
-       size+=size_of_relative_string( &info->architecture );
-       size+=size_of_relative_string( &info->driverpath );
-       size+=size_of_relative_string( &info->datafile );
-       size+=size_of_relative_string( &info->configfile );
-
-       return size;
-}
-
-/*******************************************************************
-return the size required by a string array.
-********************************************************************/
-
-uint32 spoolss_size_string_array(uint16 *string)
-{
-       uint32 i = 0;
-
-       if (string) {
-               for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
-       }
-       i=i+2; /* to count all chars including the leading zero */
-       i=2*i; /* because we need the value in bytes */
-       i=i+4; /* the offset pointer size */
-
-       return i;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-
-uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
-{
-       int size=0;
-
-       size+=size_of_uint32( &info->version ); 
-       size+=size_of_relative_string( &info->name );
-       size+=size_of_relative_string( &info->architecture );
-       size+=size_of_relative_string( &info->driverpath );
-       size+=size_of_relative_string( &info->datafile );
-       size+=size_of_relative_string( &info->configfile );
-       size+=size_of_relative_string( &info->helpfile );
-       size+=size_of_relative_string( &info->monitorname );
-       size+=size_of_relative_string( &info->defaultdatatype );
-       
-       size+=spoolss_size_string_array(info->dependentfiles);
-
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-
-uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
-{
-       uint32 size=0;
-
-       size+=size_of_uint32( &info->version ); 
-       size+=size_of_relative_string( &info->name );
-       size+=size_of_relative_string( &info->architecture );
-       size+=size_of_relative_string( &info->driverpath );
-       size+=size_of_relative_string( &info->datafile );
-       size+=size_of_relative_string( &info->configfile );
-       size+=size_of_relative_string( &info->helpfile );
-
-       size+=spoolss_size_string_array(info->dependentfiles);
-
-       size+=size_of_relative_string( &info->monitorname );
-       size+=size_of_relative_string( &info->defaultdatatype );
-       
-       size+=spoolss_size_string_array(info->previousdrivernames);
-
-       size+=size_of_nttime(&info->driver_date);
-       size+=size_of_uint32( &info->padding ); 
-       size+=size_of_uint32( &info->driver_version_low );      
-       size+=size_of_uint32( &info->driver_version_high );     
-       size+=size_of_relative_string( &info->mfgname );
-       size+=size_of_relative_string( &info->oem_url );
-       size+=size_of_relative_string( &info->hardware_id );
-       size+=size_of_relative_string( &info->provider );
-
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/  
-
-uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
-{
-       int size=0;
-       size+=size_of_uint32( &info->jobid );
-       size+=size_of_relative_string( &info->printername );
-       size+=size_of_relative_string( &info->machinename );
-       size+=size_of_relative_string( &info->username );
-       size+=size_of_relative_string( &info->document );
-       size+=size_of_relative_string( &info->datatype );
-       size+=size_of_relative_string( &info->text_status );
-       size+=size_of_uint32( &info->status );
-       size+=size_of_uint32( &info->priority );
-       size+=size_of_uint32( &info->position );
-       size+=size_of_uint32( &info->totalpages );
-       size+=size_of_uint32( &info->pagesprinted );
-       size+=size_of_systemtime( &info->submitted );
-
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/  
-
-uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
-{
-       int size=0;
-
-       size+=4; /* size of sec desc ptr */
-
-       size+=size_of_uint32( &info->jobid );
-       size+=size_of_relative_string( &info->printername );
-       size+=size_of_relative_string( &info->machinename );
-       size+=size_of_relative_string( &info->username );
-       size+=size_of_relative_string( &info->document );
-       size+=size_of_relative_string( &info->notifyname );
-       size+=size_of_relative_string( &info->datatype );
-       size+=size_of_relative_string( &info->printprocessor );
-       size+=size_of_relative_string( &info->parameters );
-       size+=size_of_relative_string( &info->drivername );
-       size+=size_of_device_mode( info->devmode );
-       size+=size_of_relative_string( &info->text_status );
-/*     SEC_DESC sec_desc;*/
-       size+=size_of_uint32( &info->status );
-       size+=size_of_uint32( &info->priority );
-       size+=size_of_uint32( &info->position );
-       size+=size_of_uint32( &info->starttime );
-       size+=size_of_uint32( &info->untiltime );
-       size+=size_of_uint32( &info->totalpages );
-       size+=size_of_uint32( &info->size );
-       size+=size_of_systemtime( &info->submitted );
-       size+=size_of_uint32( &info->timeelapsed );
-       size+=size_of_uint32( &info->pagesprinted );
-
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/  
-uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
-{
-       uint32  size = 0; 
-       
-       if (!p)
-               return 0;
-       
-       /* uint32(offset) + uint32(length) + length) */
-       size += (size_of_uint32(&p->value_len)*2) + p->value_len;
-       size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
-       
-       size += size_of_uint32(&p->type);
-                      
-       return size;
-}
-
-/*******************************************************************
- * read a structure.
- * called from spoolss_getprinterdriver2 (srv_spoolss.c)
- ********************************************************************/
-
-bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-       
-       if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
-               return False;
-       if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
-               return False;
-       if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
-               return False;
-       
-       if(!prs_align(ps))
-               return False;
-       if(!prs_uint32("level", ps, depth, &q_u->level))
-               return False;
-               
-       if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
-               return False;
-
-       if(!prs_align(ps))
-               return False;
-
-       if(!prs_uint32("offered", ps, depth, &q_u->offered))
-               return False;
-               
-       if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
-               return False;
-       if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- * read a structure.
- * called from spoolss_getprinterdriver2 (srv_spoolss.c)
- ********************************************************************/
-
-bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
-               return False;
-
-       if (!prs_align(ps))
-               return False;
-       if (!prs_uint32("needed", ps, depth, &r_u->needed))
-               return False;
-       if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
-               return False;
-       if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
-               return False;           
-       if (!prs_werror("status", ps, depth, &r_u->status))
-               return False;
-
-       return True;            
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-bool make_spoolss_q_enumprinters(
-       SPOOL_Q_ENUMPRINTERS *q_u, 
-       uint32 flags, 
-       char *servername, 
-       uint32 level, 
-       RPC_BUFFER *buffer, 
-       uint32 offered
-)
-{
-       q_u->flags=flags;
-       
-       q_u->servername_ptr = (servername != NULL) ? 1 : 0;
-       init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
-
-       q_u->level=level;
-       q_u->buffer=buffer;
-       q_u->offered=offered;
-
-       return True;
-}
-
-/*******************************************************************
- * read a structure.
- * called from spoolss_enumprinters (srv_spoolss.c)
- ********************************************************************/
-
-bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-
-       if (!prs_uint32("flags", ps, depth, &q_u->flags))
-               return False;
-       if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
-               return False;
-
-       if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
-               return False;
-               
-       if (!prs_align(ps))
-               return False;
-       if (!prs_uint32("level", ps, depth, &q_u->level))
-               return False;
-
-       if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
-               return False;
-
-       if (!prs_align(ps))
-               return False;
-       if (!prs_uint32("offered", ps, depth, &q_u->offered))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a SPOOL_R_ENUMPRINTERS structure.
- ********************************************************************/
-
-bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
-               return False;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_uint32("needed", ps, depth, &r_u->needed))
-               return False;
-               
-       if (!prs_uint32("returned", ps, depth, &r_u->returned))
-               return False;
-               
-       if (!prs_werror("status", ps, depth, &r_u->status))
-               return False;
-
-       return True;            
-}
-
-/*******************************************************************
- * write a structure.
- * called from spoolss_r_enum_printers (srv_spoolss.c)
- *
- ********************************************************************/
-
-bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
-{      
-       prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
-               return False;
-
-       if (!prs_align(ps))
-               return False;
-
-       if (!prs_uint32("needed", ps, depth, &r_u->needed))
-               return False;
-               
-       if (!prs_werror("status", ps, depth, &r_u->status))
-               return False;
-
-       return True;            
-}
-
-/*******************************************************************
- * read a structure.
- * called from spoolss_getprinter (srv_spoolss.c)
- ********************************************************************/
-
-bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-
-       if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
-               return False;
-       if (!prs_uint32("level", ps, depth, &q_u->level))
-               return False;
-
-       if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
-               return False;
-
-       if (!prs_align(ps))
-               return False;
-       if (!prs_uint32("offered", ps, depth, &q_u->offered))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
-{              
-       prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
-               return False;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_uint32("needed", ps, depth, &r_u->needed))
-               return False;
-               
-       if (!prs_uint32("returned", ps, depth, &r_u->returned))
-               return False;
-               
-       if (!prs_werror("status", ps, depth, &r_u->status))
-               return False;
-
-       return True;            
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
-                               uint32 firstjob,
-                               uint32 numofjobs,
-                               uint32 level,
-                               RPC_BUFFER *buffer,
-                               uint32 offered)
-{
-       if (q_u == NULL)
-       {
-               return False;
-       }
-       memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
-       q_u->firstjob = firstjob;
-       q_u->numofjobs = numofjobs;
-       q_u->level = level;
-       q_u->buffer= buffer;
-       q_u->offered = offered;
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-
-       if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
-               return False;
-               
-       if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
-               return False;
-       if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
-               return False;
-       if (!prs_uint32("level", ps, depth, &q_u->level))
-               return False;
-
-       if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
-               return False;   
-
-       if(!prs_align(ps))
-               return False;
-
-       if (!prs_uint32("offered", ps, depth, &q_u->offered))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
-********************************************************************/  
-
-bool spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
-               return False;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_uint32("needed", ps, depth, &r_u->needed))
-               return False;
-               
-       if (!prs_uint32("returned", ps, depth, &r_u->returned))
-               return False;
-               
-       if (!prs_werror("status", ps, depth, &r_u->status))
-               return False;
-
-       return True;            
-}
-
-/*******************************************************************
- * init a structure.
+ * return the length of a uint32 (obvious, but the code is clean)
  ********************************************************************/
 
-bool make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
-                                const char *name,
-                                const char *environment,
-                                uint32 level,
-                                RPC_BUFFER *buffer, uint32 offered)
+static uint32 size_of_uint32(uint32 *value)
 {
-        init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
-        init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
-
-        q_u->level=level;
-        q_u->buffer=buffer;
-        q_u->offered=offered;
-
-        return True;
+       return (sizeof(*value));
 }
 
 /*******************************************************************
- Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
+return the size required by a struct in the stream
 ********************************************************************/  
-
-bool spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
+uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
 {
-
-       prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
-               return False;
-       if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
-               return False;
-               
-       if (!prs_align(ps))
-               return False;
-       if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
-               return False;
-       if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
-               return False;
-               
-       if (!prs_align(ps))
-               return False;
-       if (!prs_uint32("level", ps, depth, &q_u->level))
-               return False;
-               
-       if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
-               return False;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_uint32("offered", ps, depth, &q_u->offered))
-               return False;
-
-       return True;
+       uint32  size = 0; 
+       
+       if (!p)
+               return 0;
+       
+       /* uint32(offset) + uint32(length) + length) */
+       size += (size_of_uint32(&p->value_len)*2) + p->value_len;
+       size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
+       
+       size += size_of_uint32(&p->type);
+                      
+       return size;
 }
 
 /*******************************************************************
@@ -2072,117 +586,6 @@ bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u,
        return True;
 }
 
-/*******************************************************************
- Parse a SPOOL_R_GETJOB structure.
-********************************************************************/  
-
-bool spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
-{              
-       prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
-               return False;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_uint32("needed", ps, depth, &r_u->needed))
-               return False;
-               
-       if (!prs_werror("status", ps, depth, &r_u->status))
-               return False;
-
-       return True;            
-}
-
-/*******************************************************************
- Parse a SPOOL_Q_GETJOB structure.
-********************************************************************/  
-
-bool spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-
-       if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
-               return False;
-       if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
-               return False;
-       if(!prs_uint32("level", ps, depth, &q_u->level))
-               return False;
-       
-       if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
-               return False;
-
-       if(!prs_align(ps))
-               return False;
-       
-       if(!prs_uint32("offered", ps, depth, &q_u->offered))
-               return False;
-
-       return True;
-}
-
-void free_devmode(DEVICEMODE *devmode)
-{
-       if (devmode!=NULL) {
-               SAFE_FREE(devmode->dev_private);
-               SAFE_FREE(devmode);
-       }
-}
-
-void free_printer_info_1(PRINTER_INFO_1 *printer)
-{
-       SAFE_FREE(printer);
-}
-
-void free_printer_info_2(PRINTER_INFO_2 *printer)
-{
-       if (printer!=NULL) {
-               free_devmode(printer->devmode);
-               printer->devmode = NULL;
-               SAFE_FREE(printer);
-       }
-}
-
-void free_printer_info_3(PRINTER_INFO_3 *printer)
-{
-       SAFE_FREE(printer);
-}
-
-void free_printer_info_4(PRINTER_INFO_4 *printer)
-{
-       SAFE_FREE(printer);
-}
-
-void free_printer_info_5(PRINTER_INFO_5 *printer)
-{
-       SAFE_FREE(printer);
-}
-
-void free_printer_info_6(PRINTER_INFO_6 *printer)
-{
-       SAFE_FREE(printer);
-}
-
-void free_printer_info_7(PRINTER_INFO_7 *printer)
-{
-       SAFE_FREE(printer);
-}
-
-void free_job_info_2(JOB_INFO_2 *job)
-{
-    if (job!=NULL)
-        free_devmode(job->devmode);
-}
-
 /*******************************************************************
  * read a structure.
  ********************************************************************/  
index 616eb1dbf01070c73770897fd9cdb4466cc29a1e..da8220232bb1c4e3cf247580801dfaba12eb906d 100644 (file)
@@ -190,27 +190,7 @@ static bool api_spoolss_rfnpcnex(pipes_struct *p)
 
 static bool api_spoolss_enumprinters(pipes_struct *p)
 {
-       SPOOL_Q_ENUMPRINTERS q_u;
-       SPOOL_R_ENUMPRINTERS r_u;
-       prs_struct *data = &p->in_data.data;
-       prs_struct *rdata = &p->out_data.rdata;
-
-       ZERO_STRUCT(q_u);
-       ZERO_STRUCT(r_u);
-
-       if (!spoolss_io_q_enumprinters("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_enumprinters: unable to unmarshall SPOOL_Q_ENUMPRINTERS.\n"));
-               return False;
-       }
-
-       r_u.status = _spoolss_enumprinters( p, &q_u, &r_u);
-
-       if (!spoolss_io_r_enumprinters("", &r_u, rdata, 0)) {
-               DEBUG(0,("spoolss_io_r_enumprinters: unable to marshall SPOOL_R_ENUMPRINTERS.\n"));
-               return False;
-       }
-
-       return True;
+       return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMPRINTERS);
 }
 
 /********************************************************************
@@ -221,27 +201,7 @@ static bool api_spoolss_enumprinters(pipes_struct *p)
 
 static bool api_spoolss_getprinter(pipes_struct *p)
 {
-       SPOOL_Q_GETPRINTER q_u;
-       SPOOL_R_GETPRINTER r_u;
-       prs_struct *data = &p->in_data.data;
-       prs_struct *rdata = &p->out_data.rdata;
-
-       ZERO_STRUCT(q_u);
-       ZERO_STRUCT(r_u);
-
-       if(!spoolss_io_q_getprinter("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_getprinter: unable to unmarshall SPOOL_Q_GETPRINTER.\n"));
-               return False;
-       }
-
-       r_u.status = _spoolss_getprinter(p, &q_u, &r_u);
-
-       if(!spoolss_io_r_getprinter("",&r_u,rdata,0)) {
-               DEBUG(0,("spoolss_io_r_getprinter: unable to marshall SPOOL_R_GETPRINTER.\n"));
-               return False;
-       }
-
-       return True;
+       return proxy_spoolss_call(p, NDR_SPOOLSS_GETPRINTER);
 }
 
 /********************************************************************
@@ -252,27 +212,7 @@ static bool api_spoolss_getprinter(pipes_struct *p)
 
 static bool api_spoolss_getprinterdriver2(pipes_struct *p)
 {
-       SPOOL_Q_GETPRINTERDRIVER2 q_u;
-       SPOOL_R_GETPRINTERDRIVER2 r_u;
-       prs_struct *data = &p->in_data.data;
-       prs_struct *rdata = &p->out_data.rdata;
-
-       ZERO_STRUCT(q_u);
-       ZERO_STRUCT(r_u);
-
-       if(!spoolss_io_q_getprinterdriver2("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_getprinterdriver2: unable to unmarshall SPOOL_Q_GETPRINTERDRIVER2.\n"));
-               return False;
-       }
-
-       r_u.status = _spoolss_getprinterdriver2(p, &q_u, &r_u);
-       
-       if(!spoolss_io_r_getprinterdriver2("",&r_u,rdata,0)) {
-               DEBUG(0,("spoolss_io_r_getprinterdriver2: unable to marshall SPOOL_R_GETPRINTERDRIVER2.\n"));
-               return False;
-       }
-       
-       return True;
+       return proxy_spoolss_call(p, NDR_SPOOLSS_GETPRINTERDRIVER2);
 }
 
 /********************************************************************
@@ -351,27 +291,7 @@ static bool api_spoolss_addjob(pipes_struct *p)
 
 static bool api_spoolss_enumjobs(pipes_struct *p)
 {
-       SPOOL_Q_ENUMJOBS q_u;
-       SPOOL_R_ENUMJOBS r_u;
-       prs_struct *data = &p->in_data.data;
-       prs_struct *rdata = &p->out_data.rdata;
-
-       ZERO_STRUCT(q_u);
-       ZERO_STRUCT(r_u);
-
-       if (!spoolss_io_q_enumjobs("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_enumjobs: unable to unmarshall SPOOL_Q_ENUMJOBS.\n"));
-               return False;
-       }
-
-       r_u.status = _spoolss_enumjobs(p, &q_u, &r_u);
-
-       if (!spoolss_io_r_enumjobs("",&r_u,rdata,0)) {
-               DEBUG(0,("spoolss_io_r_enumjobs: unable to marshall SPOOL_R_ENUMJOBS.\n"));
-               return False;
-       }
-
-       return True;
+       return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMJOBS);
 }
 
 /****************************************************************************
@@ -395,27 +315,7 @@ static bool api_spoolss_setjob(pipes_struct *p)
 
 static bool api_spoolss_enumprinterdrivers(pipes_struct *p)
 {
-       SPOOL_Q_ENUMPRINTERDRIVERS q_u;
-       SPOOL_R_ENUMPRINTERDRIVERS r_u;
-       prs_struct *data = &p->in_data.data;
-       prs_struct *rdata = &p->out_data.rdata;
-
-       ZERO_STRUCT(q_u);
-       ZERO_STRUCT(r_u);
-
-       if (!spoolss_io_q_enumprinterdrivers("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_enumprinterdrivers: unable to unmarshall SPOOL_Q_ENUMPRINTERDRIVERS.\n"));
-               return False;
-       }
-
-       r_u.status = _spoolss_enumprinterdrivers(p, &q_u, &r_u);
-
-       if (!spoolss_io_r_enumprinterdrivers("",&r_u,rdata,0)) {
-               DEBUG(0,("spoolss_io_r_enumprinterdrivers: unable to marshall SPOOL_R_ENUMPRINTERDRIVERS.\n"));
-               return False;
-       }
-
-       return True;
+       return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMPRINTERDRIVERS);
 }
 
 /****************************************************************************
@@ -589,27 +489,7 @@ static bool api_spoolss_enumprintmonitors(pipes_struct *p)
 
 static bool api_spoolss_getjob(pipes_struct *p)
 {
-       SPOOL_Q_GETJOB q_u;
-       SPOOL_R_GETJOB r_u;
-       prs_struct *data = &p->in_data.data;
-       prs_struct *rdata = &p->out_data.rdata;
-       
-       ZERO_STRUCT(q_u);
-       ZERO_STRUCT(r_u);
-       
-       if(!spoolss_io_q_getjob("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_getjob: unable to unmarshall SPOOL_Q_GETJOB.\n"));
-               return False;
-       }
-
-       r_u.status = _spoolss_getjob(p, &q_u, &r_u);
-       
-       if(!spoolss_io_r_getjob("",&r_u,rdata,0)) {
-               DEBUG(0,("spoolss_io_r_getjob: unable to marshall SPOOL_R_GETJOB.\n"));
-               return False;
-       }
-               
-       return True;
+       return proxy_spoolss_call(p, NDR_SPOOLSS_GETJOB);
 }
 
 /********************************************************************
index 0a4f5ae05ce6688f32be454b1810f665eb64c787..950dc013b2dd079df17ddd2e19a326b0f8fd3ecf 100644 (file)
 
 #include "includes.h"
 
+/* macros stolen from s4 spoolss server */
+#define SPOOLSS_BUFFER_UNION(fn,ic,info,level) \
+       ((info)?ndr_size_##fn(info, level, ic, 0):0)
+
+#define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,ic,info,level,count) \
+       ((info)?ndr_size_##fn##_info(mem_ctx, ic, level, count, info):0)
+
+#define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
+
+
 extern userdom_struct current_user_info;
 
 #undef DBGC_CLASS
@@ -3914,149 +3924,81 @@ done:
  * fill a printer_info_0 struct
  ********************************************************************/
 
-static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
+static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
+                                     const NT_PRINTER_INFO_LEVEL *ntprinter,
+                                     struct spoolss_PrinterInfo0 *r,
+                                     int snum)
 {
-       char *chaine = NULL;
        int count;
-       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
        counter_printer_0 *session_counter;
-       uint32 global_counter;
-       struct tm *t;
        time_t setuptime;
        print_status_struct status;
-       TALLOC_CTX *ctx = talloc_tos();
 
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
-               return False;
-
-       init_unistr(&printer->printername, ntprinter->info_2->printername);
+       r->printername          = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
+       W_ERROR_HAVE_NO_MEMORY(r->printername);
 
-       chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
-       if (!chaine) {
-               free_a_printer(&ntprinter,2);
-               return false;
-       }
+       r->servername           = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
+       W_ERROR_HAVE_NO_MEMORY(r->servername);
 
        count = print_queue_length(snum, &status);
 
        /* check if we already have a counter for this printer */
-       for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
+       for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
                if (session_counter->snum == snum)
                        break;
        }
 
-       init_unistr(&printer->servername, chaine);
-
        /* it's the first time, add it to the list */
-       if (session_counter==NULL) {
-               if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
-                       free_a_printer(&ntprinter, 2);
-                       return False;
-               }
+       if (session_counter == NULL) {
+               session_counter = SMB_MALLOC_P(counter_printer_0);
+               W_ERROR_HAVE_NO_MEMORY(session_counter);
                ZERO_STRUCTP(session_counter);
-               session_counter->snum=snum;
-               session_counter->counter=0;
+               session_counter->snum           = snum;
+               session_counter->counter        = 0;
                DLIST_ADD(counter_list, session_counter);
        }
 
        /* increment it */
        session_counter->counter++;
 
-       /* JFM:
-        * the global_counter should be stored in a TDB as it's common to all the clients
-        * and should be zeroed on samba startup
-        */
-       global_counter=session_counter->counter;
-       printer->cjobs = count;
-       printer->total_jobs = 0;
-       printer->total_bytes = 0;
+       r->cjobs                        = count;
+       r->total_jobs                   = 0;
+       r->total_bytes                  = 0;
 
        setuptime = (time_t)ntprinter->info_2->setuptime;
-       t=gmtime(&setuptime);
 
-       printer->year = t->tm_year+1900;
-       printer->month = t->tm_mon+1;
-       printer->dayofweek = t->tm_wday;
-       printer->day = t->tm_mday;
-       printer->hour = t->tm_hour;
-       printer->minute = t->tm_min;
-       printer->second = t->tm_sec;
-       printer->milliseconds = 0;
-
-       printer->global_counter = global_counter;
-       printer->total_pages = 0;
+       init_systemtime(&r->time, gmtime(&setuptime));
 
+       /* JFM:
+        * the global_counter should be stored in a TDB as it's common to all the clients
+        * and should be zeroed on samba startup
+        */
+       r->global_counter               = session_counter->counter;
+       r->total_pages                  = 0;
        /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
-       printer->major_version = 0x0005;        /* NT 5 */
-       printer->build_version = 0x0893;        /* build 2195 */
-
-       printer->unknown7 = 0x1;
-       printer->unknown8 = 0x0;
-       printer->unknown9 = 0x0;
-       printer->session_counter = session_counter->counter;
-       printer->unknown11 = 0x0;
-       printer->printer_errors = 0x0;          /* number of print failure */
-       printer->unknown13 = 0x0;
-       printer->unknown14 = 0x1;
-       printer->unknown15 = 0x024a;            /* 586 Pentium ? */
-       printer->unknown16 =  0x0;
-       printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
-       printer->unknown18 =  0x0;
-       printer->status = nt_printq_status(status.status);
-       printer->unknown20 =  0x0;
-       printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
-       printer->unknown22 = 0x0;
-       printer->unknown23 = 0x6;               /* 6  ???*/
-       printer->unknown24 = 0;                 /* unknown 24 to 26 are always 0 */
-       printer->unknown25 = 0;
-       printer->unknown26 = 0;
-       printer->unknown27 = 0;
-       printer->unknown28 = 0;
-       printer->unknown29 = 0;
-
-       free_a_printer(&ntprinter,2);
-       return (True);
-}
-
-/********************************************************************
- * construct_printer_info_1
- * fill a printer_info_1 struct
- ********************************************************************/
-static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
-{
-       char *chaine = NULL;
-       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
-       TALLOC_CTX *ctx = talloc_tos();
-
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
-               return false;
-
-       printer->flags=flags;
-
-       if (*ntprinter->info_2->comment == '\0') {
-               init_unistr(&printer->comment, lp_comment(snum));
-               chaine = talloc_asprintf(ctx,
-                               "%s,%s,%s", ntprinter->info_2->printername,
-                               ntprinter->info_2->drivername, lp_comment(snum));
-       }
-       else {
-               init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
-               chaine = talloc_asprintf(ctx,
-                               "%s,%s,%s", ntprinter->info_2->printername,
-                               ntprinter->info_2->drivername, ntprinter->info_2->comment);
-       }
-
-       if (!chaine) {
-               free_a_printer(&ntprinter,2);
-               return false;
-       }
-
-       init_unistr(&printer->description, chaine);
-       init_unistr(&printer->name, ntprinter->info_2->printername);
+       r->version                      = 0x0005;       /* NT 5 */
+       r->free_build                   = 0x0893;       /* build 2195 */
+       r->spooling                     = 0;
+       r->max_spooling                 = 0;
+       r->session_counter              = session_counter->counter;
+       r->num_error_out_of_paper       = 0x0;
+       r->num_error_not_ready          = 0x0;          /* number of print failure */
+       r->job_error                    = 0x0;
+       r->number_of_processors         = 0x1;
+       r->processor_type               = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
+       r->high_part_total_bytes        = 0x0;
+       r->change_id                    = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
+       r->last_error                   = WERR_OK;
+       r->status                       = nt_printq_status(status.status);
+       r->enumerate_network_printers   = 0x0;
+       r->c_setprinter                 = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
+       r->processor_architecture       = 0x0;
+       r->processor_level              = 0x6;          /* 6  ???*/
+       r->ref_ic                       = 0;
+       r->reserved2                    = 0;
+       r->reserved3                    = 0;
 
-       free_a_printer(&ntprinter,2);
-
-       return True;
+       return WERR_OK;
 }
 
 /****************************************************************************
@@ -4072,6 +4014,73 @@ static void free_dev_mode(DEVICEMODE *dev)
        SAFE_FREE(dev);
 }
 
+/****************************************************************************
+ Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure.  Both pointers
+ should be valid upon entry
+****************************************************************************/
+
+static WERROR convert_nt_devicemode_new(TALLOC_CTX *mem_ctx,
+                                       struct spoolss_DeviceMode *r,
+                                       const NT_DEVICEMODE *ntdevmode)
+{
+       if (!r || !ntdevmode) {
+               return WERR_INVALID_PARAM;
+       }
+
+       r->devicename           = talloc_strdup(mem_ctx, ntdevmode->devicename);
+       W_ERROR_HAVE_NO_MEMORY(r->devicename);
+
+       r->specversion          = ntdevmode->specversion;
+       r->driverversion        = ntdevmode->driverversion;
+       r->size                 = ntdevmode->size;
+       r->__driverextra_length = ntdevmode->driverextra;
+       r->fields               = ntdevmode->fields;
+
+       r->orientation          = ntdevmode->orientation;
+       r->papersize            = ntdevmode->papersize;
+       r->paperlength          = ntdevmode->paperlength;
+       r->paperwidth           = ntdevmode->paperwidth;
+       r->scale                = ntdevmode->scale;
+       r->copies               = ntdevmode->copies;
+       r->defaultsource        = ntdevmode->defaultsource;
+       r->printquality         = ntdevmode->printquality;
+       r->color                = ntdevmode->color;
+       r->duplex               = ntdevmode->duplex;
+       r->yresolution          = ntdevmode->yresolution;
+       r->ttoption             = ntdevmode->ttoption;
+       r->collate              = ntdevmode->collate;
+
+       r->formname             = talloc_strdup(mem_ctx, ntdevmode->formname);
+       W_ERROR_HAVE_NO_MEMORY(r->formname);
+
+       /* all 0 below are values that have not been set in the old parsing/copy
+        * function, maybe they should... - gd */
+
+       r->logpixels            = 0;
+       r->bitsperpel           = 0;
+       r->pelswidth            = 0;
+       r->pelsheight           = 0;
+       r->displayflags         = 0;
+       r->displayfrequency     = 0;
+       r->icmmethod            = ntdevmode->icmmethod;
+       r->icmintent            = ntdevmode->icmintent;
+       r->mediatype            = ntdevmode->mediatype;
+       r->dithertype           = ntdevmode->dithertype;
+       r->reserved1            = 0;
+       r->reserved2            = 0;
+       r->panningwidth         = 0;
+       r->panningheight        = 0;
+
+       if (ntdevmode->nt_dev_private != NULL) {
+               r->driverextra_data = data_blob_talloc(mem_ctx,
+                       ntdevmode->nt_dev_private,
+                       ntdevmode->driverextra);
+               W_ERROR_HAVE_NO_MEMORY(r->driverextra_data.data);
+       }
+
+       return WERR_OK;
+}
+
 
 /****************************************************************************
  Convert an NT_DEVICEMODE to a DEVICEMODE structure.  Both pointers
@@ -4120,38 +4129,39 @@ static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode
 }
 
 /****************************************************************************
- Create a DEVMODE struct. Returns malloced memory.
+ Create a spoolss_DeviceMode struct. Returns talloced memory.
 ****************************************************************************/
 
-DEVICEMODE *construct_dev_mode(const char *servicename)
+struct spoolss_DeviceMode *construct_dev_mode_new(TALLOC_CTX *mem_ctx,
+                                                 const char *servicename)
 {
+       WERROR result;
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
-       DEVICEMODE              *devmode = NULL;
+       struct spoolss_DeviceMode *devmode = NULL;
 
-       DEBUG(7,("construct_dev_mode\n"));
+       DEBUG(7,("construct_dev_mode_new\n"));
 
        DEBUGADD(8,("getting printer characteristics\n"));
 
        if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
                return NULL;
 
-       if ( !printer->info_2->devmode ) {
+       if (!printer->info_2->devmode) {
                DEBUG(5, ("BONG! There was no device mode!\n"));
                goto done;
        }
 
-       if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
-               DEBUG(2,("construct_dev_mode: malloc fail.\n"));
+       devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
+       if (!devmode) {
+               DEBUG(2,("construct_dev_mode_new: talloc fail.\n"));
                goto done;
        }
 
-       ZERO_STRUCTP(devmode);
-
        DEBUGADD(8,("loading DEVICEMODE\n"));
 
-       if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
-               free_dev_mode( devmode );
-               devmode = NULL;
+       result = convert_nt_devicemode_new(mem_ctx, devmode, printer->info_2->devmode);
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(devmode);
        }
 
 done:
@@ -4160,321 +4170,400 @@ done:
        return devmode;
 }
 
-/********************************************************************
- * construct_printer_info_2
- * fill a printer_info_2 struct
- ********************************************************************/
+/****************************************************************************
+ Create a DEVMODE struct. Returns malloced memory.
+****************************************************************************/
 
-static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
+DEVICEMODE *construct_dev_mode(const char *servicename)
 {
-       int count;
-       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
-
-       print_status_struct status;
-
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
-               return False;
-
-       count = print_queue_length(snum, &status);
-
-       init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
-       init_unistr(&printer->printername, ntprinter->info_2->printername);                             /* printername*/
-       init_unistr(&printer->sharename, lp_servicename(snum));                 /* sharename */
-       init_unistr(&printer->portname, ntprinter->info_2->portname);                   /* port */
-       init_unistr(&printer->drivername, ntprinter->info_2->drivername);       /* drivername */
+       NT_PRINTER_INFO_LEVEL   *printer = NULL;
+       DEVICEMODE              *devmode = NULL;
 
-       if (*ntprinter->info_2->comment == '\0')
-               init_unistr(&printer->comment, lp_comment(snum));                       /* comment */
-       else
-               init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
+       DEBUG(7,("construct_dev_mode\n"));
 
-       init_unistr(&printer->location, ntprinter->info_2->location);           /* location */
-       init_unistr(&printer->sepfile, ntprinter->info_2->sepfile);             /* separator file */
-       init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
-       init_unistr(&printer->datatype, ntprinter->info_2->datatype);           /* datatype */
-       init_unistr(&printer->parameters, ntprinter->info_2->parameters);       /* parameters (of print processor) */
+       DEBUGADD(8,("getting printer characteristics\n"));
 
-       printer->attributes = ntprinter->info_2->attributes;
+       if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
+               return NULL;
 
-       printer->priority = ntprinter->info_2->priority;                                /* priority */
-       printer->defaultpriority = ntprinter->info_2->default_priority;         /* default priority */
-       printer->starttime = ntprinter->info_2->starttime;                      /* starttime */
-       printer->untiltime = ntprinter->info_2->untiltime;                      /* untiltime */
-       printer->status = nt_printq_status(status.status);                      /* status */
-       printer->cjobs = count;                                                 /* jobs */
-       printer->averageppm = ntprinter->info_2->averageppm;                    /* average pages per minute */
+       if ( !printer->info_2->devmode ) {
+               DEBUG(5, ("BONG! There was no device mode!\n"));
+               goto done;
+       }
 
-       if ( !(printer->devmode = construct_dev_mode(
-                      lp_const_servicename(snum))) )
-               DEBUG(8, ("Returning NULL Devicemode!\n"));
+       if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
+               DEBUG(2,("construct_dev_mode: malloc fail.\n"));
+               goto done;
+       }
 
-       printer->secdesc = NULL;
+       ZERO_STRUCTP(devmode);
 
-       if ( ntprinter->info_2->secdesc_buf
-               && ntprinter->info_2->secdesc_buf->sd_size != 0 )
-       {
-               /* don't use talloc_steal() here unless you do a deep steal of all
-                  the SEC_DESC members */
+       DEBUGADD(8,("loading DEVICEMODE\n"));
 
-               printer->secdesc = dup_sec_desc( talloc_tos(),
-                       ntprinter->info_2->secdesc_buf->sd );
+       if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
+               free_dev_mode( devmode );
+               devmode = NULL;
        }
 
-       free_a_printer(&ntprinter, 2);
+done:
+       free_a_printer(&printer,2);
 
-       return True;
+       return devmode;
 }
 
 /********************************************************************
- * construct_printer_info_3
- * fill a printer_info_3 struct
+ * construct_printer_info3
+ * fill a spoolss_PrinterInfo3 struct
  ********************************************************************/
 
-static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
+static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
+                                     const NT_PRINTER_INFO_LEVEL *ntprinter,
+                                     struct spoolss_PrinterInfo3 *r,
+                                     int snum)
 {
-       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
-       PRINTER_INFO_3 *printer = NULL;
-
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
-               return False;
-
-       *pp_printer = NULL;
-       if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
-               DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
-               free_a_printer(&ntprinter, 2);
-               return False;
-       }
-
-       ZERO_STRUCTP(printer);
-
        /* These are the components of the SD we are returning. */
 
        if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
                /* don't use talloc_steal() here unless you do a deep steal of all
                   the SEC_DESC members */
 
-               printer->secdesc = dup_sec_desc( talloc_tos(),
-                       ntprinter->info_2->secdesc_buf->sd );
+               r->secdesc = dup_sec_desc(mem_ctx,
+                                         ntprinter->info_2->secdesc_buf->sd);
+               W_ERROR_HAVE_NO_MEMORY(r->secdesc);
        }
 
-       free_a_printer(&ntprinter, 2);
-
-       *pp_printer = printer;
-       return True;
+       return WERR_OK;
 }
 
 /********************************************************************
- * construct_printer_info_4
- * fill a printer_info_4 struct
+ * construct_printer_info4
+ * fill a spoolss_PrinterInfo4 struct
  ********************************************************************/
 
-static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
+static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
+                                     const NT_PRINTER_INFO_LEVEL *ntprinter,
+                                     struct spoolss_PrinterInfo4 *r,
+                                     int snum)
 {
-       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
-
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
-               return False;
+       r->printername  = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
+       W_ERROR_HAVE_NO_MEMORY(r->printername);
+       r->servername   = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
+       W_ERROR_HAVE_NO_MEMORY(r->servername);
 
-       init_unistr(&printer->printername, ntprinter->info_2->printername);                             /* printername*/
-       init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
-       printer->attributes = ntprinter->info_2->attributes;
+       r->attributes   = ntprinter->info_2->attributes;
 
-       free_a_printer(&ntprinter, 2);
-       return True;
+       return WERR_OK;
 }
 
 /********************************************************************
- * construct_printer_info_5
- * fill a printer_info_5 struct
+ * construct_printer_info5
+ * fill a spoolss_PrinterInfo5 struct
  ********************************************************************/
 
-static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
+static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
+                                     const NT_PRINTER_INFO_LEVEL *ntprinter,
+                                     struct spoolss_PrinterInfo5 *r,
+                                     int snum)
 {
-       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+       r->printername  = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
+       W_ERROR_HAVE_NO_MEMORY(r->printername);
+       r->portname     = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
+       W_ERROR_HAVE_NO_MEMORY(r->portname);
 
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
-               return False;
-
-       init_unistr(&printer->printername, ntprinter->info_2->printername);
-       init_unistr(&printer->portname, ntprinter->info_2->portname);
-       printer->attributes = ntprinter->info_2->attributes;
+       r->attributes   = ntprinter->info_2->attributes;
 
        /* these two are not used by NT+ according to MSDN */
 
-       printer->device_not_selected_timeout = 0x0;  /* have seen 0x3a98 */
-       printer->transmission_retry_timeout  = 0x0;  /* have seen 0xafc8 */
-
-       free_a_printer(&ntprinter, 2);
+       r->device_not_selected_timeout          = 0x0;  /* have seen 0x3a98 */
+       r->transmission_retry_timeout           = 0x0;  /* have seen 0xafc8 */
 
-       return True;
+       return WERR_OK;
 }
 
 /********************************************************************
  * construct_printer_info_6
- * fill a printer_info_6 struct
+ * fill a spoolss_PrinterInfo6 struct
  ********************************************************************/
 
-static bool construct_printer_info_6(Printer_entry *print_hnd,
-                                    PRINTER_INFO_6 *printer,
-                                    int snum)
+static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
+                                     const NT_PRINTER_INFO_LEVEL *ntprinter,
+                                     struct spoolss_PrinterInfo6 *r,
+                                     int snum)
 {
-       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
        int count;
        print_status_struct status;
 
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
-                                        lp_const_servicename(snum))))
-               return False;
-
        count = print_queue_length(snum, &status);
 
-       printer->status = nt_printq_status(status.status);
-
-       free_a_printer(&ntprinter, 2);
+       r->status = nt_printq_status(status.status);
 
-       return True;
+       return WERR_OK;
 }
 
 /********************************************************************
- * construct_printer_info_7
- * fill a printer_info_7 struct
+ * construct_printer_info7
+ * fill a spoolss_PrinterInfo7 struct
  ********************************************************************/
 
-static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
+static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
+                                     Printer_entry *print_hnd,
+                                     struct spoolss_PrinterInfo7 *r,
+                                     int snum)
 {
-       char *guid_str = NULL;
        struct GUID guid;
 
        if (is_printer_published(print_hnd, snum, &guid)) {
-               if (asprintf(&guid_str, "{%s}",
-                            GUID_string(talloc_tos(), &guid)) == -1) {
-                       return false;
-               }
-               strupper_m(guid_str);
-               init_unistr(&printer->guid, guid_str);
-               SAFE_FREE(guid_str);
-               printer->action = DSPRINT_PUBLISH;
+               r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
+               r->action = DSPRINT_PUBLISH;
        } else {
-               init_unistr(&printer->guid, "");
-               printer->action = DSPRINT_UNPUBLISH;
+               r->guid = talloc_strdup(mem_ctx, "");
+               r->action = DSPRINT_UNPUBLISH;
        }
+       W_ERROR_HAVE_NO_MEMORY(r->guid);
 
-       return True;
+       return WERR_OK;
 }
 
 /********************************************************************
- Spoolss_enumprinters.
+ * construct_printer_info1
+ * fill a spoolss_PrinterInfo1 struct
 ********************************************************************/
 
-static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
+                                     const NT_PRINTER_INFO_LEVEL *ntprinter,
+                                     uint32_t flags,
+                                     struct spoolss_PrinterInfo1 *r,
+                                     int snum)
 {
-       int snum;
-       int i;
-       int n_services=lp_numservices();
-       PRINTER_INFO_1 *printers=NULL;
-       PRINTER_INFO_1 current_prt;
-       WERROR result = WERR_OK;
+       char *chaine = NULL;
+       r->flags                = flags;
 
-       DEBUG(4,("enum_all_printers_info_1\n"));
+       if (*ntprinter->info_2->comment == '\0') {
+               r->comment      = talloc_strdup(mem_ctx, lp_comment(snum));
+               chaine = talloc_asprintf(mem_ctx,
+                               "%s,%s,%s", ntprinter->info_2->printername,
+                               ntprinter->info_2->drivername, lp_comment(snum));
+       } else {
+               r->comment      = talloc_strdup(mem_ctx, ntprinter->info_2->comment); /* saved comment */
+               chaine = talloc_asprintf(mem_ctx,
+                               "%s,%s,%s", ntprinter->info_2->printername,
+                               ntprinter->info_2->drivername, ntprinter->info_2->comment);
+       }
+       W_ERROR_HAVE_NO_MEMORY(chaine);
+       W_ERROR_HAVE_NO_MEMORY(r->comment);
 
-       for (snum=0; snum<n_services; snum++) {
-               if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
-                       DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
-
-                       if (construct_printer_info_1(NULL, flags, &current_prt, snum)) {
-                               if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
-                                       DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
-                                       *returned=0;
-                                       return WERR_NOMEM;
-                               }
-                               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
+       r->description          = talloc_strdup(mem_ctx, chaine);
+       W_ERROR_HAVE_NO_MEMORY(r->description);
+       r->name                 = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
+       W_ERROR_HAVE_NO_MEMORY(r->name);
 
-                               memcpy(&printers[*returned], &current_prt, sizeof(PRINTER_INFO_1));
-                               (*returned)++;
-                       }
-               }
-       }
+       return WERR_OK;
+}
 
-       /* check the required size. */
-       for (i=0; i<*returned; i++)
-               (*needed) += spoolss_size_printer_info_1(&printers[i]);
+/********************************************************************
+ * construct_printer_info2
+ * fill a spoolss_PrinterInfo2 struct
+********************************************************************/
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
+static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
+                                     const NT_PRINTER_INFO_LEVEL *ntprinter,
+                                     struct spoolss_PrinterInfo2 *r,
+                                     int snum)
+{
+       int count;
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+       print_status_struct status;
+
+       count = print_queue_length(snum, &status);
+
+       r->servername           = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
+       W_ERROR_HAVE_NO_MEMORY(r->servername);
+       r->printername          = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
+       W_ERROR_HAVE_NO_MEMORY(r->printername);
+       r->sharename            = talloc_strdup(mem_ctx, lp_servicename(snum));
+       W_ERROR_HAVE_NO_MEMORY(r->sharename);
+       r->portname             = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
+       W_ERROR_HAVE_NO_MEMORY(r->portname);
+       r->drivername           = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
+       W_ERROR_HAVE_NO_MEMORY(r->drivername);
+
+       if (*ntprinter->info_2->comment == '\0') {
+               r->comment      = talloc_strdup(mem_ctx, lp_comment(snum));
+       } else {
+               r->comment      = talloc_strdup(mem_ctx, ntprinter->info_2->comment);
        }
+       W_ERROR_HAVE_NO_MEMORY(r->comment);
 
-       /* fill the buffer with the structures */
-       for (i=0; i<*returned; i++)
-               smb_io_printer_info_1("", buffer, &printers[i], 0);
+       r->location             = talloc_strdup(mem_ctx, ntprinter->info_2->location);
+       W_ERROR_HAVE_NO_MEMORY(r->location);
+       r->sepfile              = talloc_strdup(mem_ctx, ntprinter->info_2->sepfile);
+       W_ERROR_HAVE_NO_MEMORY(r->sepfile);
+       r->printprocessor       = talloc_strdup(mem_ctx, ntprinter->info_2->printprocessor);
+       W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
+       r->datatype             = talloc_strdup(mem_ctx, ntprinter->info_2->datatype);
+       W_ERROR_HAVE_NO_MEMORY(r->datatype);
+       r->parameters           = talloc_strdup(mem_ctx, ntprinter->info_2->parameters);
+       W_ERROR_HAVE_NO_MEMORY(r->parameters);
 
-out:
-       /* clear memory */
+       r->attributes           = ntprinter->info_2->attributes;
 
-       SAFE_FREE(printers);
+       r->priority             = ntprinter->info_2->priority;
+       r->defaultpriority      = ntprinter->info_2->default_priority;
+       r->starttime            = ntprinter->info_2->starttime;
+       r->untiltime            = ntprinter->info_2->untiltime;
+       r->status               = nt_printq_status(status.status);
+       r->cjobs                = count;
+       r->averageppm           = ntprinter->info_2->averageppm;
 
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+       r->devmode = construct_dev_mode_new(mem_ctx, lp_const_servicename(snum));
+       if (!r->devmode) {
+               DEBUG(8,("Returning NULL Devicemode!\n"));
+       }
 
-       return result;
-}
+       r->secdesc              = NULL;
 
-/********************************************************************
- enum_all_printers_info_1_local.
-*********************************************************************/
+       if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
+               /* don't use talloc_steal() here unless you do a deep steal of all
+                  the SEC_DESC members */
 
-static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
-{
-       DEBUG(4,("enum_all_printers_info_1_local\n"));
+               r->secdesc      = dup_sec_desc(mem_ctx, ntprinter->info_2->secdesc_buf->sd);
+       }
 
-       return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
+       return WERR_OK;
 }
 
 /********************************************************************
- enum_all_printers_info_1_name.
-*********************************************************************/
+********************************************************************/
 
-static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static bool snum_is_shared_printer(int snum)
 {
-       char *s = name;
-
-       DEBUG(4,("enum_all_printers_info_1_name\n"));
-
-       if ((name[0] == '\\') && (name[1] == '\\'))
-               s = name + 2;
-
-       if (is_myname_or_ipaddr(s)) {
-               return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
-       }
-       else
-               return WERR_INVALID_NAME;
+       return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
 }
 
-#if 0  /* JERRY -- disabled for now.  Don't think this is used, tested, or correct */
 /********************************************************************
enum_all_printers_info_1_remote.
-*********************************************************************/
Spoolss_enumprinters.
+********************************************************************/
 
-static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
+                                      uint32_t flags,
+                                      union spoolss_PrinterInfo **info_p,
+                                      uint32_t *count)
 {
-       PRINTER_INFO_1 *printer;
-       fstring printername;
-       fstring desc;
-       fstring comment;
-       DEBUG(4,("enum_all_printers_info_1_remote\n"));
+       int snum;
+       int n_services = lp_numservices();
+       union spoolss_PrinterInfo *info = NULL;
        WERROR result = WERR_OK;
 
-       /* JFM: currently it's more a place holder than anything else.
-        * In the spooler world there is a notion of server registration.
-        * the print servers are registered on the PDC (in the same domain)
-        *
-        * We should have a TDB here. The registration is done thru an
-        * undocumented RPC call.
+       DEBUG(4,("enum_all_printers_info_1\n"));
+
+       *count = 0;
+
+       for (snum=0; snum<n_services; snum++) {
+
+               NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+               struct spoolss_PrinterInfo1 info1;
+
+               if (!snum_is_shared_printer(snum)) {
+                       continue;
+               }
+
+               DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
+
+               result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum));
+               if (!W_ERROR_IS_OK(result)) {
+                       continue;
+               }
+
+               result = construct_printer_info1(info, ntprinter, flags, &info1, snum);
+               free_a_printer(&ntprinter,2);
+               if (!W_ERROR_IS_OK(result)) {
+                       continue;
+               }
+
+               info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+                                           union spoolss_PrinterInfo,
+                                           *count + 1);
+               if (!info) {
+                       DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
+                       result = WERR_NOMEM;
+                       goto out;
+               }
+
+               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *count));
+
+               info[*count].info1 = info1;
+               (*count)++;
+       }
+
+ out:
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
+       }
+
+       *info_p = info;
+
+       return WERR_OK;
+}
+
+/********************************************************************
+ enum_all_printers_info_1_local.
+*********************************************************************/
+
+static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
+                                            union spoolss_PrinterInfo **info,
+                                            uint32_t *count)
+{
+       DEBUG(4,("enum_all_printers_info_1_local\n"));
+
+       return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
+}
+
+/********************************************************************
+ enum_all_printers_info_1_name.
+*********************************************************************/
+
+static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
+                                           const char *name,
+                                           union spoolss_PrinterInfo **info,
+                                           uint32_t *count)
+{
+       const char *s = name;
+
+       DEBUG(4,("enum_all_printers_info_1_name\n"));
+
+       if ((name[0] == '\\') && (name[1] == '\\')) {
+               s = name + 2;
+       }
+
+       if (!is_myname_or_ipaddr(s)) {
+               return WERR_INVALID_NAME;
+       }
+
+       return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
+}
+
+#if 0  /* JERRY -- disabled for now.  Don't think this is used, tested, or correct */
+/********************************************************************
+ enum_all_printers_info_1_remote.
+*********************************************************************/
+
+static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+{
+       PRINTER_INFO_1 *printer;
+       fstring printername;
+       fstring desc;
+       fstring comment;
+       DEBUG(4,("enum_all_printers_info_1_remote\n"));
+       WERROR result = WERR_OK;
+
+       /* JFM: currently it's more a place holder than anything else.
+        * In the spooler world there is a notion of server registration.
+        * the print servers are registered on the PDC (in the same domain)
+        *
+        * We should have a TDB here. The registration is done thru an
+        * undocumented RPC call.
         */
 
        if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
@@ -4523,9 +4612,12 @@ out:
  enum_all_printers_info_1_network.
 *********************************************************************/
 
-static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
+                                              const char *name,
+                                              union spoolss_PrinterInfo **info,
+                                              uint32_t *count)
 {
-       char *s = name;
+       const char *s = name;
 
        DEBUG(4,("enum_all_printers_info_1_network\n"));
 
@@ -4537,13 +4629,15 @@ static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer,
           listed. Windows responds to this call with a
           WERR_CAN_NOT_COMPLETE so we should do the same. */
 
-       if (name[0] == '\\' && name[1] == '\\')
+       if (name[0] == '\\' && name[1] == '\\') {
                 s = name + 2;
+       }
 
-       if (is_myname_or_ipaddr(s))
+       if (is_myname_or_ipaddr(s)) {
                 return WERR_CAN_NOT_COMPLETE;
+       }
 
-       return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
+       return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_NAME, info, count);
 }
 
 /********************************************************************
@@ -4552,92 +4646,96 @@ static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer,
  * called from api_spoolss_enumprinters (see this to understand)
  ********************************************************************/
 
-static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
+                                      union spoolss_PrinterInfo **info_p,
+                                      uint32_t *count)
 {
        int snum;
-       int i;
-       int n_services=lp_numservices();
-       PRINTER_INFO_2 *printers=NULL;
-       PRINTER_INFO_2 current_prt;
+       int n_services = lp_numservices();
+       union spoolss_PrinterInfo *info = NULL;
        WERROR result = WERR_OK;
 
-       *returned = 0;
+       *count = 0;
 
        for (snum=0; snum<n_services; snum++) {
-               if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
-                       DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
-
-                       if (construct_printer_info_2(NULL, &current_prt, snum)) {
-                               if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
-                                       DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
-                                       *returned = 0;
-                                       return WERR_NOMEM;
-                               }
 
-                               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
+               struct spoolss_PrinterInfo2 info2;
+               NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
 
-                               memcpy(&printers[*returned], &current_prt, sizeof(PRINTER_INFO_2));
-
-                               (*returned)++;
-                       }
+               if (!snum_is_shared_printer(snum)) {
+                       continue;
                }
-       }
 
-       /* check the required size. */
-       for (i=0; i<*returned; i++)
-               (*needed) += spoolss_size_printer_info_2(&printers[i]);
+               DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
+               result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum));
+               if (!W_ERROR_IS_OK(result)) {
+                       continue;
+               }
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-       }
+               result = construct_printer_info2(info, ntprinter, &info2, snum);
+               free_a_printer(&ntprinter, 2);
+               if (!W_ERROR_IS_OK(result)) {
+                       continue;
+               }
 
-       /* fill the buffer with the structures */
-       for (i=0; i<*returned; i++)
-               smb_io_printer_info_2("", buffer, &(printers[i]), 0);
+               info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+                                           union spoolss_PrinterInfo,
+                                           *count + 1);
+               if (!info) {
+                       DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
+                       result = WERR_NOMEM;
+                       goto out;
+               }
 
-out:
-       /* clear memory */
+               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *count + 1));
 
-       for (i=0; i<*returned; i++)
-               free_devmode(printers[i].devmode);
+               info[*count].info2 = info2;
 
-       SAFE_FREE(printers);
+               (*count)++;
+       }
 
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+ out:
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
+       }
 
-       return result;
+       *info_p = info;
+
+       return WERR_OK;
 }
 
 /********************************************************************
  * handle enumeration of printers at level 1
  ********************************************************************/
 
-static WERROR enumprinters_level1( uint32 flags, fstring name,
-                                RPC_BUFFER *buffer, uint32 offered,
-                                uint32 *needed, uint32 *returned)
+static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
+                                 uint32_t flags,
+                                 const char *name,
+                                 union spoolss_PrinterInfo **info,
+                                 uint32_t *count)
 {
        /* Not all the flags are equals */
 
-       if (flags & PRINTER_ENUM_LOCAL)
-               return enum_all_printers_info_1_local(buffer, offered, needed, returned);
+       if (flags & PRINTER_ENUM_LOCAL) {
+               return enum_all_printers_info_1_local(mem_ctx, info, count);
+       }
 
-       if (flags & PRINTER_ENUM_NAME)
-               return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
+       if (flags & PRINTER_ENUM_NAME) {
+               return enum_all_printers_info_1_name(mem_ctx, name, info, count);
+       }
 
 #if 0  /* JERRY - disabled for now */
-       if (flags & PRINTER_ENUM_REMOTE)
-               return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
+       if (flags & PRINTER_ENUM_REMOTE) {
+               return enum_all_printers_info_1_remote(mem_ctx, name, info, count);
+       }
 #endif
 
-       if (flags & PRINTER_ENUM_NETWORK)
-               return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
+       if (flags & PRINTER_ENUM_NETWORK) {
+               return enum_all_printers_info_1_network(mem_ctx, name, info, count);
+       }
 
        return WERR_OK; /* NT4sp5 does that */
 }
@@ -4646,23 +4744,27 @@ static WERROR enumprinters_level1( uint32 flags, fstring name,
  * handle enumeration of printers at level 2
  ********************************************************************/
 
-static WERROR enumprinters_level2( uint32 flags, const char *servername,
-                                RPC_BUFFER *buffer, uint32 offered,
-                                uint32 *needed, uint32 *returned)
+static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
+                                 uint32_t flags,
+                                 const char *servername,
+                                 union spoolss_PrinterInfo **info,
+                                 uint32_t *count)
 {
        if (flags & PRINTER_ENUM_LOCAL) {
-                       return enum_all_printers_info_2(buffer, offered, needed, returned);
+               return enum_all_printers_info_2(mem_ctx, info, count);
        }
 
        if (flags & PRINTER_ENUM_NAME) {
-               if (is_myname_or_ipaddr(canon_servername(servername)))
-                       return enum_all_printers_info_2(buffer, offered, needed, returned);
-               else
+               if (!is_myname_or_ipaddr(canon_servername(servername))) {
                        return WERR_INVALID_NAME;
+               }
+
+               return enum_all_printers_info_2(mem_ctx, info, count);
        }
 
-       if (flags & PRINTER_ENUM_REMOTE)
+       if (flags & PRINTER_ENUM_REMOTE) {
                return WERR_UNKNOWN_LEVEL;
+       }
 
        return WERR_OK;
 }
@@ -4671,49 +4773,37 @@ static WERROR enumprinters_level2( uint32 flags, const char *servername,
  * handle enumeration of printers at level 5
  ********************************************************************/
 
-static WERROR enumprinters_level5( uint32 flags, const char *servername,
-                                RPC_BUFFER *buffer, uint32 offered,
-                                uint32 *needed, uint32 *returned)
+static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
+                                 uint32_t flags,
+                                 const char *servername,
+                                 union spoolss_PrinterInfo **info,
+                                 uint32_t *count)
 {
-/*     return enum_all_printers_info_5(buffer, offered, needed, returned);*/
+/*     return enum_all_printers_info_5(mem_ctx, info, offered, needed, count);*/
        return WERR_OK;
 }
 
-/********************************************************************
- * api_spoolss_enumprinters
- *
- * called from api_spoolss_enumprinters (see this to understand)
- ********************************************************************/
+/****************************************************************
+ _spoolss_EnumPrinters
+****************************************************************/
 
-WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
+WERROR _spoolss_EnumPrinters(pipes_struct *p,
+                            struct spoolss_EnumPrinters *r)
 {
-       uint32 flags = q_u->flags;
-       UNISTR2 *servername = &q_u->servername;
-       uint32 level = q_u->level;
-       RPC_BUFFER *buffer = NULL;
-       uint32 offered = q_u->offered;
-       uint32 *needed = &r_u->needed;
-       uint32 *returned = &r_u->returned;
-
-       fstring name;
+       const char *name;
+       WERROR result;
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer && (offered!=0)) {
-               return WERR_INVALID_PARAM;
-       }
-
-       if (offered > MAX_RPC_DATA_SIZE) {
+       if (!r->in.buffer && (r->in.offered != 0)) {
                return WERR_INVALID_PARAM;
        }
 
-       rpcbuf_move(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
-
-       DEBUG(4,("_spoolss_enumprinters\n"));
+       DEBUG(4,("_spoolss_EnumPrinters\n"));
 
-       *needed=0;
-       *returned=0;
+       *r->out.needed = 0;
+       *r->out.count = 0;
+       *r->out.info = NULL;
 
        /*
         * Level 1:
@@ -4728,392 +4818,376 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
         * Level 5: same as Level 2
         */
 
-       unistr2_to_ascii(name, servername, sizeof(name));
-       strupper_m(name);
+       name = talloc_strdup_upper(p->mem_ctx, r->in.server);
+       W_ERROR_HAVE_NO_MEMORY(name);
 
-       switch (level) {
+       switch (r->in.level) {
        case 1:
-               return enumprinters_level1(flags, name, buffer, offered, needed, returned);
+               result = enumprinters_level1(p->mem_ctx, r->in.flags, name,
+                                            r->out.info, r->out.count);
+               break;
        case 2:
-               return enumprinters_level2(flags, name, buffer, offered, needed, returned);
+               result = enumprinters_level2(p->mem_ctx, r->in.flags, name,
+                                            r->out.info, r->out.count);
+               break;
        case 5:
-               return enumprinters_level5(flags, name, buffer, offered, needed, returned);
+               result = enumprinters_level5(p->mem_ctx, r->in.flags, name,
+                                            r->out.info, r->out.count);
+               break;
        case 3:
        case 4:
+               result = WERR_OK; /* ??? */
                break;
+       default:
+               return WERR_UNKNOWN_LEVEL;
        }
-       return WERR_UNKNOWN_LEVEL;
+
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+                                                    spoolss_EnumPrinters, NULL,
+                                                    *r->out.info, r->in.level,
+                                                    *r->out.count);
+       *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
+       *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
+
+       return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 }
 
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_GetPrinter
+****************************************************************/
 
-static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+WERROR _spoolss_GetPrinter(pipes_struct *p,
+                          struct spoolss_GetPrinter *r)
 {
-       PRINTER_INFO_0 *printer=NULL;
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
+       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
        WERROR result = WERR_OK;
 
-       if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
-               return WERR_NOMEM;
+       int snum;
 
-       construct_printer_info_0(print_hnd, printer, snum);
+       /* that's an [in out] buffer */
 
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_0(printer);
+       if (!r->in.buffer && (r->in.offered != 0)) {
+               return WERR_INVALID_PARAM;
+       }
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
+       *r->out.needed = 0;
+
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
+               return WERR_BADFID;
        }
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+       result = get_a_printer(Printer, &ntprinter, 2,
+                              lp_const_servicename(snum));
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
        }
 
-       /* fill the buffer with the structures */
-       smb_io_printer_info_0("", buffer, printer, 0);
+       switch (r->in.level) {
+       case 0:
+               result = construct_printer_info0(p->mem_ctx, ntprinter,
+                                                &r->out.info->info0, snum);
+               break;
+       case 1:
+               result = construct_printer_info1(p->mem_ctx, ntprinter,
+                                                PRINTER_ENUM_ICON8,
+                                                &r->out.info->info1, snum);
+               break;
+       case 2:
+               result = construct_printer_info2(p->mem_ctx, ntprinter,
+                                                &r->out.info->info2, snum);
+               break;
+       case 3:
+               result = construct_printer_info3(p->mem_ctx, ntprinter,
+                                                &r->out.info->info3, snum);
+               break;
+       case 4:
+               result = construct_printer_info4(p->mem_ctx, ntprinter,
+                                                &r->out.info->info4, snum);
+               break;
+       case 5:
+               result = construct_printer_info5(p->mem_ctx, ntprinter,
+                                                &r->out.info->info5, snum);
+               break;
+       case 6:
+               result = construct_printer_info6(p->mem_ctx, ntprinter,
+                                                &r->out.info->info6, snum);
+               break;
+       case 7:
+               result = construct_printer_info7(p->mem_ctx, Printer,
+                                                &r->out.info->info7, snum);
+               break;
+       default:
+               result = WERR_UNKNOWN_LEVEL;
+               break;
+       }
 
-out:
-       /* clear memory */
+       free_a_printer(&ntprinter, 2);
 
-       SAFE_FREE(printer);
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(r->out.info);
+               return result;
+       }
 
-       return result;
+       *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo, NULL,
+                                              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);
 }
 
-/****************************************************************************
-****************************************************************************/
+/********************************************************************
+ ********************************************************************/
 
-static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static const char **string_array_from_driver_info(TALLOC_CTX *mem_ctx,
+                                                 fstring *fstring_array,
+                                                 const char *cservername)
 {
-       PRINTER_INFO_1 *printer=NULL;
-       WERROR result = WERR_OK;
+       int i, num_strings = 0;
+       const char **array = NULL;
 
-       if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
-               return WERR_NOMEM;
+       for (i=0; fstring_array && fstring_array[i][0] != '\0'; i++) {
 
-       construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
+               const char *str = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                                                 cservername, fstring_array[i]);
+               if (!str) {
+                       TALLOC_FREE(array);
+                       return NULL;
+               }
 
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_1(printer);
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
+               if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
+                       TALLOC_FREE(array);
+                       return NULL;
+               }
        }
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+       if (i > 0) {
+               ADD_TO_ARRAY(mem_ctx, const char *, NULL,
+                            &array, &num_strings);
        }
 
-       /* fill the buffer with the structures */
-       smb_io_printer_info_1("", buffer, printer, 0);
+       return array;
+}
 
-out:
-       /* clear memory */
-       SAFE_FREE(printer);
-
-       return result;
-}
-
-/****************************************************************************
-****************************************************************************/
+/********************************************************************
+ * fill a spoolss_DriverInfo1 struct
+ ********************************************************************/
 
-static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
+                                       struct spoolss_DriverInfo1 *r,
+                                       const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+                                       const char *servername,
+                                       const char *architecture)
 {
-       PRINTER_INFO_2 *printer=NULL;
-       WERROR result = WERR_OK;
-
-       if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
-               return WERR_NOMEM;
-
-       construct_printer_info_2(print_hnd, printer, snum);
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_2(printer);
+       r->driver_name          = talloc_strdup(mem_ctx, driver->info_3->name);
+       W_ERROR_HAVE_NO_MEMORY(r->driver_name);
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-       }
-
-       /* fill the buffer with the structures */
-       if (!smb_io_printer_info_2("", buffer, printer, 0))
-               result = WERR_NOMEM;
-
-out:
-       /* clear memory */
-       free_printer_info_2(printer);
-
-       return result;
+       return WERR_OK;
 }
 
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
-       PRINTER_INFO_3 *printer=NULL;
-       WERROR result = WERR_OK;
-
-       if (!construct_printer_info_3(print_hnd, &printer, snum))
-               return WERR_NOMEM;
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_3(printer);
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-       }
-
-       /* fill the buffer with the structures */
-       smb_io_printer_info_3("", buffer, printer, 0);
-
-out:
-       /* clear memory */
-       free_printer_info_3(printer);
-
-       return result;
-}
+/********************************************************************
+ * fill a spoolss_DriverInfo2 struct
+ ********************************************************************/
 
-/****************************************************************************
-****************************************************************************/
+static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
+                                       struct spoolss_DriverInfo2 *r,
+                                       const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+                                       const char *servername)
 
-static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
-       PRINTER_INFO_4 *printer=NULL;
-       WERROR result = WERR_OK;
-
-       if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
-               return WERR_NOMEM;
-
-       if (!construct_printer_info_4(print_hnd, printer, snum)) {
-               SAFE_FREE(printer);
-               return WERR_NOMEM;
-       }
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_4(printer);
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-       }
-
-       /* fill the buffer with the structures */
-       smb_io_printer_info_4("", buffer, printer, 0);
-
-out:
-       /* clear memory */
-       free_printer_info_4(printer);
-
-       return result;
-}
-
-/****************************************************************************
-****************************************************************************/
+       const char *cservername = canon_servername(servername);
 
-static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
-       PRINTER_INFO_5 *printer=NULL;
-       WERROR result = WERR_OK;
+       r->version              = driver->info_3->cversion;
 
-       if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
-               return WERR_NOMEM;
+       r->driver_name          = talloc_strdup(mem_ctx, driver->info_3->name);
+       W_ERROR_HAVE_NO_MEMORY(r->driver_name);
+       r->architecture         = talloc_strdup(mem_ctx, driver->info_3->environment);
+       W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
-       if (!construct_printer_info_5(print_hnd, printer, snum)) {
-               free_printer_info_5(printer);
-               return WERR_NOMEM;
+       if (strlen(driver->info_3->driverpath)) {
+               r->driver_path  = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                               cservername, driver->info_3->driverpath);
+       } else {
+               r->driver_path  = talloc_strdup(mem_ctx, "");
        }
+       W_ERROR_HAVE_NO_MEMORY(r->driver_path);
 
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_5(printer);
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
+       if (strlen(driver->info_3->datafile)) {
+               r->data_file    = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                               cservername, driver->info_3->datafile);
+       } else {
+               r->data_file    = talloc_strdup(mem_ctx, "");
        }
+       W_ERROR_HAVE_NO_MEMORY(r->data_file);
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+       if (strlen(driver->info_3->configfile)) {
+               r->config_file  = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                               cservername, driver->info_3->configfile);
+       } else {
+               r->config_file  = talloc_strdup(mem_ctx, "");
        }
+       W_ERROR_HAVE_NO_MEMORY(r->config_file);
 
-       /* fill the buffer with the structures */
-       smb_io_printer_info_5("", buffer, printer, 0);
-
-out:
-       /* clear memory */
-       free_printer_info_5(printer);
-
-       return result;
+       return WERR_OK;
 }
 
-static WERROR getprinter_level_6(Printer_entry *print_hnd,
-                                int snum,
-                                RPC_BUFFER *buffer, uint32 offered,
-                                uint32 *needed)
-{
-       PRINTER_INFO_6 *printer;
-       WERROR result = WERR_OK;
+/********************************************************************
+ * fill a spoolss_DriverInfo3 struct
+ ********************************************************************/
 
-       if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
-               return WERR_NOMEM;
-       }
+static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
+                                       struct spoolss_DriverInfo3 *r,
+                                       const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+                                       const char *servername)
+{
+       const char *cservername = canon_servername(servername);
 
-       if (!construct_printer_info_6(print_hnd, printer, snum)) {
-               free_printer_info_6(printer);
-               return WERR_NOMEM;
-       }
+       r->version              = driver->info_3->cversion;
 
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_6(printer);
+       r->driver_name          = talloc_strdup(mem_ctx, driver->info_3->name);
+       W_ERROR_HAVE_NO_MEMORY(r->driver_name);
+       r->architecture         = talloc_strdup(mem_ctx, driver->info_3->environment);
+       W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+       if (strlen(driver->info_3->driverpath)) {
+               r->driver_path  = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                               cservername, driver->info_3->driverpath);
+       } else {
+               r->driver_path  = talloc_strdup(mem_ctx, "");
        }
+       W_ERROR_HAVE_NO_MEMORY(r->driver_path);
 
-       /* fill the buffer with the structures */
-       smb_io_printer_info_6("", buffer, printer, 0);
-
-out:
-       /* clear memory */
-       free_printer_info_6(printer);
-
-       return result;
-}
-
-static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
-       PRINTER_INFO_7 *printer=NULL;
-       WERROR result = WERR_OK;
-
-       if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
-               return WERR_NOMEM;
-
-       if (!construct_printer_info_7(print_hnd, printer, snum)) {
-               result = WERR_NOMEM;
-               goto out;
+       if (strlen(driver->info_3->datafile)) {
+               r->data_file    = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                               cservername, driver->info_3->datafile);
+       } else {
+               r->data_file    = talloc_strdup(mem_ctx, "");
        }
+       W_ERROR_HAVE_NO_MEMORY(r->data_file);
 
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_7(printer);
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
+       if (strlen(driver->info_3->configfile)) {
+               r->config_file  = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                               cservername, driver->info_3->configfile);
+       } else {
+               r->config_file  = talloc_strdup(mem_ctx, "");
        }
+       W_ERROR_HAVE_NO_MEMORY(r->config_file);
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-
+       if (strlen(driver->info_3->helpfile)) {
+               r->help_file    = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                               cservername, driver->info_3->helpfile);
+       } else {
+               r->help_file    = talloc_strdup(mem_ctx, "");
        }
+       W_ERROR_HAVE_NO_MEMORY(r->config_file);
 
-       /* fill the buffer with the structures */
-       smb_io_printer_info_7("", buffer, printer, 0);
-
-out:
-       /* clear memory */
-       free_printer_info_7(printer);
+       r->monitor_name         = talloc_strdup(mem_ctx, driver->info_3->monitorname);
+       W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
+       r->default_datatype     = talloc_strdup(mem_ctx, driver->info_3->defaultdatatype);
+       W_ERROR_HAVE_NO_MEMORY(r->default_datatype);
 
-       return result;
+       r->dependent_files = string_array_from_driver_info(mem_ctx,
+                                                          driver->info_3->dependentfiles,
+                                                          cservername);
+       return WERR_OK;
 }
 
-/****************************************************************************
-****************************************************************************/
+/********************************************************************
+ * fill a spoolss_DriverInfo6 struct
+ ********************************************************************/
 
-WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
+static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
+                                       struct spoolss_DriverInfo6 *r,
+                                       const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+                                       const char *servername)
 {
-       POLICY_HND *handle = &q_u->handle;
-       uint32 level = q_u->level;
-       RPC_BUFFER *buffer = NULL;
-       uint32 offered = q_u->offered;
-       uint32 *needed = &r_u->needed;
-       Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+       const char *cservername = canon_servername(servername);
 
-       int snum;
+       r->version              = driver->info_3->cversion;
 
-       /* that's an [in out] buffer */
+       r->driver_name          = talloc_strdup(mem_ctx, driver->info_3->name);
+       W_ERROR_HAVE_NO_MEMORY(r->driver_name);
+       r->architecture         = talloc_strdup(mem_ctx, driver->info_3->environment);
+       W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
-       if (!q_u->buffer && (offered!=0)) {
-               return WERR_INVALID_PARAM;
+       if (strlen(driver->info_3->driverpath)) {
+               r->driver_path  = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                               cservername, driver->info_3->driverpath);
+       } else {
+               r->driver_path  = talloc_strdup(mem_ctx, "");
        }
+       W_ERROR_HAVE_NO_MEMORY(r->driver_path);
 
-       if (offered > MAX_RPC_DATA_SIZE) {
-               return WERR_INVALID_PARAM;
+       if (strlen(driver->info_3->datafile)) {
+               r->data_file    = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                               cservername, driver->info_3->datafile);
+       } else {
+               r->data_file    = talloc_strdup(mem_ctx, "");
        }
+       W_ERROR_HAVE_NO_MEMORY(r->data_file);
 
-       rpcbuf_move(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
-
-       *needed=0;
-
-       if (!get_printer_snum(p, handle, &snum, NULL))
-               return WERR_BADFID;
+       if (strlen(driver->info_3->configfile)) {
+               r->config_file  = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                               cservername, driver->info_3->configfile);
+       } else {
+               r->config_file  = talloc_strdup(mem_ctx, "");
+       }
+       W_ERROR_HAVE_NO_MEMORY(r->config_file);
 
-       switch (level) {
-       case 0:
-               return getprinter_level_0(Printer, snum, buffer, offered, needed);
-       case 1:
-               return getprinter_level_1(Printer, snum, buffer, offered, needed);
-       case 2:
-               return getprinter_level_2(Printer, snum, buffer, offered, needed);
-       case 3:
-               return getprinter_level_3(Printer, snum, buffer, offered, needed);
-       case 4:
-               return getprinter_level_4(Printer, snum, buffer, offered, needed);
-       case 5:
-               return getprinter_level_5(Printer, snum, buffer, offered, needed);
-       case 6:
-               return getprinter_level_6(Printer, snum, buffer, offered, needed);
-       case 7:
-               return getprinter_level_7(Printer, snum, buffer, offered, needed);
+       if (strlen(driver->info_3->helpfile)) {
+               r->help_file    = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                               cservername, driver->info_3->helpfile);
+       } else {
+               r->help_file    = talloc_strdup(mem_ctx, "");
        }
-       return WERR_UNKNOWN_LEVEL;
-}
+       W_ERROR_HAVE_NO_MEMORY(r->config_file);
 
-/********************************************************************
- * fill a DRIVER_INFO_1 struct
- ********************************************************************/
+       r->monitor_name         = talloc_strdup(mem_ctx, driver->info_3->monitorname);
+       W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
+       r->default_datatype     = talloc_strdup(mem_ctx, driver->info_3->defaultdatatype);
+       W_ERROR_HAVE_NO_MEMORY(r->default_datatype);
+
+       r->dependent_files = string_array_from_driver_info(mem_ctx,
+                                                          driver->info_3->dependentfiles,
+                                                          cservername);
+       r->previous_names = string_array_from_driver_info(mem_ctx,
+                                                         NULL,
+                                                         cservername);
+
+       r->driver_date          = 0;
+       r->driver_version       = 0;
+
+       r->manufacturer_name    = talloc_strdup(mem_ctx, "");
+       W_ERROR_HAVE_NO_MEMORY(r->manufacturer_name);
+       r->manufacturer_url     = talloc_strdup(mem_ctx, "");
+       W_ERROR_HAVE_NO_MEMORY(r->manufacturer_url);
+       r->hardware_id          = talloc_strdup(mem_ctx, "");
+       W_ERROR_HAVE_NO_MEMORY(r->hardware_id);
+       r->provider             = talloc_strdup(mem_ctx, "");
+       W_ERROR_HAVE_NO_MEMORY(r->provider);
 
-static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
-{
-       init_unistr( &info->name, driver.info_3->name);
+       return WERR_OK;
 }
 
 /********************************************************************
  * construct_printer_driver_info_1
  ********************************************************************/
 
-static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_1(TALLOC_CTX *mem_ctx,
+                                             struct spoolss_DriverInfo1 *r,
+                                             int snum,
+                                             const char *servername,
+                                             const char *architecture,
+                                             uint32_t version)
 {
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
+       WERROR result;
 
        ZERO_STRUCT(driver);
 
@@ -5125,58 +5199,11 @@ static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, con
                return WERR_UNKNOWN_PRINTER_DRIVER;
        }
 
-       fill_printer_driver_info_1(info, driver, servername, architecture);
+       result = fill_printer_driver_info1(mem_ctx, r, &driver, servername, architecture);
 
        free_a_printer(&printer,2);
 
-       return WERR_OK;
-}
-
-/********************************************************************
- * construct_printer_driver_info_2
- * fill a printer_info_2 struct
- ********************************************************************/
-
-static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
-{
-       TALLOC_CTX *ctx = talloc_tos();
-       char *temp = NULL;
-       const char *cservername = canon_servername(servername);
-
-       info->version=driver.info_3->cversion;
-
-       init_unistr( &info->name, driver.info_3->name );
-       init_unistr( &info->architecture, driver.info_3->environment );
-
-       if (strlen(driver.info_3->driverpath)) {
-               temp = talloc_asprintf(ctx,
-                               "\\\\%s%s",
-                               cservername,
-                               driver.info_3->driverpath);
-               init_unistr( &info->driverpath, temp );
-       } else {
-               init_unistr( &info->driverpath, "" );
-       }
-
-       TALLOC_FREE(temp);
-       if (strlen(driver.info_3->datafile)) {
-               temp = talloc_asprintf(ctx,
-                               "\\\\%s%s",
-                               cservername,
-                               driver.info_3->datafile);
-               init_unistr( &info->datafile, temp );
-       } else
-               init_unistr( &info->datafile, "" );
-
-       TALLOC_FREE(temp);
-       if (strlen(driver.info_3->configfile)) {
-               temp = talloc_asprintf(ctx,
-                               "\\\\%s%s",
-                               cservername,
-                               driver.info_3->configfile);
-               init_unistr( &info->configfile, temp );
-       } else
-               init_unistr( &info->configfile, "" );
+       return result;
 }
 
 /********************************************************************
@@ -5184,10 +5211,16 @@ static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_IN
  * fill a printer_info_2 struct
  ********************************************************************/
 
-static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_2(TALLOC_CTX *mem_ctx,
+                                             struct spoolss_DriverInfo2 *r,
+                                             int snum,
+                                             const char *servername,
+                                             const char *architecture,
+                                             uint32_t version)
 {
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
+       WERROR result;
 
        ZERO_STRUCT(printer);
        ZERO_STRUCT(driver);
@@ -5200,11 +5233,11 @@ static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, con
                return WERR_UNKNOWN_PRINTER_DRIVER;
        }
 
-       fill_printer_driver_info_2(info, driver, servername);
+       result = fill_printer_driver_info2(mem_ctx, r, &driver, servername);
 
        free_a_printer(&printer,2);
 
-       return WERR_OK;
+       return result;
 }
 
 /********************************************************************
@@ -5285,72 +5318,12 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c
  * fill a printer_info_3 struct
  ********************************************************************/
 
-static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
-{
-       char *temp = NULL;
-       TALLOC_CTX *ctx = talloc_tos();
-       const char *cservername = canon_servername(servername);
-
-       ZERO_STRUCTP(info);
-
-       info->version=driver.info_3->cversion;
-
-       init_unistr( &info->name, driver.info_3->name );
-       init_unistr( &info->architecture, driver.info_3->environment );
-
-       if (strlen(driver.info_3->driverpath)) {
-               temp = talloc_asprintf(ctx,
-                               "\\\\%s%s",
-                               cservername,
-                               driver.info_3->driverpath);
-               init_unistr( &info->driverpath, temp );
-       } else
-               init_unistr( &info->driverpath, "" );
-
-       TALLOC_FREE(temp);
-       if (strlen(driver.info_3->datafile)) {
-               temp = talloc_asprintf(ctx,
-                               "\\\\%s%s",
-                               cservername,
-                               driver.info_3->datafile);
-               init_unistr( &info->datafile, temp );
-       } else
-               init_unistr( &info->datafile, "" );
-
-       TALLOC_FREE(temp);
-       if (strlen(driver.info_3->configfile)) {
-               temp = talloc_asprintf(ctx,
-                               "\\\\%s%s",
-                               cservername,
-                               driver.info_3->configfile);
-               init_unistr( &info->configfile, temp );
-       } else
-               init_unistr( &info->configfile, "" );
-
-       TALLOC_FREE(temp);
-       if (strlen(driver.info_3->helpfile)) {
-               temp = talloc_asprintf(ctx,
-                               "\\\\%s%s",
-                               cservername,
-                               driver.info_3->helpfile);
-               init_unistr( &info->helpfile, temp );
-       } else
-               init_unistr( &info->helpfile, "" );
-
-       TALLOC_FREE(temp);
-       init_unistr( &info->monitorname, driver.info_3->monitorname );
-       init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
-
-       info->dependentfiles=NULL;
-       init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
-}
-
-/********************************************************************
- * construct_printer_info_3
- * fill a printer_info_3 struct
- ********************************************************************/
-
-static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_3(TALLOC_CTX *mem_ctx,
+                                             struct spoolss_DriverInfo3 *r,
+                                             int snum,
+                                             const char *servername,
+                                             const char *architecture,
+                                             uint32_t version)
 {
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
@@ -5378,399 +5351,180 @@ static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, con
        if (!W_ERROR_IS_OK(status)) {
                /*
                 * Is this a W2k client ?
-                */
-               if (version == 3) {
-                       /* Yes - try again with a WinNT driver. */
-                       version = 2;
-                       status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
-                       DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
-               }
-#endif
-
-               if (!W_ERROR_IS_OK(status)) {
-                       free_a_printer(&printer,2);
-                       return WERR_UNKNOWN_PRINTER_DRIVER;
-               }
-
-#if 0  /* JERRY */
-       }
-#endif
-
-
-       fill_printer_driver_info_3(info, driver, servername);
-
-       free_a_printer(&printer,2);
-
-       return WERR_OK;
-}
-
-/********************************************************************
- * construct_printer_info_6
- * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
- ********************************************************************/
-
-static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
-{
-       char *temp = NULL;
-       fstring nullstr;
-       TALLOC_CTX *ctx = talloc_tos();
-       const char *cservername = canon_servername(servername);
-
-       ZERO_STRUCTP(info);
-       memset(&nullstr, '\0', sizeof(fstring));
-
-       info->version=driver.info_3->cversion;
-
-       init_unistr( &info->name, driver.info_3->name );
-       init_unistr( &info->architecture, driver.info_3->environment );
-
-       if (strlen(driver.info_3->driverpath)) {
-               temp = talloc_asprintf(ctx,
-                               "\\\\%s%s",
-                               cservername,
-                               driver.info_3->driverpath);
-               init_unistr( &info->driverpath, temp );
-       } else
-               init_unistr( &info->driverpath, "" );
-
-       TALLOC_FREE(temp);
-       if (strlen(driver.info_3->datafile)) {
-               temp = talloc_asprintf(ctx,
-                               "\\\\%s%s",
-                               cservername,
-                               driver.info_3->datafile);
-               init_unistr( &info->datafile, temp );
-       } else
-               init_unistr( &info->datafile, "" );
-
-       TALLOC_FREE(temp);
-       if (strlen(driver.info_3->configfile)) {
-               temp = talloc_asprintf(ctx,
-                               "\\\\%s%s",
-                               cservername,
-                               driver.info_3->configfile);
-               init_unistr( &info->configfile, temp );
-       } else
-               init_unistr( &info->configfile, "" );
-
-       TALLOC_FREE(temp);
-       if (strlen(driver.info_3->helpfile)) {
-               temp = talloc_asprintf(ctx,
-                               "\\\\%s%s",
-                               cservername,
-                               driver.info_3->helpfile);
-               init_unistr( &info->helpfile, temp );
-       } else
-               init_unistr( &info->helpfile, "" );
-
-       TALLOC_FREE(temp);
-       init_unistr( &info->monitorname, driver.info_3->monitorname );
-       init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
-
-       info->dependentfiles = NULL;
-       init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
-
-       info->previousdrivernames=NULL;
-       init_unistr_array(&info->previousdrivernames, &nullstr, servername);
-
-       info->driver_date=0;
-
-       info->padding=0;
-       info->driver_version_low=0;
-       info->driver_version_high=0;
-
-       init_unistr( &info->mfgname, "");
-       init_unistr( &info->oem_url, "");
-       init_unistr( &info->hardware_id, "");
-       init_unistr( &info->provider, "");
-}
-
-/********************************************************************
- * construct_printer_info_6
- * fill a printer_info_6 struct
- ********************************************************************/
-
-static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
-              const char *servername, fstring architecture, uint32 version)
-{
-       NT_PRINTER_INFO_LEVEL           *printer = NULL;
-       NT_PRINTER_DRIVER_INFO_LEVEL    driver;
-       WERROR                          status;
-
-       ZERO_STRUCT(driver);
-
-       status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
-
-       DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
-
-       if (!W_ERROR_IS_OK(status))
-               return WERR_INVALID_PRINTER_NAME;
-
-       status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
-
-       DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
-
-       if (!W_ERROR_IS_OK(status))
-       {
-               /*
-                * Is this a W2k client ?
-                */
-
-               if (version < 3) {
-                       free_a_printer(&printer,2);
-                       return WERR_UNKNOWN_PRINTER_DRIVER;
-               }
-
-               /* Yes - try again with a WinNT driver. */
-               version = 2;
-               status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
-               DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
-               if (!W_ERROR_IS_OK(status)) {
-                       free_a_printer(&printer,2);
-                       return WERR_UNKNOWN_PRINTER_DRIVER;
-               }
-       }
-
-       fill_printer_driver_info_6(info, driver, servername);
-
-       free_a_printer(&printer,2);
-       free_a_printer_driver(driver, 3);
-
-       return WERR_OK;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
-{
-       SAFE_FREE(info->dependentfiles);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
-{
-       SAFE_FREE(info->dependentfiles);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
-       DRIVER_INFO_1 *info=NULL;
-       WERROR result;
-
-       if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
-               return WERR_NOMEM;
-
-       result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(result))
-               goto out;
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_driver_info_1(info);
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-       }
-
-       /* fill the buffer with the structures */
-       smb_io_printer_driver_info_1("", buffer, info, 0);
-
-out:
-       /* clear memory */
-       SAFE_FREE(info);
-
-       return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
-       DRIVER_INFO_2 *info=NULL;
-       WERROR result;
-
-       if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
-               return WERR_NOMEM;
-
-       result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(result))
-               goto out;
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_driver_info_2(info);
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-       }
-
-       /* fill the buffer with the structures */
-       smb_io_printer_driver_info_2("", buffer, info, 0);
-
-out:
-       /* clear memory */
-       SAFE_FREE(info);
-
-       return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
-       DRIVER_INFO_3 info;
-       WERROR result;
-
-       ZERO_STRUCT(info);
-
-       result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(result))
-               goto out;
+                */
+               if (version == 3) {
+                       /* Yes - try again with a WinNT driver. */
+                       version = 2;
+                       status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
+                       DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
+               }
+#endif
 
-       /* check the required size. */
-       *needed += spoolss_size_printer_driver_info_3(&info);
+               if (!W_ERROR_IS_OK(status)) {
+                       free_a_printer(&printer,2);
+                       return WERR_UNKNOWN_PRINTER_DRIVER;
+               }
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
+#if 0  /* JERRY */
        }
+#endif
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-       }
 
-       /* fill the buffer with the structures */
-       smb_io_printer_driver_info_3("", buffer, &info, 0);
+       status = fill_printer_driver_info3(mem_ctx, r, &driver, servername);
 
-out:
-       free_printer_driver_info_3(&info);
+       free_a_printer(&printer,2);
 
-       return result;
+       return status;
 }
 
-/****************************************************************************
-****************************************************************************/
+/********************************************************************
+ * construct_printer_info_6
+ * fill a printer_info_6 struct
+ ********************************************************************/
 
-static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR construct_printer_driver_info_6(TALLOC_CTX *mem_ctx,
+                                             struct spoolss_DriverInfo6 *r,
+                                             int snum,
+                                             const char *servername,
+                                             const char *architecture,
+                                             uint32_t version)
 {
-       DRIVER_INFO_6 info;
-       WERROR result;
+       NT_PRINTER_INFO_LEVEL           *printer = NULL;
+       NT_PRINTER_DRIVER_INFO_LEVEL    driver;
+       WERROR                          status;
 
-       ZERO_STRUCT(info);
+       ZERO_STRUCT(driver);
 
-       result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(result))
-               goto out;
+       status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
 
-       /* check the required size. */
-       *needed += spoolss_size_printer_driver_info_6(&info);
+       DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
+       if (!W_ERROR_IS_OK(status))
+               return WERR_INVALID_PRINTER_NAME;
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+       status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
+
+       DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
+
+       if (!W_ERROR_IS_OK(status))
+       {
+               /*
+                * Is this a W2k client ?
+                */
+
+               if (version < 3) {
+                       free_a_printer(&printer,2);
+                       return WERR_UNKNOWN_PRINTER_DRIVER;
+               }
+
+               /* Yes - try again with a WinNT driver. */
+               version = 2;
+               status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
+               DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
+               if (!W_ERROR_IS_OK(status)) {
+                       free_a_printer(&printer,2);
+                       return WERR_UNKNOWN_PRINTER_DRIVER;
+               }
        }
 
-       /* fill the buffer with the structures */
-       smb_io_printer_driver_info_6("", buffer, &info, 0);
+       status = fill_printer_driver_info6(mem_ctx, r, &driver, servername);
 
-out:
-       free_printer_driver_info_6(&info);
+       free_a_printer(&printer,2);
+       free_a_printer_driver(driver, 3);
 
-       return result;
+       return status;
 }
 
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_GetPrinterDriver2
+****************************************************************/
 
-WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
+WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
+                                 struct spoolss_GetPrinterDriver2 *r)
 {
-       POLICY_HND *handle = &q_u->handle;
-       UNISTR2 *uni_arch = &q_u->architecture;
-       uint32 level = q_u->level;
-       uint32 clientmajorversion = q_u->clientmajorversion;
-       RPC_BUFFER *buffer = NULL;
-       uint32 offered = q_u->offered;
-       uint32 *needed = &r_u->needed;
-       uint32 *servermajorversion = &r_u->servermajorversion;
-       uint32 *serverminorversion = &r_u->serverminorversion;
        Printer_entry *printer;
+       WERROR result;
 
-       fstring servername;
-       fstring architecture;
+       const char *servername;
        int snum;
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer && (offered!=0)) {
-               return WERR_INVALID_PARAM;
-       }
-
-       if (offered > MAX_RPC_DATA_SIZE) {
+       if (!r->in.buffer && (r->in.offered != 0)) {
                return WERR_INVALID_PARAM;
        }
 
-       rpcbuf_move(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+       DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
 
-       DEBUG(4,("_spoolss_getprinterdriver2\n"));
-
-       if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
-               DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
+       if (!(printer = find_printer_index_by_hnd( p, r->in.handle))) {
+               DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
                return WERR_INVALID_PRINTER_NAME;
        }
 
-       *needed = 0;
-       *servermajorversion = 0;
-       *serverminorversion = 0;
+       *r->out.needed = 0;
+       *r->out.server_major_version = 0;
+       *r->out.server_minor_version = 0;
 
-       fstrcpy(servername, get_server_name( printer ));
-       unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
+       servername = get_server_name(printer);
 
-       if (!get_printer_snum(p, handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
-       switch (level) {
+       switch (r->in.level) {
        case 1:
-               return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
+               result = construct_printer_driver_info_1(p->mem_ctx,
+                                                        &r->out.info->info1,
+                                                        snum,
+                                                        servername,
+                                                        r->in.architecture,
+                                                        r->in.client_major_version);
+               break;
        case 2:
-               return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
+               result = construct_printer_driver_info_2(p->mem_ctx,
+                                                        &r->out.info->info2,
+                                                        snum,
+                                                        servername,
+                                                        r->in.architecture,
+                                                        r->in.client_major_version);
+               break;
        case 3:
-               return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
+               result = construct_printer_driver_info_3(p->mem_ctx,
+                                                        &r->out.info->info3,
+                                                        snum,
+                                                        servername,
+                                                        r->in.architecture,
+                                                        r->in.client_major_version);
+               break;
        case 6:
-               return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
+               result = construct_printer_driver_info_6(p->mem_ctx,
+                                                        &r->out.info->info6,
+                                                        snum,
+                                                        servername,
+                                                        r->in.architecture,
+                                                        r->in.client_major_version);
+               break;
+       default:
 #if 0  /* JERRY */
        case 101:
                /* apparently this call is the equivalent of
                   EnumPrinterDataEx() for the DsDriver key */
                break;
 #endif
+               result = WERR_UNKNOWN_LEVEL;
+               break;
        }
 
-       return WERR_UNKNOWN_LEVEL;
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(r->out.info);
+               return result;
+       }
+
+       *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo, NULL,
+                                              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);
 }
 
 
@@ -5868,7 +5622,7 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p,
        }
 
        Printer->jobid = print_job_start(p->server_info, snum,
-                                        CONST_DISCARD(char *,info_1->document_name),
+                                        info_1->document_name,
                                         Printer->nt_devmode);
 
        /* An error occured in print_job_start() so return an appropriate
@@ -6626,251 +6380,276 @@ WERROR _spoolss_AddJob(pipes_struct *p,
 }
 
 /****************************************************************************
+fill_job_info1
 ****************************************************************************/
 
-static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
-                            int position, int snum,
-                            const NT_PRINTER_INFO_LEVEL *ntprinter)
+static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
+                            struct spoolss_JobInfo1 *r,
+                            const print_queue_struct *queue,
+                            int position, int snum,
+                            const NT_PRINTER_INFO_LEVEL *ntprinter)
 {
        struct tm *t;
 
-       t=gmtime(&queue->time);
+       t = gmtime(&queue->time);
 
-       job_info->jobid=queue->job;
-       init_unistr(&job_info->printername, lp_servicename(snum));
-       init_unistr(&job_info->machinename, ntprinter->info_2->servername);
-       init_unistr(&job_info->username, queue->fs_user);
-       init_unistr(&job_info->document, queue->fs_file);
-       init_unistr(&job_info->datatype, "RAW");
-       init_unistr(&job_info->text_status, "");
-       job_info->status=nt_printj_status(queue->status);
-       job_info->priority=queue->priority;
-       job_info->position=position;
-       job_info->totalpages=queue->page_count;
-       job_info->pagesprinted=0;
+       r->job_id               = queue->job;
 
-       make_systemtime(&job_info->submitted, t);
+       r->printer_name         = talloc_strdup(mem_ctx, lp_servicename(snum));
+       W_ERROR_HAVE_NO_MEMORY(r->printer_name);
+       r->server_name          = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
+       W_ERROR_HAVE_NO_MEMORY(r->server_name);
+       r->user_name            = talloc_strdup(mem_ctx, queue->fs_user);
+       W_ERROR_HAVE_NO_MEMORY(r->user_name);
+       r->document_name        = talloc_strdup(mem_ctx, queue->fs_file);
+       W_ERROR_HAVE_NO_MEMORY(r->document_name);
+       r->data_type            = talloc_strdup(mem_ctx, "RAW");
+       W_ERROR_HAVE_NO_MEMORY(r->data_type);
+       r->text_status          = talloc_strdup(mem_ctx, "");
+       W_ERROR_HAVE_NO_MEMORY(r->text_status);
+
+       r->status               = nt_printj_status(queue->status);
+       r->priority             = queue->priority;
+       r->position             = position;
+       r->total_pages          = queue->page_count;
+       r->pages_printed        = 0; /* ??? */
+
+       init_systemtime(&r->submitted, t);
+
+       return WERR_OK;
 }
 
 /****************************************************************************
+fill_job_info2
 ****************************************************************************/
 
-static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
-                            int position, int snum,
-                           const NT_PRINTER_INFO_LEVEL *ntprinter,
-                           DEVICEMODE *devmode)
+static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
+                            struct spoolss_JobInfo2 *r,
+                            const print_queue_struct *queue,
+                            int position, int snum,
+                            const NT_PRINTER_INFO_LEVEL *ntprinter,
+                            struct spoolss_DeviceMode *devmode)
 {
        struct tm *t;
 
-       t=gmtime(&queue->time);
-
-       job_info->jobid=queue->job;
-
-       init_unistr(&job_info->printername, ntprinter->info_2->printername);
-
-       init_unistr(&job_info->machinename, ntprinter->info_2->servername);
-       init_unistr(&job_info->username, queue->fs_user);
-       init_unistr(&job_info->document, queue->fs_file);
-       init_unistr(&job_info->notifyname, queue->fs_user);
-       init_unistr(&job_info->datatype, "RAW");
-       init_unistr(&job_info->printprocessor, "winprint");
-       init_unistr(&job_info->parameters, "");
-       init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
-       init_unistr(&job_info->text_status, "");
+       t = gmtime(&queue->time);
+
+       r->job_id               = queue->job;
+
+       r->printer_name         = talloc_strdup(mem_ctx, lp_servicename(snum));
+       W_ERROR_HAVE_NO_MEMORY(r->printer_name);
+       r->server_name          = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
+       W_ERROR_HAVE_NO_MEMORY(r->server_name);
+       r->user_name            = talloc_strdup(mem_ctx, queue->fs_user);
+       W_ERROR_HAVE_NO_MEMORY(r->user_name);
+       r->document_name        = talloc_strdup(mem_ctx, queue->fs_file);
+       W_ERROR_HAVE_NO_MEMORY(r->document_name);
+       r->notify_name          = talloc_strdup(mem_ctx, queue->fs_user);
+       W_ERROR_HAVE_NO_MEMORY(r->notify_name);
+       r->data_type            = talloc_strdup(mem_ctx, "RAW");
+       W_ERROR_HAVE_NO_MEMORY(r->data_type);
+       r->print_processor      = talloc_strdup(mem_ctx, "winprint");
+       W_ERROR_HAVE_NO_MEMORY(r->print_processor);
+       r->parameters           = talloc_strdup(mem_ctx, "");
+       W_ERROR_HAVE_NO_MEMORY(r->parameters);
+       r->driver_name          = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
+       W_ERROR_HAVE_NO_MEMORY(r->driver_name);
+
+       r->devmode              = devmode;
+
+       r->text_status          = talloc_strdup(mem_ctx, "");
+       W_ERROR_HAVE_NO_MEMORY(r->text_status);
+
+       r->secdesc              = NULL;
+
+       r->status               = nt_printj_status(queue->status);
+       r->priority             = queue->priority;
+       r->position             = position;
+       r->start_time           = 0;
+       r->until_time           = 0;
+       r->total_pages          = queue->page_count;
+       r->size                 = queue->size;
+       init_systemtime(&r->submitted, t);
+       r->time                 = 0;
+       r->pages_printed        = 0; /* ??? */
 
-/* and here the security descriptor */
-
-       job_info->status=nt_printj_status(queue->status);
-       job_info->priority=queue->priority;
-       job_info->position=position;
-       job_info->starttime=0;
-       job_info->untiltime=0;
-       job_info->totalpages=queue->page_count;
-       job_info->size=queue->size;
-       make_systemtime(&(job_info->submitted), t);
-       job_info->timeelapsed=0;
-       job_info->pagesprinted=0;
-
-       job_info->devmode = devmode;
-
-       return (True);
+       return WERR_OK;
 }
 
 /****************************************************************************
  Enumjobs at level 1.
 ****************************************************************************/
 
-static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
+static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
+                             const print_queue_struct *queue,
+                             uint32_t num_queues, int snum,
                               const NT_PRINTER_INFO_LEVEL *ntprinter,
-                             RPC_BUFFER *buffer, uint32 offered,
-                             uint32 *needed, uint32 *returned)
+                             union spoolss_JobInfo **info_p,
+                             uint32_t *count)
 {
-       JOB_INFO_1 *info;
+       union spoolss_JobInfo *info;
        int i;
        WERROR result = WERR_OK;
 
-       info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
-       if (info==NULL) {
-               *returned=0;
-               return WERR_NOMEM;
-       }
-
-       for (i=0; i<*returned; i++)
-               fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
+       info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
+       W_ERROR_HAVE_NO_MEMORY(info);
 
-       /* check the required size. */
-       for (i=0; i<*returned; i++)
-               (*needed) += spoolss_size_job_info_1(&info[i]);
+       *count = num_queues;
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
+       for (i=0; i<*count; i++) {
+               result = fill_job_info1(info,
+                                       &info[i].info1,
+                                       &queue[i],
+                                       i,
+                                       snum,
+                                       ntprinter);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto out;
+               }
        }
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+ out:
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
        }
 
-       /* fill the buffer with the structures */
-       for (i=0; i<*returned; i++)
-               smb_io_job_info_1("", buffer, &info[i], 0);
-
-out:
-       /* clear memory */
-       SAFE_FREE(info);
-
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+       *info_p = info;
 
-       return result;
+       return WERR_OK;
 }
 
 /****************************************************************************
  Enumjobs at level 2.
 ****************************************************************************/
 
-static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
+static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
+                             const print_queue_struct *queue,
+                             uint32_t num_queues, int snum,
                               const NT_PRINTER_INFO_LEVEL *ntprinter,
-                             RPC_BUFFER *buffer, uint32 offered,
-                             uint32 *needed, uint32 *returned)
+                             union spoolss_JobInfo **info_p,
+                             uint32_t *count)
 {
-       JOB_INFO_2 *info = NULL;
+       union spoolss_JobInfo *info;
        int i;
        WERROR result = WERR_OK;
-       DEVICEMODE *devmode = NULL;
 
-       if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
-               *returned=0;
-               return WERR_NOMEM;
-       }
+       info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
+       W_ERROR_HAVE_NO_MEMORY(info);
 
-       /* this should not be a failure condition if the devmode is NULL */
+       *count = num_queues;
 
-       devmode = construct_dev_mode(lp_const_servicename(snum));
+       for (i=0; i<*count; i++) {
 
-       for (i=0; i<*returned; i++)
-               fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
+               struct spoolss_DeviceMode *devmode;
 
-       /* check the required size. */
-       for (i=0; i<*returned; i++)
-               (*needed) += spoolss_size_job_info_2(&info[i]);
+               devmode = construct_dev_mode_new(info, lp_const_servicename(snum));
+               if (!devmode) {
+                       result = WERR_NOMEM;
+                       goto out;
+               }
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
+               result = fill_job_info2(info,
+                                       &info[i].info2,
+                                       &queue[i],
+                                       i,
+                                       snum,
+                                       ntprinter,
+                                       devmode);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto out;
+               }
        }
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+ out:
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
        }
 
-       /* fill the buffer with the structures */
-       for (i=0; i<*returned; i++)
-               smb_io_job_info_2("", buffer, &info[i], 0);
-
-out:
-       free_devmode(devmode);
-       SAFE_FREE(info);
-
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
-
-       return result;
+       *info_p = info;
 
+       return WERR_OK;
 }
 
-/****************************************************************************
- Enumjobs.
-****************************************************************************/
+/****************************************************************
+ _spoolss_EnumJobs
+****************************************************************/
 
-WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
+WERROR _spoolss_EnumJobs(pipes_struct *p,
+                        struct spoolss_EnumJobs *r)
 {
-       POLICY_HND *handle = &q_u->handle;
-       uint32 level = q_u->level;
-       RPC_BUFFER *buffer = NULL;
-       uint32 offered = q_u->offered;
-       uint32 *needed = &r_u->needed;
-       uint32 *returned = &r_u->returned;
-       WERROR wret;
+       WERROR result;
        NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
        int snum;
        print_status_struct prt_status;
-       print_queue_struct *queue=NULL;
+       print_queue_struct *queue = NULL;
+       uint32_t count;
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer && (offered!=0)) {
-               return WERR_INVALID_PARAM;
-       }
-
-       if (offered > MAX_RPC_DATA_SIZE) {
+       if (!r->in.buffer && (r->in.offered != 0)) {
                return WERR_INVALID_PARAM;
        }
 
-       rpcbuf_move(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
-
-       DEBUG(4,("_spoolss_enumjobs\n"));
+       DEBUG(4,("_spoolss_EnumJobs\n"));
 
-       *needed=0;
-       *returned=0;
+       *r->out.needed = 0;
+       *r->out.count = 0;
+       *r->out.info = NULL;
 
        /* lookup the printer snum and tdb entry */
 
-       if (!get_printer_snum(p, handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
-       wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
-       if ( !W_ERROR_IS_OK(wret) )
-               return wret;
+       result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
-       *returned = print_queue_status(snum, &queue, &prt_status);
-       DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
+       count = print_queue_status(snum, &queue, &prt_status);
+       DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
+               count, prt_status.status, prt_status.message));
 
-       if (*returned == 0) {
+       if (count == 0) {
                SAFE_FREE(queue);
                free_a_printer(&ntprinter, 2);
                return WERR_OK;
        }
 
-       switch (level) {
+       switch (r->in.level) {
        case 1:
-               wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
+               result = enumjobs_level1(p->mem_ctx, queue, count, snum,
+                                        ntprinter, r->out.info, r->out.count);
                break;
        case 2:
-               wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
+               result = enumjobs_level2(p->mem_ctx, queue, count, snum,
+                                        ntprinter, r->out.info, r->out.count);
                break;
        default:
-               *returned=0;
-               wret = WERR_UNKNOWN_LEVEL;
+               result = WERR_UNKNOWN_LEVEL;
                break;
        }
 
        SAFE_FREE(queue);
-       free_a_printer( &ntprinter, 2 );
-       return wret;
+       free_a_printer(&ntprinter, 2);
+
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+                                                    spoolss_EnumJobs, NULL,
+                                                    *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);
 }
 
 /****************************************************************
@@ -6934,330 +6713,369 @@ WERROR _spoolss_SetJob(pipes_struct *p,
  Enumerates all printer drivers at level 1.
 ****************************************************************************/
 
-static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level1(TALLOC_CTX *mem_ctx,
+                                       const char *servername,
+                                       const char *architecture,
+                                       union spoolss_DriverInfo **info_p,
+                                       uint32_t *count)
 {
        int i;
        int ndrivers;
-       uint32 version;
+       uint32_t version;
        fstring *list = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
-       DRIVER_INFO_1 *driver_info_1=NULL;
+       union spoolss_DriverInfo *info = NULL;
        WERROR result = WERR_OK;
 
-       *returned=0;
+       *count = 0;
 
        for (version=0; version<DRIVER_MAX_VERSION; version++) {
-               list=NULL;
-               ndrivers=get_ntdrivers(&list, architecture, version);
-               DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
+               list = NULL;
+               ndrivers = get_ntdrivers(&list, architecture, version);
+               DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
+                       ndrivers, architecture, version));
 
-               if(ndrivers == -1) {
-                       SAFE_FREE(driver_info_1);
-                       return WERR_NOMEM;
+               if (ndrivers == -1) {
+                       result = WERR_NOMEM;
+                       goto out;
                }
 
-               if(ndrivers != 0) {
-                       if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
-                               DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
-                               SAFE_FREE(list);
-                               return WERR_NOMEM;
+               if (ndrivers != 0) {
+                       info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+                                                   union spoolss_DriverInfo,
+                                                   *count + ndrivers);
+                       if (!info) {
+                               DEBUG(0,("enumprinterdrivers_level1: "
+                                       "failed to enlarge driver info buffer!\n"));
+                               result = WERR_NOMEM;
+                               goto out;
                        }
                }
 
                for (i=0; i<ndrivers; i++) {
-                       WERROR status;
                        DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
                        ZERO_STRUCT(driver);
-                       status = get_a_printer_driver(&driver, 3, list[i],
+                       result = get_a_printer_driver(&driver, 3, list[i],
                                                      architecture, version);
-                       if (!W_ERROR_IS_OK(status)) {
-                               SAFE_FREE(list);
-                               SAFE_FREE(driver_info_1);
-                               return status;
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto out;
+                       }
+                       result = fill_printer_driver_info1(info, &info[*count+i].info1,
+                                                          &driver, servername,
+                                                          architecture);
+                       if (!W_ERROR_IS_OK(result)) {
+                               free_a_printer_driver(driver, 3);
+                               goto out;
                        }
-                       fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
                        free_a_printer_driver(driver, 3);
                }
 
-               *returned+=ndrivers;
+               *count += ndrivers;
                SAFE_FREE(list);
        }
 
-       /* check the required size. */
-       for (i=0; i<*returned; i++) {
-               DEBUGADD(6,("adding driver [%d]'s size\n",i));
-               *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
-       }
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-       }
+ out:
+       SAFE_FREE(list);
 
-       /* fill the buffer with the driver structures */
-       for (i=0; i<*returned; i++) {
-               DEBUGADD(6,("adding driver [%d] to buffer\n",i));
-               smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
        }
 
-out:
-       SAFE_FREE(driver_info_1);
-
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+       *info_p = info;
 
-       return result;
+       return WERR_OK;
 }
 
 /****************************************************************************
  Enumerates all printer drivers at level 2.
 ****************************************************************************/
 
-static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level2(TALLOC_CTX *mem_ctx,
+                                       const char *servername,
+                                       const char *architecture,
+                                       union spoolss_DriverInfo **info_p,
+                                       uint32_t *count)
 {
        int i;
        int ndrivers;
-       uint32 version;
+       uint32_t version;
        fstring *list = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
-       DRIVER_INFO_2 *driver_info_2=NULL;
+       union spoolss_DriverInfo *info = NULL;
        WERROR result = WERR_OK;
 
-       *returned=0;
+       *count = 0;
 
        for (version=0; version<DRIVER_MAX_VERSION; version++) {
-               list=NULL;
-               ndrivers=get_ntdrivers(&list, architecture, version);
-               DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
+               list = NULL;
+               ndrivers = get_ntdrivers(&list, architecture, version);
+               DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
+                       ndrivers, architecture, version));
 
-               if(ndrivers == -1) {
-                       SAFE_FREE(driver_info_2);
-                       return WERR_NOMEM;
+               if (ndrivers == -1) {
+                       result = WERR_NOMEM;
+                       goto out;
                }
 
-               if(ndrivers != 0) {
-                       if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
-                               DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
-                               SAFE_FREE(list);
-                               return WERR_NOMEM;
+               if (ndrivers != 0) {
+                       info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+                                                   union spoolss_DriverInfo,
+                                                   *count + ndrivers);
+                       if (!info) {
+                               DEBUG(0,("enumprinterdrivers_level2: "
+                                       "failed to enlarge driver info buffer!\n"));
+                               result = WERR_NOMEM;
+                               goto out;
                        }
                }
 
                for (i=0; i<ndrivers; i++) {
-                       WERROR status;
-
                        DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
                        ZERO_STRUCT(driver);
-                       status = get_a_printer_driver(&driver, 3, list[i],
+                       result = get_a_printer_driver(&driver, 3, list[i],
                                                      architecture, version);
-                       if (!W_ERROR_IS_OK(status)) {
-                               SAFE_FREE(list);
-                               SAFE_FREE(driver_info_2);
-                               return status;
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto out;
+                       }
+                       result = fill_printer_driver_info2(info, &info[*count+i].info2,
+                                                          &driver, servername);
+                       if (!W_ERROR_IS_OK(result)) {
+                               free_a_printer_driver(driver, 3);
+                               goto out;
                        }
-                       fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
                        free_a_printer_driver(driver, 3);
                }
 
-               *returned+=ndrivers;
+               *count += ndrivers;
                SAFE_FREE(list);
        }
 
-       /* check the required size. */
-       for (i=0; i<*returned; i++) {
-               DEBUGADD(6,("adding driver [%d]'s size\n",i));
-               *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
-       }
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-       }
+ out:
+       SAFE_FREE(list);
 
-       /* fill the buffer with the form structures */
-       for (i=0; i<*returned; i++) {
-               DEBUGADD(6,("adding driver [%d] to buffer\n",i));
-               smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
        }
 
-out:
-       SAFE_FREE(driver_info_2);
-
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+       *info_p = info;
 
-       return result;
+       return WERR_OK;
 }
 
 /****************************************************************************
  Enumerates all printer drivers at level 3.
 ****************************************************************************/
 
-static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level3(TALLOC_CTX *mem_ctx,
+                                       const char *servername,
+                                       const char *architecture,
+                                       union spoolss_DriverInfo **info_p,
+                                       uint32_t *count)
 {
        int i;
        int ndrivers;
-       uint32 version;
+       uint32_t version;
        fstring *list = NULL;
-       DRIVER_INFO_3 *driver_info_3=NULL;
+       union spoolss_DriverInfo *info = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
        WERROR result = WERR_OK;
 
-       *returned=0;
+       *count = 0;
 
        for (version=0; version<DRIVER_MAX_VERSION; version++) {
-               list=NULL;
-               ndrivers=get_ntdrivers(&list, architecture, version);
-               DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
+               list = NULL;
+               ndrivers = get_ntdrivers(&list, architecture, version);
+               DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
+                       ndrivers, architecture, version));
 
-               if(ndrivers == -1) {
-                       SAFE_FREE(driver_info_3);
-                       return WERR_NOMEM;
+               if (ndrivers == -1) {
+                       result = WERR_NOMEM;
+                       goto out;
                }
 
-               if(ndrivers != 0) {
-                       if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
-                               DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
-                               SAFE_FREE(list);
-                               return WERR_NOMEM;
+               if (ndrivers != 0) {
+                       info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+                                                   union spoolss_DriverInfo,
+                                                   *count + ndrivers);
+                       if (!info) {
+                               DEBUG(0,("enumprinterdrivers_level3: "
+                                       "failed to enlarge driver info buffer!\n"));
+                               result = WERR_NOMEM;
+                               goto out;
                        }
                }
 
                for (i=0; i<ndrivers; i++) {
-                       WERROR status;
-
                        DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
                        ZERO_STRUCT(driver);
-                       status = get_a_printer_driver(&driver, 3, list[i],
+                       result = get_a_printer_driver(&driver, 3, list[i],
                                                      architecture, version);
-                       if (!W_ERROR_IS_OK(status)) {
-                               SAFE_FREE(list);
-                               SAFE_FREE(driver_info_3);
-                               return status;
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto out;
+                       }
+                       result = fill_printer_driver_info3(info, &info[*count+i].info3,
+                                                          &driver, servername);
+                       if (!W_ERROR_IS_OK(result)) {
+                               free_a_printer_driver(driver, 3);
+                               goto out;
                        }
-                       fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
+
                        free_a_printer_driver(driver, 3);
                }
 
-               *returned+=ndrivers;
+               *count += ndrivers;
                SAFE_FREE(list);
        }
 
-       /* check the required size. */
-       for (i=0; i<*returned; i++) {
-               DEBUGADD(6,("adding driver [%d]'s size\n",i));
-               *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
-       }
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-       }
-
-       /* fill the buffer with the driver structures */
-       for (i=0; i<*returned; i++) {
-               DEBUGADD(6,("adding driver [%d] to buffer\n",i));
-               smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
-       }
+ out:
+       SAFE_FREE(list);
 
-out:
-       for (i=0; i<*returned; i++) {
-               SAFE_FREE(driver_info_3[i].dependentfiles);
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
        }
 
-       SAFE_FREE(driver_info_3);
-
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+       *info_p = info;
 
-       return result;
+       return WERR_OK;
 }
 
-/****************************************************************************
- Enumerates all printer drivers.
-****************************************************************************/
+/****************************************************************
+ _spoolss_EnumPrinterDrivers
+****************************************************************/
 
-WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
+WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
+                                  struct spoolss_EnumPrinterDrivers *r)
 {
-       uint32 level = q_u->level;
-       RPC_BUFFER *buffer = NULL;
-       uint32 offered = q_u->offered;
-       uint32 *needed = &r_u->needed;
-       uint32 *returned = &r_u->returned;
        const char *cservername;
-       fstring servername;
-       fstring architecture;
+       WERROR result;
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer && (offered!=0)) {
-               return WERR_INVALID_PARAM;
-       }
-
-       if (offered > MAX_RPC_DATA_SIZE) {
+       if (!r->in.buffer && (r->in.offered != 0)) {
                return WERR_INVALID_PARAM;
        }
 
-       rpcbuf_move(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+       DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
 
-       DEBUG(4,("_spoolss_enumprinterdrivers\n"));
-
-       *needed   = 0;
-       *returned = 0;
-
-       unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
-       unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
+       *r->out.needed = 0;
+       *r->out.count = 0;
+       *r->out.info = NULL;
 
-       cservername = canon_servername(servername);
+       cservername = canon_servername(r->in.server);
 
-       if (!is_myname_or_ipaddr(cservername))
+       if (!is_myname_or_ipaddr(cservername)) {
                return WERR_UNKNOWN_PRINTER_DRIVER;
+       }
 
-       switch (level) {
+       switch (r->in.level) {
        case 1:
-               return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
+               result = enumprinterdrivers_level1(p->mem_ctx, cservername,
+                                                  r->in.environment,
+                                                  r->out.info, r->out.count);
+               break;
        case 2:
-               return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
+               result = enumprinterdrivers_level2(p->mem_ctx, cservername,
+                                                  r->in.environment,
+                                                  r->out.info, r->out.count);
+               break;
        case 3:
-               return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
+               result = enumprinterdrivers_level3(p->mem_ctx, cservername,
+                                                  r->in.environment,
+                                                  r->out.info, r->out.count);
+               break;
        default:
                return WERR_UNKNOWN_LEVEL;
        }
+
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+                                                    spoolss_EnumPrinterDrivers, NULL,
+                                                    *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 fill_form_info_1(TALLOC_CTX *mem_ctx,
-                              struct spoolss_FormInfo1 *form,
-                              nt_forms_struct *list)
+                              struct spoolss_FormInfo1 *r,
+                              const nt_forms_struct *form)
+{
+       r->form_name    = talloc_strdup(mem_ctx, form->name);
+       W_ERROR_HAVE_NO_MEMORY(r->form_name);
+
+       r->flags        = form->flag;
+       r->size.width   = form->width;
+       r->size.height  = form->length;
+       r->area.left    = form->left;
+       r->area.top     = form->top;
+       r->area.right   = form->right;
+       r->area.bottom  = form->bottom;
+
+       return WERR_OK;
+}
+
+/****************************************************************
+ spoolss_enumforms_level1
+****************************************************************/
+
+static WERROR spoolss_enumforms_level1(TALLOC_CTX *mem_ctx,
+                                      const nt_forms_struct *builtin_forms,
+                                      uint32_t num_builtin_forms,
+                                      const nt_forms_struct *user_forms,
+                                      uint32_t num_user_forms,
+                                      union spoolss_FormInfo **info_p,
+                                      uint32_t *count)
 {
-       form->form_name         = talloc_strdup(mem_ctx, list->name);
-       W_ERROR_HAVE_NO_MEMORY(form->form_name);
+       union spoolss_FormInfo *info;
+       WERROR result = WERR_OK;
+       int i;
+
+       *count = num_builtin_forms + num_user_forms;
+
+       info = TALLOC_ARRAY(mem_ctx, union spoolss_FormInfo, *count);
+       W_ERROR_HAVE_NO_MEMORY(info);
+
+       /* construct the list of form structures */
+       for (i=0; i<num_builtin_forms; i++) {
+               DEBUGADD(6,("Filling form number [%d]\n",i));
+               result = fill_form_info_1(info, &info[i].info1,
+                                         &builtin_forms[i]);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto out;
+               }
+       }
+
+       for (; i<num_user_forms; i++) {
+               DEBUGADD(6,("Filling form number [%d]\n",i));
+               result = fill_form_info_1(info, &info[i].info1,
+                                         &user_forms[i-num_builtin_forms]);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto out;
+               }
+       }
 
-       form->flags             = list->flag;
-       form->size.width        = list->width;
-       form->size.height       = list->length;
-       form->area.left         = list->left;
-       form->area.top          = list->top;
-       form->area.right        = list->right;
-       form->area.bottom       = list->bottom;
+ out:
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
+       }
+
+       *info_p = info;
 
        return WERR_OK;
 }
@@ -7269,15 +7087,15 @@ static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
 WERROR _spoolss_EnumForms(pipes_struct *p,
                          struct spoolss_EnumForms *r)
 {
-       nt_forms_struct *list=NULL;
-       nt_forms_struct *builtinlist=NULL;
-       union spoolss_FormInfo *info;
-       uint32_t count;
-       uint32_t numbuiltinforms;
-       size_t buffer_size = 0;
-       int i;
+       WERROR result;
+       nt_forms_struct *user_forms = NULL;
+       nt_forms_struct *builtin_forms = NULL;
+       uint32_t num_user_forms;
+       uint32_t num_builtin_forms;
 
        *r->out.count = 0;
+       *r->out.needed = 0;
+       *r->out.info = NULL;
 
        /* that's an [in out] buffer */
 
@@ -7289,69 +7107,85 @@ WERROR _spoolss_EnumForms(pipes_struct *p,
        DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
        DEBUGADD(5,("Info level [%d]\n",          r->in.level));
 
-       numbuiltinforms = get_builtin_ntforms(&builtinlist);
-       DEBUGADD(5,("Number of builtin forms [%d]\n",     numbuiltinforms));
-       count = get_ntforms(&list);
-       DEBUGADD(5,("Number of user forms [%d]\n",     count));
-       count += numbuiltinforms;
+       num_builtin_forms = get_builtin_ntforms(&builtin_forms);
+       DEBUGADD(5,("Number of builtin forms [%d]\n", num_builtin_forms));
+       num_user_forms = get_ntforms(&user_forms);
+       DEBUGADD(5,("Number of user forms [%d]\n", num_user_forms));
 
-       if (count == 0) {
-               SAFE_FREE(builtinlist);
-               SAFE_FREE(list);
+       if (num_user_forms + num_builtin_forms == 0) {
+               SAFE_FREE(builtin_forms);
+               SAFE_FREE(user_forms);
                return WERR_NO_MORE_ITEMS;
        }
 
-       info = TALLOC_ARRAY(p->mem_ctx, union spoolss_FormInfo, count);
-       if (!info) {
-               SAFE_FREE(builtinlist);
-               SAFE_FREE(list);
-               return WERR_NOMEM;
-       }
-
        switch (r->in.level) {
        case 1:
-               /* construct the list of form structures */
-               for (i=0; i<numbuiltinforms; i++) {
-                       DEBUGADD(6,("Filling form number [%d]\n",i));
-                       fill_form_info_1(info, &info[i].info1, &builtinlist[i]);
-               }
-
-               SAFE_FREE(builtinlist);
+               result = spoolss_enumforms_level1(p->mem_ctx,
+                                                 builtin_forms,
+                                                 num_builtin_forms,
+                                                 user_forms,
+                                                 num_user_forms,
+                                                 r->out.info,
+                                                 r->out.count);
+               break;
+       default:
+               result = WERR_UNKNOWN_LEVEL;
+               break;
+       }
 
-               for (; i<count; i++) {
-                       DEBUGADD(6,("Filling form number [%d]\n",i));
-                       fill_form_info_1(info, &info[i].info1, &list[i-numbuiltinforms]);
-               }
+       SAFE_FREE(user_forms);
+       SAFE_FREE(builtin_forms);
 
-               SAFE_FREE(list);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
-               /* check the required size. */
-               for (i=0; i<numbuiltinforms; i++) {
-                       DEBUGADD(6,("adding form [%d]'s size\n",i));
-                       buffer_size += ndr_size_spoolss_FormInfo1(&info[i].info1, NULL, 0);
-               }
-               for (; i<count; i++) {
-                       DEBUGADD(6,("adding form [%d]'s size\n",i));
-                       buffer_size += ndr_size_spoolss_FormInfo1(&info[i].info1, NULL, 0);
-               }
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+                                                    spoolss_EnumForms, NULL,
+                                                    *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);
 
-               *r->out.needed = buffer_size;
+       return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+}
 
-               if (*r->out.needed > r->in.offered) {
-                       TALLOC_FREE(info);
-                       return WERR_INSUFFICIENT_BUFFER;
-               }
+/****************************************************************
+****************************************************************/
 
-               *r->out.count = count;
-               *r->out.info = info;
+static WERROR find_form_byname(const char *name,
+                              nt_forms_struct *form)
+{
+       nt_forms_struct *list = NULL;
+       int num_forms = 0, i = 0;
 
+       if (get_a_builtin_ntform_by_string(name, form)) {
                return WERR_OK;
+       }
 
-       default:
-               SAFE_FREE(list);
-               SAFE_FREE(builtinlist);
-               return WERR_UNKNOWN_LEVEL;
+       num_forms = get_ntforms(&list);
+       DEBUGADD(5,("Number of forms [%d]\n", num_forms));
+
+       if (num_forms == 0) {
+               return WERR_BADFID;
+       }
+
+       /* Check if the requested name is in the list of form structures */
+       for (i = 0; i < num_forms; i++) {
+
+               DEBUG(4,("checking form %s (want %s)\n", list[i].name, name));
+
+               if (strequal(name, list[i].name)) {
+                       DEBUGADD(6,("Found form %s number [%d]\n", name, i));
+                       *form = list[i];
+                       SAFE_FREE(list);
+                       return WERR_OK;
+               }
        }
+
+       SAFE_FREE(list);
+
+       return WERR_BADFID;
 }
 
 /****************************************************************
@@ -7361,86 +7195,47 @@ WERROR _spoolss_EnumForms(pipes_struct *p,
 WERROR _spoolss_GetForm(pipes_struct *p,
                        struct spoolss_GetForm *r)
 {
-       uint32 level = r->in.level;
-       uint32 offered = r->in.offered;
-       uint32 *needed = r->out.needed;
-
-       nt_forms_struct *list=NULL;
-       nt_forms_struct builtin_form;
-       bool foundBuiltin;
-       union spoolss_FormInfo info;
-       struct spoolss_FormInfo1 form_1;
-       int numofforms=0, i=0;
+       WERROR result;
+       nt_forms_struct form;
 
        /* that's an [in out] buffer */
 
-       if (!r->in.buffer && (offered!=0)) {
+       if (!r->in.buffer && (r->in.offered != 0)) {
                return WERR_INVALID_PARAM;
        }
 
        DEBUG(4,("_spoolss_GetForm\n"));
-       DEBUGADD(5,("Offered buffer size [%d]\n", offered));
-       DEBUGADD(5,("Info level [%d]\n",          level));
-
-       foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
-       if (!foundBuiltin) {
-               numofforms = get_ntforms(&list);
-               DEBUGADD(5,("Number of forms [%d]\n",     numofforms));
+       DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
+       DEBUGADD(5,("Info level [%d]\n",          r->in.level));
 
-               if (numofforms == 0)
-                       return WERR_BADFID;
+       result = find_form_byname(r->in.form_name, &form);
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(r->out.info);
+               return result;
        }
 
-       ZERO_STRUCT(form_1);
-
-       switch (level) {
+       switch (r->in.level) {
        case 1:
-               if (foundBuiltin) {
-                       fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
-               } else {
-
-                       /* Check if the requested name is in the list of form structures */
-                       for (i=0; i<numofforms; i++) {
-
-                               DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
-                                       list[i].name, r->in.form_name));
-
-                               if (strequal(r->in.form_name, list[i].name)) {
-                                       DEBUGADD(6,("Found form %s number [%d]\n",
-                                               r->in.form_name, i));
-                                       fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
-                                       break;
-                               }
-                       }
-
-                       SAFE_FREE(list);
-                       if (i == numofforms) {
-                               return WERR_BADFID;
-                       }
-               }
-               /* check the required size. */
-
-               info.info1 = form_1;
-
-               *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
-
-               if (*needed > offered) {
-                       r->out.info = NULL;
-                       return WERR_INSUFFICIENT_BUFFER;
-               }
+               result = fill_form_info_1(p->mem_ctx,
+                                         &r->out.info->info1,
+                                         &form);
+               break;
 
-               r->out.info->info1 = form_1;
+       default:
+               result = WERR_UNKNOWN_LEVEL;
+               break;
+       }
 
-               /* fill the buffer with the form structures */
-               DEBUGADD(6,("adding form %s [%d] to buffer\n",
-                       r->in.form_name, i));
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(r->out.info);
+               return result;
+       }
 
-               return WERR_OK;
+       *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, NULL,
+                                              r->out.info, r->in.level);
+       r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
 
-       default:
-               SAFE_FREE(list);
-               return WERR_UNKNOWN_LEVEL;
-       }
+       return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 }
 
 /****************************************************************************
@@ -7547,8 +7342,6 @@ WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
 
 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
                                union spoolss_PortInfo **info_p,
-                               uint32_t offered,
-                               uint32_t *needed,
                                uint32_t *count)
 {
        union spoolss_PortInfo *info = NULL;
@@ -7572,24 +7365,13 @@ static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
 
                for (i=0; i<numlines; i++) {
                        DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
-                       result = fill_port_1(info, &info[i].info1, qlines[i]);
-                       if (!W_ERROR_IS_OK(result)) {
-                               goto out;
-                       }
-               }
-       }
-       TALLOC_FREE(qlines);
-
-       /* check the required size. */
-       for (i=0; i<numlines; i++) {
-               DEBUGADD(6,("adding port [%d]'s size\n", i));
-               *needed += ndr_size_spoolss_PortInfo1(&info[i].info1, NULL, 0);
-       }
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
+                       result = fill_port_1(info, &info[i].info1, qlines[i]);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto out;
+                       }
+               }
        }
+       TALLOC_FREE(qlines);
 
 out:
        if (!W_ERROR_IS_OK(result)) {
@@ -7612,8 +7394,6 @@ out:
 
 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
                                union spoolss_PortInfo **info_p,
-                               uint32_t offered,
-                               uint32_t *needed,
                                uint32_t *count)
 {
        union spoolss_PortInfo *info = NULL;
@@ -7645,17 +7425,6 @@ static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
        }
        TALLOC_FREE(qlines);
 
-       /* check the required size. */
-       for (i=0; i<numlines; i++) {
-               DEBUGADD(6,("adding port [%d]'s size\n", i));
-               *needed += ndr_size_spoolss_PortInfo2(&info[i].info2, NULL, 0);
-       }
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
 out:
        if (!W_ERROR_IS_OK(result)) {
                TALLOC_FREE(info);
@@ -7678,6 +7447,8 @@ out:
 WERROR _spoolss_EnumPorts(pipes_struct *p,
                          struct spoolss_EnumPorts *r)
 {
+       WERROR result;
+
        /* that's an [in out] buffer */
 
        if (!r->in.buffer && (r->in.offered != 0)) {
@@ -7692,16 +7463,29 @@ WERROR _spoolss_EnumPorts(pipes_struct *p,
 
        switch (r->in.level) {
        case 1:
-               return enumports_level_1(p->mem_ctx, r->out.info,
-                                        r->in.offered, r->out.needed,
-                                        r->out.count);
+               result = enumports_level_1(p->mem_ctx, r->out.info,
+                                          r->out.count);
+               break;
        case 2:
-               return enumports_level_2(p->mem_ctx, r->out.info,
-                                        r->in.offered, r->out.needed,
-                                        r->out.count);
+               result = enumports_level_2(p->mem_ctx, r->out.info,
+                                          r->out.count);
+               break;
        default:
                return WERR_UNKNOWN_LEVEL;
        }
+
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+                                                    spoolss_EnumPorts, NULL,
+                                                    *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);
 }
 
 /****************************************************************************
@@ -8106,9 +7890,7 @@ static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
                                          const char *servername,
                                          const char *environment,
-                                         struct spoolss_DriverDirectoryInfo1 *r,
-                                         uint32_t offered,
-                                         uint32_t *needed)
+                                         struct spoolss_DriverDirectoryInfo1 *r)
 {
        WERROR werr;
        char *path = NULL;
@@ -8126,13 +7908,6 @@ static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
 
        r->directory_name = path;
 
-       *needed += ndr_size_spoolss_DriverDirectoryInfo1(r, NULL, 0);
-
-       if (*needed > offered) {
-               talloc_free(path);
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
        return WERR_OK;
 }
 
@@ -8161,14 +7936,17 @@ WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
        werror = getprinterdriverdir_level_1(p->mem_ctx,
                                             r->in.server,
                                             r->in.environment,
-                                            &r->out.info->info1,
-                                            r->in.offered,
-                                            r->out.needed);
+                                            &r->out.info->info1);
        if (!W_ERROR_IS_OK(werror)) {
                TALLOC_FREE(r->out.info);
+               return werror;
        }
 
-       return werror;
+       *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, NULL,
+                                              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);
 }
 
 /****************************************************************************
@@ -8757,8 +8535,6 @@ static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
 
 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
                                          union spoolss_PrintProcessorInfo **info_p,
-                                         uint32_t offered,
-                                         uint32_t *needed,
                                          uint32_t *count)
 {
        union spoolss_PrintProcessorInfo *info;
@@ -8774,13 +8550,6 @@ static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
                goto out;
        }
 
-       *needed += ndr_size_spoolss_PrintProcessorInfo1(&info[0].info1, NULL, 0);
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
  out:
        if (!W_ERROR_IS_OK(result)) {
                TALLOC_FREE(info);
@@ -8800,6 +8569,8 @@ static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
                                    struct spoolss_EnumPrintProcessors *r)
 {
+       WERROR result;
+
        /* that's an [in out] buffer */
 
        if (!r->in.buffer && (r->in.offered != 0)) {
@@ -8821,12 +8592,25 @@ WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
 
        switch (r->in.level) {
        case 1:
-               return enumprintprocessors_level_1(p->mem_ctx, r->out.info,
-                                                  r->in.offered, r->out.needed,
-                                                  r->out.count);
+               result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
+                                                    r->out.count);
+               break;
        default:
                return WERR_UNKNOWN_LEVEL;
        }
+
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+                                                    spoolss_EnumPrintProcessors, NULL,
+                                                    *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);
 }
 
 /****************************************************************************
@@ -8849,8 +8633,6 @@ static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
 
 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
                                             union spoolss_PrintProcDataTypesInfo **info_p,
-                                            uint32_t offered,
-                                            uint32_t *needed,
                                             uint32_t *count)
 {
        WERROR result;
@@ -8866,13 +8648,6 @@ static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
                goto out;
        }
 
-       *needed += ndr_size_spoolss_PrintProcDataTypesInfo1(&info[0].info1, NULL, 0);
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
  out:
        if (!W_ERROR_IS_OK(result)) {
                TALLOC_FREE(info);
@@ -8892,6 +8667,8 @@ static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
                                       struct spoolss_EnumPrintProcDataTypes *r)
 {
+       WERROR result;
+
        /* that's an [in out] buffer */
 
        if (!r->in.buffer && (r->in.offered != 0)) {
@@ -8906,12 +8683,21 @@ WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
 
        switch (r->in.level) {
        case 1:
-               return enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
-                                                     r->in.offered, r->out.needed,
-                                                     r->out.count);
+               result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
+                                                       r->out.count);
+               break;
        default:
                return WERR_UNKNOWN_LEVEL;
        }
+
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+                                                    spoolss_EnumPrintProcDataTypes, NULL,
+                                                    *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);
 }
 
 /****************************************************************************
@@ -8954,13 +8740,10 @@ static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
 
 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
                                        union spoolss_MonitorInfo **info_p,
-                                       uint32_t offered,
-                                       uint32_t *needed,
                                        uint32_t *count)
 {
        union spoolss_MonitorInfo *info;
        WERROR result = WERR_OK;
-       int i;
 
        info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
        W_ERROR_HAVE_NO_MEMORY(info);
@@ -8979,15 +8762,6 @@ static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
                goto out;
        }
 
-       for (i=0; i<*count; i++) {
-               *needed += ndr_size_spoolss_MonitorInfo1(&info[i].info1, NULL, 0);
-       }
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
 out:
        if (!W_ERROR_IS_OK(result)) {
                TALLOC_FREE(info);
@@ -9006,13 +8780,10 @@ out:
 
 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
                                        union spoolss_MonitorInfo **info_p,
-                                       uint32_t offered,
-                                       uint32_t *needed,
                                        uint32_t *count)
 {
        union spoolss_MonitorInfo *info;
        WERROR result = WERR_OK;
-       int i;
 
        info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
        W_ERROR_HAVE_NO_MEMORY(info);
@@ -9035,15 +8806,6 @@ static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
                goto out;
        }
 
-       for (i=0; i<*count; i++) {
-               *needed += ndr_size_spoolss_MonitorInfo2(&info[i].info2, NULL, 0);
-       }
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
 out:
        if (!W_ERROR_IS_OK(result)) {
                TALLOC_FREE(info);
@@ -9063,6 +8825,8 @@ out:
 WERROR _spoolss_EnumMonitors(pipes_struct *p,
                             struct spoolss_EnumMonitors *r)
 {
+       WERROR result;
+
        /* that's an [in out] buffer */
 
        if (!r->in.buffer && (r->in.offered != 0)) {
@@ -9084,101 +8848,89 @@ WERROR _spoolss_EnumMonitors(pipes_struct *p,
 
        switch (r->in.level) {
        case 1:
-               return enumprintmonitors_level_1(p->mem_ctx, r->out.info,
-                                                r->in.offered, r->out.needed,
-                                                r->out.count);
+               result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
+                                                  r->out.count);
+               break;
        case 2:
-               return enumprintmonitors_level_2(p->mem_ctx, r->out.info,
-                                                r->in.offered, r->out.needed,
-                                                r->out.count);
+               result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
+                                                  r->out.count);
+               break;
        default:
                return WERR_UNKNOWN_LEVEL;
        }
+
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
+                                                    spoolss_EnumMonitors, NULL,
+                                                    *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 getjob_level_1(print_queue_struct **queue, int count, int snum,
-                             NT_PRINTER_INFO_LEVEL *ntprinter,
-                             uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
-                            uint32 *needed)
+static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
+                            const print_queue_struct *queue,
+                            int count, int snum,
+                            const NT_PRINTER_INFO_LEVEL *ntprinter,
+                            uint32_t jobid,
+                            struct spoolss_JobInfo1 *r)
 {
-       int i=0;
-       bool found=False;
-       JOB_INFO_1 *info_1=NULL;
-       WERROR result = WERR_OK;
-
-       info_1=SMB_MALLOC_P(JOB_INFO_1);
+       int i = 0;
+       bool found = false;
 
-       if (info_1 == NULL) {
-               return WERR_NOMEM;
-       }
-
-       for (i=0; i<count && found==False; i++) {
-               if ((*queue)[i].job==(int)jobid)
-                       found=True;
+       for (i=0; i<count && found == false; i++) {
+               if (queue[i].job == (int)jobid) {
+                       found = true;
+               }
        }
 
-       if (found==False) {
-               SAFE_FREE(info_1);
+       if (found == false) {
                /* NT treats not found as bad param... yet another bad choice */
                return WERR_INVALID_PARAM;
        }
 
-       fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
-
-       *needed += spoolss_size_job_info_1(info_1);
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
-
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-       }
-
-       smb_io_job_info_1("", buffer, info_1, 0);
-
-out:
-       SAFE_FREE(info_1);
-
-       return result;
+       return fill_job_info1(mem_ctx,
+                             r,
+                             &queue[i-1],
+                             i,
+                             snum,
+                             ntprinter);
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
-                             NT_PRINTER_INFO_LEVEL *ntprinter,
-                             uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
-                            uint32 *needed)
-{
-       int             i = 0;
-       bool            found = False;
-       JOB_INFO_2      *info_2;
-       WERROR          result;
-       DEVICEMODE      *devmode = NULL;
-       NT_DEVICEMODE   *nt_devmode = NULL;
-
-       if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
-               return WERR_NOMEM;
-
-       ZERO_STRUCTP(info_2);
+static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
+                            const print_queue_struct *queue,
+                            int count, int snum,
+                            const NT_PRINTER_INFO_LEVEL *ntprinter,
+                            uint32_t jobid,
+                            struct spoolss_JobInfo2 *r)
+{
+       int i = 0;
+       bool found = false;
+       struct spoolss_DeviceMode *devmode;
+       NT_DEVICEMODE *nt_devmode;
+       WERROR result;
 
-       for ( i=0; i<count && found==False; i++ )
-       {
-               if ((*queue)[i].job == (int)jobid)
-                       found = True;
+       for (i=0; i<count && found == false; i++) {
+               if (queue[i].job == (int)jobid) {
+                       found = true;
+               }
        }
 
-       if ( !found ) {
+       if (found == false) {
                /* NT treats not found as bad param... yet another bad
                   choice */
-               result = WERR_INVALID_PARAM;
-               goto done;
+               return WERR_INVALID_PARAM;
        }
 
        /*
@@ -9187,54 +8939,36 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
         *  a failure condition
         */
 
-       if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
-               devmode = construct_dev_mode(lp_const_servicename(snum));
-       else {
-               if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
-                       ZERO_STRUCTP( devmode );
-                       convert_nt_devicemode( devmode, nt_devmode );
+       nt_devmode = print_job_devmode(lp_const_servicename(snum), jobid);
+       if (nt_devmode) {
+               devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
+               W_ERROR_HAVE_NO_MEMORY(devmode);
+               result = convert_nt_devicemode_new(devmode, devmode, nt_devmode);
+               if (!W_ERROR_IS_OK(result)) {
+                       return result;
                }
+       } else {
+               devmode = construct_dev_mode_new(mem_ctx, lp_const_servicename(snum));
+               W_ERROR_HAVE_NO_MEMORY(devmode);
        }
 
-       fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
-
-       *needed += spoolss_size_job_info_2(info_2);
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto done;
-       }
-
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto done;
-       }
-
-       smb_io_job_info_2("", buffer, info_2, 0);
-
-       result = WERR_OK;
-
- done:
-       /* Cleanup allocated memory */
-
-       free_job_info_2(info_2);        /* Also frees devmode */
-       SAFE_FREE(info_2);
-
-       return result;
+       return fill_job_info2(mem_ctx,
+                             r,
+                             &queue[i-1],
+                             i,
+                             snum,
+                             ntprinter,
+                             devmode);
 }
 
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_GetJob
+****************************************************************/
 
-WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
+WERROR _spoolss_GetJob(pipes_struct *p,
+                      struct spoolss_GetJob *r)
 {
-       POLICY_HND *handle = &q_u->handle;
-       uint32 jobid = q_u->jobid;
-       uint32 level = q_u->level;
-       RPC_BUFFER *buffer = NULL;
-       uint32 offered = q_u->offered;
-       uint32 *needed = &r_u->needed;
-       WERROR          wstatus = WERR_OK;
+       WERROR result = WERR_OK;
        NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
        int snum;
        int count;
@@ -9243,51 +8977,57 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer && (offered!=0)) {
-               return WERR_INVALID_PARAM;
-       }
-
-       if (offered > MAX_RPC_DATA_SIZE) {
+       if (!r->in.buffer && (r->in.offered != 0)) {
                return WERR_INVALID_PARAM;
        }
 
-       rpcbuf_move(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+       DEBUG(5,("_spoolss_GetJob\n"));
 
-       DEBUG(5,("spoolss_getjob\n"));
-
-       *needed = 0;
+       *r->out.needed = 0;
 
-       if (!get_printer_snum(p, handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
-       wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
-       if ( !W_ERROR_IS_OK(wstatus) )
-               return wstatus;
+       result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
        count = print_queue_status(snum, &queue, &prt_status);
 
        DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
                     count, prt_status.status, prt_status.message));
 
-       switch ( level ) {
+       switch (r->in.level) {
        case 1:
-                       wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
-                               buffer, offered, needed);
-                       break;
+               result = getjob_level_1(p->mem_ctx,
+                                       queue, count, snum, ntprinter,
+                                       r->in.job_id, &r->out.info->info1);
+               break;
        case 2:
-                       wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
-                               buffer, offered, needed);
-                       break;
+               result = getjob_level_2(p->mem_ctx,
+                                       queue, count, snum, ntprinter,
+                                       r->in.job_id, &r->out.info->info2);
+               break;
        default:
-                       wstatus = WERR_UNKNOWN_LEVEL;
-                       break;
+               result = WERR_UNKNOWN_LEVEL;
+               break;
        }
 
        SAFE_FREE(queue);
-       free_a_printer( &ntprinter, 2 );
+       free_a_printer(&ntprinter, 2);
 
-       return wstatus;
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(r->out.info);
+               return result;
+       }
+
+       *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, NULL,
+                                              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);
 }
 
 /****************************************************************
@@ -9812,9 +9552,7 @@ done:
 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
                                                 const char *servername,
                                                 const char *environment,
-                                                struct spoolss_PrintProcessorDirectoryInfo1 *r,
-                                                uint32_t offered,
-                                                uint32_t *needed)
+                                                struct spoolss_PrintProcessorDirectoryInfo1 *r)
 {
        WERROR werr;
        char *path = NULL;
@@ -9832,13 +9570,6 @@ static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
 
        r->directory_name = path;
 
-       *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(r, NULL, 0);
-
-       if (*needed > offered) {
-               talloc_free(path);
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
        return WERR_OK;
 }
 
@@ -9867,14 +9598,17 @@ WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
        result = getprintprocessordirectory_level_1(p->mem_ctx,
                                                    r->in.server,
                                                    r->in.environment,
-                                                   &r->out.info->info1,
-                                                   r->in.offered,
-                                                   r->out.needed);
+                                                   &r->out.info->info1);
        if (!W_ERROR_IS_OK(result)) {
                TALLOC_FREE(r->out.info);
+               return result;
        }
 
-       return result;
+       *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo, NULL,
+                                              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);
 }
 
 /*******************************************************************
@@ -10207,39 +9941,6 @@ WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
        return WERR_OK;
 }
 
-/****************************************************************
- _spoolss_EnumPrinters
-****************************************************************/
-
-WERROR _spoolss_EnumPrinters(pipes_struct *p,
-                            struct spoolss_EnumPrinters *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_GetJob
-****************************************************************/
-
-WERROR _spoolss_GetJob(pipes_struct *p,
-                      struct spoolss_GetJob *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_EnumJobs
-****************************************************************/
-
-WERROR _spoolss_EnumJobs(pipes_struct *p,
-                        struct spoolss_EnumJobs *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
 /****************************************************************
  _spoolss_AddPrinter
 ****************************************************************/
@@ -10251,28 +9952,6 @@ WERROR _spoolss_AddPrinter(pipes_struct *p,
        return WERR_NOT_SUPPORTED;
 }
 
-/****************************************************************
- _spoolss_GetPrinter
-****************************************************************/
-
-WERROR _spoolss_GetPrinter(pipes_struct *p,
-                          struct spoolss_GetPrinter *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_EnumPrinterDrivers
-****************************************************************/
-
-WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
-                                  struct spoolss_EnumPrinterDrivers *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
 /****************************************************************
  _spoolss_GetPrinterDriver
 ****************************************************************/
@@ -10482,17 +10161,6 @@ WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
        return WERR_NOT_SUPPORTED;
 }
 
-/****************************************************************
- _spoolss_GetPrinterDriver2
-****************************************************************/
-
-WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
-                                 struct spoolss_GetPrinterDriver2 *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
 /****************************************************************
  _spoolss_FindFirstPrinterChangeNotification
 ****************************************************************/
index 6cbdf89583fc9e1b4e12837955cdab9ebf5fa818..33fff2e3b3a24df21aa26de12bf4f4bfec7a538c 100644 (file)
@@ -137,57 +137,45 @@ static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli,
 /****************************************************************************
 ****************************************************************************/
 
-static void display_print_info_0(PRINTER_INFO_0 *i0)
+static void display_print_info0(struct spoolss_PrinterInfo0 *r)
 {
-       fstring name = "";
-       fstring servername = "";
-
-       if (!i0)
+       if (!r)
                return;
 
-       rpcstr_pull(name, i0->printername.buffer, sizeof(name), -1, STR_TERMINATE);
-
-       rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), -1,STR_TERMINATE);
-
-       printf("\tprintername:[%s]\n", name);
-       printf("\tservername:[%s]\n", servername);
-       printf("\tcjobs:[0x%x]\n", i0->cjobs);
-       printf("\ttotal_jobs:[0x%x]\n", i0->total_jobs);
-
-       printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0->year, i0->month,
-              i0->day, i0->dayofweek);
-       printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0->hour, i0->minute,
-              i0->second, i0->milliseconds);
-
-       printf("\tglobal_counter:[0x%x]\n", i0->global_counter);
-       printf("\ttotal_pages:[0x%x]\n", i0->total_pages);
-
-       printf("\tmajorversion:[0x%x]\n", i0->major_version);
-       printf("\tbuildversion:[0x%x]\n", i0->build_version);
-
-       printf("\tunknown7:[0x%x]\n", i0->unknown7);
-       printf("\tunknown8:[0x%x]\n", i0->unknown8);
-       printf("\tunknown9:[0x%x]\n", i0->unknown9);
-       printf("\tsession_counter:[0x%x]\n", i0->session_counter);
-       printf("\tunknown11:[0x%x]\n", i0->unknown11);
-       printf("\tprinter_errors:[0x%x]\n", i0->printer_errors);
-       printf("\tunknown13:[0x%x]\n", i0->unknown13);
-       printf("\tunknown14:[0x%x]\n", i0->unknown14);
-       printf("\tunknown15:[0x%x]\n", i0->unknown15);
-       printf("\tunknown16:[0x%x]\n", i0->unknown16);
-       printf("\tchange_id:[0x%x]\n", i0->change_id);
-       printf("\tunknown18:[0x%x]\n", i0->unknown18);
-       printf("\tstatus:[0x%x]\n", i0->status);
-       printf("\tunknown20:[0x%x]\n", i0->unknown20);
-       printf("\tc_setprinter:[0x%x]\n", i0->c_setprinter);
-       printf("\tunknown22:[0x%x]\n", i0->unknown22);
-       printf("\tunknown23:[0x%x]\n", i0->unknown23);
-       printf("\tunknown24:[0x%x]\n", i0->unknown24);
-       printf("\tunknown25:[0x%x]\n", i0->unknown25);
-       printf("\tunknown26:[0x%x]\n", i0->unknown26);
-       printf("\tunknown27:[0x%x]\n", i0->unknown27);
-       printf("\tunknown28:[0x%x]\n", i0->unknown28);
-       printf("\tunknown29:[0x%x]\n", i0->unknown29);
+       printf("\tprintername:[%s]\n", r->printername);
+       printf("\tservername:[%s]\n", r->servername);
+       printf("\tcjobs:[0x%x]\n", r->cjobs);
+       printf("\ttotal_jobs:[0x%x]\n", r->total_jobs);
+       printf("\ttotal_bytes:[0x%x]\n", r->total_bytes);
+       printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r->time.year, r->time.month,
+              r->time.day, r->time.day_of_week);
+       printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r->time.hour, r->time.minute,
+              r->time.second, r->time.millisecond);
+
+       printf("\tglobal_counter:[0x%x]\n", r->global_counter);
+       printf("\ttotal_pages:[0x%x]\n", r->total_pages);
+
+       printf("\tversion:[0x%x]\n", r->version);
+       printf("\tfree_build:[0x%x]\n", r->free_build);
+       printf("\tspooling:[0x%x]\n", r->spooling);
+       printf("\tmax_spooling:[0x%x]\n", r->max_spooling);
+       printf("\tsession_counter:[0x%x]\n", r->session_counter);
+       printf("\tnum_error_out_of_paper:[0x%x]\n", r->num_error_out_of_paper);
+       printf("\tnum_error_not_ready:[0x%x]\n", r->num_error_not_ready);
+       printf("\tjob_error:[0x%x]\n", r->job_error);
+       printf("\tnumber_of_processors:[0x%x]\n", r->number_of_processors);
+       printf("\tprocessor_type:[0x%x]\n", r->processor_type);
+       printf("\thigh_part_total_bytes:[0x%x]\n", r->high_part_total_bytes);
+       printf("\tchange_id:[0x%x]\n", r->change_id);
+       printf("\tlast_error: %s\n", win_errstr(r->last_error));
+       printf("\tstatus:[0x%x]\n", r->status);
+       printf("\tenumerate_network_printers:[0x%x]\n", r->enumerate_network_printers);
+       printf("\tc_setprinter:[0x%x]\n", r->c_setprinter);
+       printf("\tprocessor_architecture:[0x%x]\n", r->processor_architecture);
+       printf("\tprocessor_level:[0x%x]\n", r->processor_level);
+       printf("\tref_ic:[0x%x]\n", r->ref_ic);
+       printf("\treserved2:[0x%x]\n", r->reserved2);
+       printf("\treserved3:[0x%x]\n", r->reserved3);
 
        printf("\n");
 }
@@ -195,22 +183,12 @@ static void display_print_info_0(PRINTER_INFO_0 *i0)
 /****************************************************************************
 ****************************************************************************/
 
-static void display_print_info_1(PRINTER_INFO_1 *i1)
+static void display_print_info1(struct spoolss_PrinterInfo1 *r)
 {
-       fstring desc = "";
-       fstring name = "";
-       fstring comm = "";
-
-       rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1,
-                   STR_TERMINATE);
-
-       rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
-       rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), -1, STR_TERMINATE);
-
-       printf("\tflags:[0x%x]\n", i1->flags);
-       printf("\tname:[%s]\n", name);
-       printf("\tdescription:[%s]\n", desc);
-       printf("\tcomment:[%s]\n", comm);
+       printf("\tflags:[0x%x]\n", r->flags);
+       printf("\tname:[%s]\n", r->name);
+       printf("\tdescription:[%s]\n", r->description);
+       printf("\tcomment:[%s]\n", r->comment);
 
        printf("\n");
 }
@@ -218,54 +196,30 @@ static void display_print_info_1(PRINTER_INFO_1 *i1)
 /****************************************************************************
 ****************************************************************************/
 
-static void display_print_info_2(PRINTER_INFO_2 *i2)
-{
-       fstring servername = "";
-       fstring printername = "";
-       fstring sharename = "";
-       fstring portname = "";
-       fstring drivername = "";
-       fstring comment = "";
-       fstring location = "";
-       fstring sepfile = "";
-       fstring printprocessor = "";
-       fstring datatype = "";
-       fstring parameters = "";
-
-       rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), -1, STR_TERMINATE);
-       rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), -1, STR_TERMINATE);
-       rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), -1, STR_TERMINATE);
-       rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), -1, STR_TERMINATE);
-       rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), -1, STR_TERMINATE);
-       rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), -1, STR_TERMINATE);
-       rpcstr_pull(location, i2->location.buffer,sizeof(location), -1, STR_TERMINATE);
-       rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), -1, STR_TERMINATE);
-       rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), -1, STR_TERMINATE);
-       rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), -1, STR_TERMINATE);
-       rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), -1, STR_TERMINATE);
-
-       printf("\tservername:[%s]\n", servername);
-       printf("\tprintername:[%s]\n", printername);
-       printf("\tsharename:[%s]\n", sharename);
-       printf("\tportname:[%s]\n", portname);
-       printf("\tdrivername:[%s]\n", drivername);
-       printf("\tcomment:[%s]\n", comment);
-       printf("\tlocation:[%s]\n", location);
-       printf("\tsepfile:[%s]\n", sepfile);
-       printf("\tprintprocessor:[%s]\n", printprocessor);
-       printf("\tdatatype:[%s]\n", datatype);
-       printf("\tparameters:[%s]\n", parameters);
-       printf("\tattributes:[0x%x]\n", i2->attributes);
-       printf("\tpriority:[0x%x]\n", i2->priority);
-       printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority);
-       printf("\tstarttime:[0x%x]\n", i2->starttime);
-       printf("\tuntiltime:[0x%x]\n", i2->untiltime);
-       printf("\tstatus:[0x%x]\n", i2->status);
-       printf("\tcjobs:[0x%x]\n", i2->cjobs);
-       printf("\taverageppm:[0x%x]\n", i2->averageppm);
-
-       if (i2->secdesc)
-               display_sec_desc(i2->secdesc);
+static void display_print_info2(struct spoolss_PrinterInfo2 *r)
+{
+       printf("\tservername:[%s]\n", r->servername);
+       printf("\tprintername:[%s]\n", r->printername);
+       printf("\tsharename:[%s]\n", r->sharename);
+       printf("\tportname:[%s]\n", r->portname);
+       printf("\tdrivername:[%s]\n", r->drivername);
+       printf("\tcomment:[%s]\n", r->comment);
+       printf("\tlocation:[%s]\n", r->location);
+       printf("\tsepfile:[%s]\n", r->sepfile);
+       printf("\tprintprocessor:[%s]\n", r->printprocessor);
+       printf("\tdatatype:[%s]\n", r->datatype);
+       printf("\tparameters:[%s]\n", r->parameters);
+       printf("\tattributes:[0x%x]\n", r->attributes);
+       printf("\tpriority:[0x%x]\n", r->priority);
+       printf("\tdefaultpriority:[0x%x]\n", r->defaultpriority);
+       printf("\tstarttime:[0x%x]\n", r->starttime);
+       printf("\tuntiltime:[0x%x]\n", r->untiltime);
+       printf("\tstatus:[0x%x]\n", r->status);
+       printf("\tcjobs:[0x%x]\n", r->cjobs);
+       printf("\taverageppm:[0x%x]\n", r->averageppm);
+
+       if (r->secdesc)
+               display_sec_desc(r->secdesc);
 
        printf("\n");
 }
@@ -273,9 +227,9 @@ static void display_print_info_2(PRINTER_INFO_2 *i2)
 /****************************************************************************
 ****************************************************************************/
 
-static void display_print_info_3(PRINTER_INFO_3 *i3)
+static void display_print_info3(struct spoolss_PrinterInfo3 *r)
 {
-       display_sec_desc(i3->secdesc);
+       display_sec_desc(r->secdesc);
 
        printf("\n");
 }
@@ -294,64 +248,65 @@ static void display_print_info7(struct spoolss_PrinterInfo7 *r)
 ****************************************************************************/
 
 static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
-                                          TALLOC_CTX *mem_ctx,
-                                          int argc, const char **argv)
+                                       TALLOC_CTX *mem_ctx,
+                                       int argc, const char **argv)
 {
        WERROR                  result;
-       uint32                  info_level = 1;
-       PRINTER_INFO_CTR        ctr;
-       uint32                  i = 0, num_printers;
-       fstring name;
+       uint32_t                level = 1;
+       union spoolss_PrinterInfo *info;
+       uint32_t                i, count;
+       const char *name;
 
-       if (argc > 3)
-       {
+       if (argc > 3) {
                printf("Usage: %s [level] [name]\n", argv[0]);
                return WERR_OK;
        }
 
-       if (argc >= 2)
-               info_level = atoi(argv[1]);
-
-       if (argc == 3)
-               fstrcpy(name, argv[2]);
-       else {
-               slprintf(name, sizeof(name)-1, "\\\\%s", cli->desthost);
-               strupper_m(name);
+       if (argc >= 2) {
+               level = atoi(argv[1]);
        }
 
-       ZERO_STRUCT(ctr);
-
-       result = rpccli_spoolss_enum_printers(cli, mem_ctx, name, PRINTER_ENUM_LOCAL,
-               info_level, &num_printers, &ctr);
+       if (argc == 3) {
+               name = argv[2];
+       } else {
+               name = cli->srv_name_slash;
+       }
 
+       result = rpccli_spoolss_enumprinters(cli, mem_ctx,
+                                            PRINTER_ENUM_LOCAL,
+                                            name,
+                                            level,
+                                            0,
+                                            &count,
+                                            &info);
        if (W_ERROR_IS_OK(result)) {
 
-               if (!num_printers) {
+               if (!count) {
                        printf ("No printers returned.\n");
                        goto done;
                }
 
-               for (i = 0; i < num_printers; i++) {
-                       switch(info_level) {
+               for (i = 0; i < count; i++) {
+                       switch (level) {
                        case 0:
-                               display_print_info_0(&ctr.printers_0[i]);
+                               display_print_info0(&info[i].info0);
                                break;
                        case 1:
-                               display_print_info_1(&ctr.printers_1[i]);
+                               display_print_info1(&info[i].info1);
                                break;
                        case 2:
-                               display_print_info_2(&ctr.printers_2[i]);
+                               display_print_info2(&info[i].info2);
                                break;
                        case 3:
-                               display_print_info_3(&ctr.printers_3[i]);
+                               display_print_info3(&info[i].info3);
                                break;
                        default:
-                               printf("unknown info level %d\n", info_level);
+                               printf("unknown info level %d\n", level);
                                goto done;
                        }
                }
        }
      done:
+ done:
 
        return result;
 }
@@ -409,8 +364,8 @@ static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
                                       const char **argv)
 {
        WERROR                  result;
-       uint32                  info_level = 1;
-       uint32                  returned;
+       uint32_t                level = 1;
+       uint32_t                count;
        union spoolss_PortInfo *info;
 
        if (argc > 2) {
@@ -418,22 +373,23 @@ static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
                return WERR_OK;
        }
 
-       if (argc == 2)
-               info_level = atoi(argv[1]);
+       if (argc == 2) {
+               level = atoi(argv[1]);
+       }
 
        /* Enumerate ports */
 
        result = rpccli_spoolss_enumports(cli, mem_ctx,
                                          cli->srv_name_slash,
-                                         info_level,
+                                         level,
                                          0,
-                                         &returned,
+                                         &count,
                                          &info);
        if (W_ERROR_IS_OK(result)) {
                int i;
 
-               for (i = 0; i < returned; i++) {
-                       switch (info_level) {
+               for (i = 0; i < count; i++) {
+                       switch (level) {
                        case 1:
                                display_port_info_1(&info[i].info1);
                                break;
@@ -441,7 +397,7 @@ static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
                                display_port_info_2(&info[i].info2);
                                break;
                        default:
-                               printf("unknown info level %d\n", info_level);
+                               printf("unknown info level %d\n", level);
                                break;
                        }
                }
@@ -611,7 +567,7 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
 {
        POLICY_HND      pol;
        WERROR          result;
-       uint32          info_level = 1;
+       uint32_t        level = 1;
        const char      *printername;
        union spoolss_PrinterInfo info;
 
@@ -622,7 +578,7 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
 
        /* Open a printer handle */
        if (argc == 3) {
-               info_level = atoi(argv[2]);
+               level = atoi(argv[2]);
        }
 
        RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
@@ -633,45 +589,46 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
                                               printername,
                                               SEC_FLAG_MAXIMUM_ALLOWED,
                                               &pol);
-       if (!W_ERROR_IS_OK(result))
+       if (!W_ERROR_IS_OK(result)) {
                goto done;
+       }
 
        /* Get printer info */
 
        result = rpccli_spoolss_getprinter(cli, mem_ctx,
                                           &pol,
-                                          info_level,
+                                          level,
                                           0,
                                           &info);
-       if (!W_ERROR_IS_OK(result))
+       if (!W_ERROR_IS_OK(result)) {
                goto done;
+       }
 
        /* Display printer info */
-       switch (info_level) {
-#if 0 /* FIXME GD */
+       switch (level) {
        case 0:
-               display_print_info_0(ctr.printers_0);
+               display_print_info0(&info.info0);
                break;
        case 1:
-               display_print_info_1(ctr.printers_1);
+               display_print_info1(&info.info1);
                break;
        case 2:
-               display_print_info_2(ctr.printers_2);
+               display_print_info2(&info.info2);
                break;
        case 3:
-               display_print_info_3(ctr.printers_3);
+               display_print_info3(&info.info3);
                break;
-#endif
        case 7:
                display_print_info7(&info.info7);
                break;
        default:
-               printf("unknown info level %d\n", info_level);
+               printf("unknown info level %d\n", level);
                break;
        }
  done:
-       if (is_valid_policy_hnd(&pol))
+       if (is_valid_policy_hnd(&pol)) {
                rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
+       }
 
        return result;
 }
@@ -895,116 +852,6 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
 /****************************************************************************
 ****************************************************************************/
 
-static void display_print_driver_1(DRIVER_INFO_1 *i1)
-{
-       fstring name;
-       if (i1 == NULL)
-               return;
-
-       rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
-
-       printf ("Printer Driver Info 1:\n");
-       printf ("\tDriver Name: [%s]\n\n", name);
-
-       return;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static void display_print_driver_2(DRIVER_INFO_2 *i1)
-{
-       fstring name;
-       fstring architecture;
-       fstring driverpath;
-       fstring datafile;
-       fstring configfile;
-       if (i1 == NULL)
-               return;
-
-       rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
-       rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
-       rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
-       rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
-       rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
-
-       printf ("Printer Driver Info 2:\n");
-       printf ("\tVersion: [%x]\n", i1->version);
-       printf ("\tDriver Name: [%s]\n", name);
-       printf ("\tArchitecture: [%s]\n", architecture);
-       printf ("\tDriver Path: [%s]\n", driverpath);
-       printf ("\tDatafile: [%s]\n", datafile);
-       printf ("\tConfigfile: [%s]\n\n", configfile);
-
-       return;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static void display_print_driver_3(DRIVER_INFO_3 *i1)
-{
-       fstring name = "";
-       fstring architecture = "";
-       fstring driverpath = "";
-       fstring datafile = "";
-       fstring configfile = "";
-       fstring helpfile = "";
-       fstring dependentfiles = "";
-       fstring monitorname = "";
-       fstring defaultdatatype = "";
-
-       int length=0;
-       bool valid = True;
-
-       if (i1 == NULL)
-               return;
-
-       rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
-       rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
-       rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
-       rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
-       rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
-       rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
-       rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
-       rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
-
-       printf ("Printer Driver Info 3:\n");
-       printf ("\tVersion: [%x]\n", i1->version);
-       printf ("\tDriver Name: [%s]\n",name);
-       printf ("\tArchitecture: [%s]\n", architecture);
-       printf ("\tDriver Path: [%s]\n", driverpath);
-       printf ("\tDatafile: [%s]\n", datafile);
-       printf ("\tConfigfile: [%s]\n", configfile);
-       printf ("\tHelpfile: [%s]\n\n", helpfile);
-
-       while (valid)
-       {
-               rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
-
-               length+=strlen(dependentfiles)+1;
-
-               if (strlen(dependentfiles) > 0)
-               {
-                       printf ("\tDependentfiles: [%s]\n", dependentfiles);
-               }
-               else
-               {
-                       valid = False;
-               }
-       }
-
-       printf ("\n");
-
-       printf ("\tMonitorname: [%s]\n", monitorname);
-       printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
-
-       return;
-}
-
-/****************************************************************************
-****************************************************************************/
-
 static void display_print_driver1(struct spoolss_DriverInfo1 *r)
 {
        if (!r) {
@@ -1068,21 +915,20 @@ static void display_print_driver3(struct spoolss_DriverInfo3 *r)
 ****************************************************************************/
 
 static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
-                                      TALLOC_CTX *mem_ctx,
-                                      int argc, const char **argv)
+                                   TALLOC_CTX *mem_ctx,
+                                   int argc, const char **argv)
 {
        POLICY_HND      pol;
        WERROR          werror;
-       uint32          info_level = 3;
+       uint32_t        level = 3;
        const char      *printername;
-       uint32          i;
-       bool            success = False;
+       uint32_t        i;
+       bool            success = false;
        union spoolss_DriverInfo info;
        uint32_t server_major_version;
        uint32_t server_minor_version;
 
-       if ((argc == 1) || (argc > 3))
-       {
+       if ((argc == 1) || (argc > 3)) {
                printf("Usage: %s <printername> [level]\n", argv[0]);
                return WERR_OK;
        }
@@ -1091,8 +937,9 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
 
        RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
 
-       if (argc == 3)
-               info_level = atoi(argv[2]);
+       if (argc == 3) {
+               level = atoi(argv[2]);
+       }
 
        /* Open a printer handle */
 
@@ -1112,23 +959,24 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
                werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
                                                          &pol,
                                                          archi_table[i].long_archi,
-                                                         info_level,
+                                                         level,
                                                          0, /* offered */
                                                          archi_table[i].version,
                                                          2,
                                                          &info,
                                                          &server_major_version,
                                                          &server_minor_version);
-               if (!W_ERROR_IS_OK(werror))
+               if (!W_ERROR_IS_OK(werror)) {
                        continue;
+               }
 
                /* need at least one success */
 
-               success = True;
+               success = true;
 
-               printf ("\n[%s]\n", archi_table[i].long_archi);
+               printf("\n[%s]\n", archi_table[i].long_archi);
 
-               switch (info_level) {
+               switch (level) {
                case 1:
                        display_print_driver1(&info.info1);
                        break;
@@ -1139,18 +987,20 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
                        display_print_driver3(&info.info3);
                        break;
                default:
-                       printf("unknown info level %d\n", info_level);
+                       printf("unknown info level %d\n", level);
                        break;
                }
        }
 
        /* Cleanup */
 
-       if (is_valid_policy_hnd(&pol))
+       if (is_valid_policy_hnd(&pol)) {
                rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
+       }
 
-       if ( success )
+       if (success) {
                werror = WERR_OK;
+       }
 
        return werror;
 }
@@ -1163,68 +1013,73 @@ static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
                                          int argc, const char **argv)
 {
        WERROR werror = WERR_OK;
-       uint32          info_level = 1;
-       PRINTER_DRIVER_CTR      ctr;
-       uint32          i, j,
-                       returned;
+       uint32_t        level = 1;
+       union spoolss_DriverInfo *info;
+       uint32_t        i, j, count;
 
        if (argc > 2) {
                printf("Usage: enumdrivers [level]\n");
                return WERR_OK;
        }
 
-       if (argc == 2)
-               info_level = atoi(argv[1]);
+       if (argc == 2) {
+               level = atoi(argv[1]);
+       }
 
 
        /* loop through and print driver info level for each architecture */
        for (i=0; archi_table[i].long_archi!=NULL; i++) {
                /* check to see if we already asked for this architecture string */
 
-               if ( i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi) )
+               if (i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi)) {
                        continue;
+               }
 
-               werror = rpccli_spoolss_enumprinterdrivers(
-                       cli, mem_ctx, info_level,
-                       archi_table[i].long_archi, &returned, &ctr);
+               werror = rpccli_spoolss_enumprinterdrivers(cli, mem_ctx,
+                                                          cli->srv_name_slash,
+                                                          archi_table[i].long_archi,
+                                                          level,
+                                                          0,
+                                                          &count,
+                                                          &info);
 
                if (W_ERROR_V(werror) == W_ERROR_V(WERR_INVALID_ENVIRONMENT)) {
-                       printf ("Server does not support environment [%s]\n",
+                       printf("Server does not support environment [%s]\n",
                                archi_table[i].long_archi);
                        werror = WERR_OK;
                        continue;
                }
 
-               if (returned == 0)
+               if (count == 0) {
                        continue;
+               }
 
                if (!W_ERROR_IS_OK(werror)) {
-                       printf ("Error getting driver for environment [%s] - %d\n",
+                       printf("Error getting driver for environment [%s] - %d\n",
                                archi_table[i].long_archi, W_ERROR_V(werror));
                        continue;
                }
 
-               printf ("\n[%s]\n", archi_table[i].long_archi);
-               switch (info_level)
-               {
+               printf("\n[%s]\n", archi_table[i].long_archi);
 
+               switch (level) {
                case 1:
-                       for (j=0; j < returned; j++) {
-                               display_print_driver_1 (&ctr.info1[j]);
+                       for (j=0; j < count; j++) {
+                               display_print_driver1(&info[j].info1);
                        }
                        break;
                case 2:
-                       for (j=0; j < returned; j++) {
-                               display_print_driver_2 (&ctr.info2[j]);
+                       for (j=0; j < count; j++) {
+                               display_print_driver2(&info[j].info2);
                        }
                        break;
                case 3:
-                       for (j=0; j < returned; j++) {
-                               display_print_driver_3 (&ctr.info3[j]);
+                       for (j=0; j < count; j++) {
+                               display_print_driver3(&info[j].info3);
                        }
                        break;
                default:
-                       printf("unknown info level %d\n", info_level);
+                       printf("unknown info level %d\n", level);
                        return WERR_UNKNOWN_LEVEL;
                }
        }
@@ -2370,48 +2225,6 @@ done:
 /****************************************************************************
 ****************************************************************************/
 
-static void display_job_info_1(JOB_INFO_1 *job)
-{
-       fstring username = "", document = "", text_status = "";
-
-       rpcstr_pull(username, job->username.buffer,
-                   sizeof(username), -1, STR_TERMINATE);
-
-       rpcstr_pull(document, job->document.buffer,
-                   sizeof(document), -1, STR_TERMINATE);
-
-       rpcstr_pull(text_status, job->text_status.buffer,
-                   sizeof(text_status), -1, STR_TERMINATE);
-
-       printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
-              username, document, text_status, job->pagesprinted,
-              job->totalpages);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static void display_job_info_2(JOB_INFO_2 *job)
-{
-       fstring username = "", document = "", text_status = "";
-
-       rpcstr_pull(username, job->username.buffer,
-                   sizeof(username), -1, STR_TERMINATE);
-
-       rpcstr_pull(document, job->document.buffer,
-                   sizeof(document), -1, STR_TERMINATE);
-
-       rpcstr_pull(text_status, job->text_status.buffer,
-                   sizeof(text_status), -1, STR_TERMINATE);
-
-       printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
-              username, document, text_status, job->pagesprinted,
-              job->totalpages, job->size);
-}
-
-/****************************************************************************
-****************************************************************************/
-
 static void display_job_info1(struct spoolss_JobInfo1 *r)
 {
        printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id,
@@ -2458,18 +2271,19 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
                                      const char **argv)
 {
        WERROR result;
-       uint32 level = 1, num_jobs, i;
+       uint32_t level = 1, count, i;
        const char *printername;
        POLICY_HND hnd;
-       JOB_INFO_CTR ctr;
+       union spoolss_JobInfo *info;
 
        if (argc < 2 || argc > 3) {
                printf("Usage: %s printername [level]\n", argv[0]);
                return WERR_OK;
        }
 
-       if (argc == 3)
+       if (argc == 3) {
                level = atoi(argv[2]);
+       }
 
        /* Open printer handle */
 
@@ -2484,19 +2298,25 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
 
        /* Enumerate ports */
 
-       result = rpccli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000,
-               &num_jobs, &ctr);
-
-       if (!W_ERROR_IS_OK(result))
+       result = rpccli_spoolss_enumjobs(cli, mem_ctx,
+                                        &hnd,
+                                        0, /* firstjob */
+                                        1000, /* numjobs */
+                                        level,
+                                        0,
+                                        &count,
+                                        &info);
+       if (!W_ERROR_IS_OK(result)) {
                goto done;
+       }
 
-       for (i = 0; i < num_jobs; i++) {
-               switch(level) {
+       for (i = 0; i < count; i++) {
+               switch (level) {
                case 1:
-                       display_job_info_1(&ctr.job.job_info_1[i]);
+                       display_job_info1(&info[i].info1);
                        break;
                case 2:
-                       display_job_info_2(&ctr.job.job_info_2[i]);
+                       display_job_info2(&info[i].info2);
                        break;
                default:
                        d_printf("unknown info level %d\n", level);
@@ -2505,8 +2325,9 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
        }
 
 done:
-       if (is_valid_policy_hnd(&hnd))
+       if (is_valid_policy_hnd(&hnd)) {
                rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
+       }
 
        return result;
 }
index d11d3be2d50a371802dd0b31d4d14be79af4e97e..897a9b8d7a7ab205646cc645f8a0a7ef8a68be3a 100644 (file)
@@ -67,7 +67,7 @@ AC_CONFIG_FILES(../source4/param/samba-hostconfig.pc)
 AC_CONFIG_FILES(../source4/librpc/dcerpc_samr.pc)
 AC_CONFIG_FILES(../source4/librpc/dcerpc_atsvc.pc)
 
-SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= 1.2.0,
+SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= 1.3.0,
        [],
        [
                SMB_INCLUDE_MK(../lib/talloc/config.mk)
@@ -84,7 +84,7 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.3,
 
 SMB_INCLUDE_MK(../lib/tdb/python.mk) 
 
-SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent = 0.9.3,
+SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent = 0.9.4,
        [],[m4_include(../lib/tevent/samba.m4)]
 )
 
@@ -152,6 +152,14 @@ fi
 dnl Samba 4 files
 AC_SUBST(LD)
 AC_LIBREPLACE_SHLD_FLAGS
+dnl Remove -L/usr/lib/? from LDFLAGS and LIBS
+LIB_REMOVE_USR_LIB(LDFLAGS)
+LIB_REMOVE_USR_LIB(LIBS)
+LIB_REMOVE_USR_LIB(KRB5_LIBS)
+
+dnl Remove -I/usr/include/? from CFLAGS and CPPFLAGS
+CFLAGS_REMOVE_USR_INCLUDE(CFLAGS)
+CFLAGS_REMOVE_USR_INCLUDE(CPPFLAGS)
 SMB_WRITE_MAKEVARS(samba4-config.mk, [prefix exec_prefix CPPFLAGS LDSHFLAGS POPT_OBJ CFLAGS TALLOC_OBJ POPT_LIBS srcdir builddir])
                 
 oldbuilddir="$builddir"
index 10e3f76bbfbe443dcc9a10b971b67afee5017666..7e7690aadf558f4ced807cef9ddefc44605e7b0f 100644 (file)
@@ -89,7 +89,7 @@ socketwrappersrcdir := $(samba4srcdir)/../lib/socket_wrapper
 nsswrappersrcdir := $(samba4srcdir)/../lib/nss_wrapper
 libstreamsrcdir := $(samba4srcdir)/lib/stream
 libutilsrcdir := $(samba4srcdir)/../lib/util
-libtdrsrcdir := $(samba4srcdir)/lib/tdr
+libtdrsrcdir := ../lib/tdr
 libcryptosrcdir := $(samba4srcdir)/../lib/crypto
 libtorturesrcdir := ../lib/torture
 libcompressionsrcdir := $(samba4srcdir)/../lib/compression
index c8cc2e64a3855eff790994cd760b0016e110c29b..d529b009d5086484c5a3727c19412fba4651ca8f 100644 (file)
@@ -454,8 +454,26 @@ static NTSTATUS open_file(files_struct *fsp,
                                        &access_granted);
                        if (!NT_STATUS_IS_OK(status)) {
                                if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+                                       /*
+                                        * On NT_STATUS_ACCESS_DENIED, access_granted
+                                        * contains the denied bits.
+                                        */
+
+                                       if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
+                                                       (access_granted & FILE_WRITE_ATTRIBUTES) &&
+                                                       (lp_map_readonly(SNUM(conn)) ||
+                                                        lp_map_archive(SNUM(conn)) ||
+                                                        lp_map_hidden(SNUM(conn)) ||
+                                                        lp_map_system(SNUM(conn)))) {
+                                               access_granted &= ~FILE_WRITE_ATTRIBUTES;
+
+                                               DEBUG(10,("open_file: overrode FILE_WRITE_ATTRIBUTES "
+                                                       "on file %s\n",
+                                                       path ));
+                                       }
+
                                        if ((access_mask & DELETE_ACCESS) &&
-                                                       (access_granted == DELETE_ACCESS) &&
+                                                       (access_granted & DELETE_ACCESS) &&
                                                        can_delete_file_in_directory(conn, path)) {
                                                /* Were we trying to do a stat open
                                                 * for delete and didn't get DELETE
@@ -465,10 +483,14 @@ static NTSTATUS open_file(files_struct *fsp,
                                                 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
                                                 * for details. */
 
-                                               DEBUG(10,("open_file: overrode ACCESS_DENIED "
+                                               access_granted &= ~DELETE_ACCESS;
+
+                                               DEBUG(10,("open_file: overrode DELETE_ACCESS "
                                                        "on file %s\n",
                                                        path ));
-                                       } else {
+                                       }
+
+                                       if (access_granted != 0) {
                                                DEBUG(10, ("open_file: Access denied on "
                                                        "file %s\n",
                                                        path));
index 22e4c1aad7fb6b50ef9f0bb633f9b68e3933f6da..a743385f7f51fa7c454f66875ba4fd7a19ba1104 100644 (file)
@@ -2859,6 +2859,7 @@ void reply_readbraw(struct smb_request *req)
        size_t nread = 0;
        SMB_OFF_T startpos;
        files_struct *fsp;
+       struct lock_struct lock;
        SMB_STRUCT_STAT st;
        SMB_OFF_T size = 0;
 
@@ -2959,10 +2960,11 @@ void reply_readbraw(struct smb_request *req)
        /* ensure we don't overrun the packet size */
        maxcount = MIN(65535,maxcount);
 
-       if (is_locked(fsp,(uint32)req->smbpid,
-                       (uint64_t)maxcount,
-                       (uint64_t)startpos,
-                       READ_LOCK)) {
+       init_strict_lock_struct(fsp, (uint32)req->smbpid,
+           (uint64_t)startpos, (uint64_t)maxcount, READ_LOCK,
+           &lock);
+
+       if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
                reply_readbraw_error();
                END_PROFILE(SMBreadbraw);
                return;
@@ -2993,7 +2995,11 @@ void reply_readbraw(struct smb_request *req)
        send_file_readbraw(conn, req, fsp, startpos, nread, mincount);
 
        DEBUG(5,("reply_readbraw finished\n"));
+
+       SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
        END_PROFILE(SMBreadbraw);
+       return;
 }
 
 #undef DBGC_CLASS
@@ -3121,6 +3127,7 @@ void reply_read(struct smb_request *req)
        SMB_OFF_T startpos;
        int outsize = 0;
        files_struct *fsp;
+       struct lock_struct lock;
 
        START_PROFILE(SMBread);
 
@@ -3162,8 +3169,11 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
 
        data = smb_buf(req->outbuf) + 3;
 
-       if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtoread,
-                     (uint64_t)startpos, READ_LOCK)) {
+       init_strict_lock_struct(fsp, (uint32)req->smbpid,
+           (uint64_t)startpos, (uint64_t)numtoread, READ_LOCK,
+           &lock);
+
+       if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
                reply_doserror(req, ERRDOS,ERRlock);
                END_PROFILE(SMBread);
                return;
@@ -3174,8 +3184,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
 
        if (nread < 0) {
                reply_unixerror(req, ERRDOS,ERRnoaccess);
-               END_PROFILE(SMBread);
-               return;
+               goto strict_unlock;
        }
 
        srv_set_message((char *)req->outbuf, 5, nread+3, False);
@@ -3188,6 +3197,9 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
        DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
                fsp->fnum, (int)numtoread, (int)nread ) );
 
+strict_unlock:
+       SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
        END_PROFILE(SMBread);
        return;
 }
@@ -3387,6 +3399,7 @@ void reply_read_and_X(struct smb_request *req)
        files_struct *fsp;
        SMB_OFF_T startpos;
        size_t smb_maxcnt;
+       struct lock_struct lock;
        bool big_readX = False;
 #if 0
        size_t smb_mincnt = SVAL(req->vwv+6, 0);
@@ -3474,8 +3487,11 @@ void reply_read_and_X(struct smb_request *req)
 
        }
 
-       if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)smb_maxcnt,
-                     (uint64_t)startpos, READ_LOCK)) {
+       init_strict_lock_struct(fsp, (uint32)req->smbpid,
+           (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
+           &lock);
+
+       if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
                END_PROFILE(SMBreadX);
                reply_doserror(req, ERRDOS, ERRlock);
                return;
@@ -3483,12 +3499,14 @@ void reply_read_and_X(struct smb_request *req)
 
        if (!big_readX &&
            schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
-               END_PROFILE(SMBreadX);
-               return;
+               goto strict_unlock;
        }
 
        send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
 
+strict_unlock:
+       SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
        END_PROFILE(SMBreadX);
        return;
 }
@@ -3523,6 +3541,7 @@ void reply_writebraw(struct smb_request *req)
        char *data=NULL;
        bool write_through;
        files_struct *fsp;
+       struct lock_struct lock;
        NTSTATUS status;
 
        START_PROFILE(SMBwritebraw);
@@ -3584,8 +3603,11 @@ void reply_writebraw(struct smb_request *req)
                return;
        }
 
-       if (is_locked(fsp,(uint32)req->smbpid,(uint64_t)tcount,
-                               (uint64_t)startpos, WRITE_LOCK)) {
+       init_strict_lock_struct(fsp, (uint32)req->smbpid,
+           (uint64_t)startpos, (uint64_t)tcount, WRITE_LOCK,
+           &lock);
+
+       if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
                reply_doserror(req, ERRDOS, ERRlock);
                error_to_writebrawerr(req);
                END_PROFILE(SMBwritebraw);
@@ -3604,8 +3626,7 @@ void reply_writebraw(struct smb_request *req)
        if (nwritten < (ssize_t)numtowrite)  {
                reply_unixerror(req, ERRHRD, ERRdiskfull);
                error_to_writebrawerr(req);
-               END_PROFILE(SMBwritebraw);
-               return;
+               goto strict_unlock;
        }
 
        total_written = nwritten;
@@ -3615,8 +3636,7 @@ void reply_writebraw(struct smb_request *req)
        if (!buf) {
                reply_doserror(req, ERRDOS, ERRnomem);
                error_to_writebrawerr(req);
-               END_PROFILE(SMBwritebraw);
-               return;
+               goto strict_unlock;
        }
 
        /* Return a SMBwritebraw message to the redirector to tell
@@ -3674,8 +3694,7 @@ void reply_writebraw(struct smb_request *req)
                        TALLOC_FREE(buf);
                        reply_unixerror(req, ERRHRD, ERRdiskfull);
                        error_to_writebrawerr(req);
-                       END_PROFILE(SMBwritebraw);
-                       return;
+                       goto strict_unlock;
                }
 
                if (nwritten < (ssize_t)numtowrite) {
@@ -3697,8 +3716,7 @@ void reply_writebraw(struct smb_request *req)
                        fsp->fsp_name, nt_errstr(status) ));
                reply_nterror(req, status);
                error_to_writebrawerr(req);
-               END_PROFILE(SMBwritebraw);
-               return;
+               goto strict_unlock;
        }
 
        DEBUG(3,("reply_writebraw: secondart write fnum=%d start=%.0f num=%d "
@@ -3706,6 +3724,8 @@ void reply_writebraw(struct smb_request *req)
                fsp->fnum, (double)startpos, (int)numtowrite,
                (int)total_written));
 
+       SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
        /* We won't return a status if write through is not selected - this
         * follows what WfWg does */
        END_PROFILE(SMBwritebraw);
@@ -3726,6 +3746,12 @@ void reply_writebraw(struct smb_request *req)
                TALLOC_FREE(req->outbuf);
        }
        return;
+
+strict_unlock:
+       SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
+       END_PROFILE(SMBwritebraw);
+       return;
 }
 
 #undef DBGC_CLASS
@@ -3744,6 +3770,7 @@ void reply_writeunlock(struct smb_request *req)
        const char *data;
        NTSTATUS status = NT_STATUS_OK;
        files_struct *fsp;
+       struct lock_struct lock;
 
        START_PROFILE(SMBwriteunlock);
 
@@ -3770,12 +3797,16 @@ void reply_writeunlock(struct smb_request *req)
        startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
        data = (const char *)req->buf + 3;
 
-       if (numtowrite
-           && is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
-                        (uint64_t)startpos, WRITE_LOCK)) {
-               reply_doserror(req, ERRDOS, ERRlock);
-               END_PROFILE(SMBwriteunlock);
-               return;
+       if (numtowrite) {
+               init_strict_lock_struct(fsp, (uint32)req->smbpid,
+                   (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
+                   &lock);
+
+               if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+                       reply_doserror(req, ERRDOS, ERRlock);
+                       END_PROFILE(SMBwriteunlock);
+                       return;
+               }
        }
 
        /* The special X/Open SMB protocol handling of
@@ -3792,14 +3823,12 @@ void reply_writeunlock(struct smb_request *req)
                DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
                        fsp->fsp_name, nt_errstr(status) ));
                reply_nterror(req, status);
-               END_PROFILE(SMBwriteunlock);
-               return;
+               goto strict_unlock;
        }
 
        if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
                reply_unixerror(req, ERRHRD, ERRdiskfull);
-               END_PROFILE(SMBwriteunlock);
-               return;
+               goto strict_unlock;
        }
 
        if (numtowrite) {
@@ -3812,8 +3841,7 @@ void reply_writeunlock(struct smb_request *req)
 
                if (NT_STATUS_V(status)) {
                        reply_nterror(req, status);
-                       END_PROFILE(SMBwriteunlock);
-                       return;
+                       goto strict_unlock;
                }
        }
 
@@ -3824,6 +3852,11 @@ void reply_writeunlock(struct smb_request *req)
        DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
                 fsp->fnum, (int)numtowrite, (int)nwritten));
 
+strict_unlock:
+       if (numtowrite) {
+               SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+       }
+
        END_PROFILE(SMBwriteunlock);
        return;
 }
@@ -3843,6 +3876,7 @@ void reply_write(struct smb_request *req)
        SMB_OFF_T startpos;
        const char *data;
        files_struct *fsp;
+       struct lock_struct lock;
        NTSTATUS status;
 
        START_PROFILE(SMBwrite);
@@ -3877,8 +3911,11 @@ void reply_write(struct smb_request *req)
        startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
        data = (const char *)req->buf + 3;
 
-       if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
-                     (uint64_t)startpos, WRITE_LOCK)) {
+       init_strict_lock_struct(fsp, (uint32)req->smbpid,
+           (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
+           &lock);
+
+       if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
                reply_doserror(req, ERRDOS, ERRlock);
                END_PROFILE(SMBwrite);
                return;
@@ -3897,14 +3934,12 @@ void reply_write(struct smb_request *req)
                nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
                if (nwritten < 0) {
                        reply_nterror(req, NT_STATUS_DISK_FULL);
-                       END_PROFILE(SMBwrite);
-                       return;
+                       goto strict_unlock;
                }
                nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
                if (nwritten < 0) {
                        reply_nterror(req, NT_STATUS_DISK_FULL);
-                       END_PROFILE(SMBwrite);
-                       return;
+                       goto strict_unlock;
                }
                trigger_write_time_update_immediate(fsp);
        } else {
@@ -3916,14 +3951,12 @@ void reply_write(struct smb_request *req)
                DEBUG(5,("reply_write: sync_file for %s returned %s\n",
                        fsp->fsp_name, nt_errstr(status) ));
                reply_nterror(req, status);
-               END_PROFILE(SMBwrite);
-               return;
+               goto strict_unlock;
        }
 
        if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
                reply_unixerror(req, ERRHRD, ERRdiskfull);
-               END_PROFILE(SMBwrite);
-               return;
+               goto strict_unlock;
        }
 
        reply_outbuf(req, 1, 0);
@@ -3937,6 +3970,9 @@ void reply_write(struct smb_request *req)
 
        DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
 
+strict_unlock:
+       SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
        END_PROFILE(SMBwrite);
        return;
 }
@@ -4034,6 +4070,7 @@ void reply_write_and_X(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
        files_struct *fsp;
+       struct lock_struct lock;
        SMB_OFF_T startpos;
        size_t numtowrite;
        bool write_through;
@@ -4136,9 +4173,11 @@ void reply_write_and_X(struct smb_request *req)
 #endif /* LARGE_SMB_OFF_T */
        }
 
-       if (is_locked(fsp,(uint32)req->smbpid,
-                     (uint64_t)numtowrite,
-                     (uint64_t)startpos, WRITE_LOCK)) {
+       init_strict_lock_struct(fsp, (uint32)req->smbpid,
+           (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
+           &lock);
+
+       if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
                reply_doserror(req, ERRDOS, ERRlock);
                END_PROFILE(SMBwriteX);
                return;
@@ -4156,8 +4195,7 @@ void reply_write_and_X(struct smb_request *req)
                if ((req->unread_bytes == 0) &&
                    schedule_aio_write_and_X(conn, req, fsp, data, startpos,
                                             numtowrite)) {
-                       END_PROFILE(SMBwriteX);
-                       return;
+                       goto strict_unlock;
                }
 
                nwritten = write_file(req,fsp,data,startpos,numtowrite);
@@ -4165,8 +4203,7 @@ void reply_write_and_X(struct smb_request *req)
 
        if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
                reply_unixerror(req, ERRHRD, ERRdiskfull);
-               END_PROFILE(SMBwriteX);
-               return;
+               goto strict_unlock;
        }
 
        reply_outbuf(req, 6, 0);
@@ -4186,13 +4223,20 @@ void reply_write_and_X(struct smb_request *req)
                DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
                        fsp->fsp_name, nt_errstr(status) ));
                reply_nterror(req, status);
-               END_PROFILE(SMBwriteX);
-               return;
+               goto strict_unlock;
        }
 
+       SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
        END_PROFILE(SMBwriteX);
        chain_reply(req);
        return;
+
+strict_unlock:
+       SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
+       END_PROFILE(SMBwriteX);
+       return;
 }
 
 /****************************************************************************
@@ -4432,6 +4476,7 @@ void reply_writeclose(struct smb_request *req)
        const char *data;
        struct timespec mtime;
        files_struct *fsp;
+       struct lock_struct lock;
 
        START_PROFILE(SMBwriteclose);
 
@@ -4458,12 +4503,16 @@ void reply_writeclose(struct smb_request *req)
        mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4));
        data = (const char *)req->buf + 1;
 
-       if (numtowrite
-           && is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
-                        (uint64_t)startpos, WRITE_LOCK)) {
-               reply_doserror(req, ERRDOS,ERRlock);
-               END_PROFILE(SMBwriteclose);
-               return;
+       if (numtowrite) {
+               init_strict_lock_struct(fsp, (uint32)req->smbpid,
+                   (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
+                   &lock);
+
+               if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+                       reply_doserror(req, ERRDOS,ERRlock);
+                       END_PROFILE(SMBwriteclose);
+                       return;
+               }
        }
 
        nwritten = write_file(req,fsp,data,startpos,numtowrite);
@@ -4487,19 +4536,23 @@ void reply_writeclose(struct smb_request *req)
 
        if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
                reply_doserror(req, ERRHRD, ERRdiskfull);
-               END_PROFILE(SMBwriteclose);
-               return;
+               goto strict_unlock;
        }
 
        if(!NT_STATUS_IS_OK(close_status)) {
                reply_nterror(req, close_status);
-               END_PROFILE(SMBwriteclose);
-               return;
+               goto strict_unlock;
        }
 
        reply_outbuf(req, 1, 0);
 
        SSVAL(req->outbuf,smb_vwv0,nwritten);
+
+strict_unlock:
+       if (numtowrite) {
+               SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+       }
+
        END_PROFILE(SMBwriteclose);
        return;
 }
index a563557d5f49bd4ec612c39d6ba8dcd6afa5cba4..e2d1497b280b589d9727d17188d2b896817216e9 100644 (file)
@@ -333,6 +333,7 @@ bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
        uint16 old_vuid = cli->vuid;
        fstring old_user_name;
        size_t passlen = strlen(password);
+       NTSTATUS status;
        bool ret;
 
        fstrcpy(old_user_name, cli->user_name);
@@ -343,7 +344,10 @@ bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
                                                workgroup));
        *new_vuid = cli->vuid;
        cli->vuid = old_vuid;
-       fstrcpy(cli->user_name, old_user_name);
+       status = cli_set_username(cli, old_user_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               return false;
+       }
        return ret;
 }
 
@@ -4150,6 +4154,119 @@ static bool run_opentest(int dummy)
        return correct;
 }
 
+/*
+  Test POSIX open /mkdir calls.
+ */
+static bool run_simple_posix_open_test(int dummy)
+{
+       static struct cli_state *cli1;
+       const char *fname = "\\posix.file";
+       const char *dname = "\\posix.dir";
+       uint16 major, minor;
+       uint32 caplow, caphigh;
+       int fnum1 = -1;
+       bool correct = false;
+
+       printf("Starting simple POSIX open test\n");
+
+       if (!torture_open_connection(&cli1, 0)) {
+               return false;
+       }
+
+       cli_sockopt(cli1, sockops);
+
+       if (!SERVER_HAS_UNIX_CIFS(cli1)) {
+               printf("Server doesn't support UNIX CIFS extensions.\n");
+               return false;
+       }
+
+       if (!cli_unix_extensions_version(cli1, &major,
+                       &minor, &caplow, &caphigh)) {
+               printf("Server didn't return UNIX CIFS extensions.\n");
+               return false;
+       }
+
+       if (!cli_set_unix_extensions_capabilities(cli1,
+                       major, minor, caplow, caphigh)) {
+               printf("Server doesn't support setting UNIX CIFS extensions.\n");
+               return false;
+        }
+
+       cli_setatr(cli1, fname, 0, 0);
+       cli_posix_unlink(cli1, fname);
+       cli_setatr(cli1, dname, 0, 0);
+       cli_posix_rmdir(cli1, dname);
+
+       /* Create a directory. */
+       if (cli_posix_mkdir(cli1, dname, 0777) == -1) {
+               printf("Server doesn't support setting UNIX CIFS extensions.\n");
+               goto out;
+       }
+
+       fnum1 = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600);
+       if (fnum1 == -1) {
+               printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
+               goto out;
+       }
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("close failed (%s)\n", cli_errstr(cli1));
+               goto out;
+       }
+
+       /* Now open the file again for read only. */
+       fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
+       if (fnum1 == -1) {
+               printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
+               goto out;
+       }
+
+       /* Now unlink while open. */
+       if (!cli_posix_unlink(cli1, fname)) {
+               printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
+               goto out;
+       }
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("close(2) failed (%s)\n", cli_errstr(cli1));
+               goto out;
+       }
+
+       /* Ensure the file has gone. */
+       fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
+       if (fnum1 != -1) {
+               printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
+               goto out;
+       }
+
+       if (!cli_posix_rmdir(cli1, dname)) {
+               printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
+               goto out;
+       }
+
+       printf("Simple POSIX open test passed\n");
+       correct = true;
+
+  out:
+
+       if (fnum1 != -1) {
+               cli_close(cli1, fnum1);
+               fnum1 = -1;
+       }
+
+       cli_setatr(cli1, fname, 0, 0);
+       cli_posix_unlink(cli1, fname);
+       cli_setatr(cli1, dname, 0, 0);
+       cli_posix_rmdir(cli1, dname);
+
+       if (!torture_close_connection(cli1)) {
+               correct = false;
+       }
+
+       return correct;
+}
+
+
 static uint32 open_attrs_table[] = {
                FILE_ATTRIBUTE_NORMAL,
                FILE_ATTRIBUTE_ARCHIVE,
@@ -5004,9 +5121,7 @@ static bool run_chain1(int dummy)
        return True;
 }
 
-static size_t null_source(uint8_t *inbuf, size_t n,
-                         const uint8_t *outbuf,
-                         void *priv)
+static size_t null_source(uint8_t *buf, size_t n, void *priv)
 {
        size_t *to_pull = (size_t *)priv;
        size_t thistime = *to_pull;
@@ -5016,7 +5131,7 @@ static size_t null_source(uint8_t *inbuf, size_t n,
                return 0;
        }
 
-       memset(inbuf, 0, thistime);
+       memset(buf, 0, thistime);
        *to_pull -= thistime;
        return thistime;
 }
@@ -5059,7 +5174,7 @@ static bool run_windows_write(int dummy)
                }
 
                status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
-                                 false, null_source, &to_pull);
+                                 null_source, &to_pull);
                if (!NT_STATUS_IS_OK(status)) {
                        printf("cli_push returned: %s\n", nt_errstr(status));
                        goto fail;
@@ -5692,6 +5807,7 @@ static struct {
        {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
        {"RW3",  run_readwritelarge, 0},
        {"OPEN", run_opentest, 0},
+       {"POSIX", run_simple_posix_open_test, 0},
 #if 1
        {"OPENATTR", run_openattrtest, 0},
 #endif
index 950ca72ed8d3aa3c6cc2944e4f6aa24c66793436..8a2ebfb01f54d2f4aeb659756eb12ec1be300be3 100644 (file)
@@ -77,62 +77,6 @@ static void display_print_driver3(struct spoolss_DriverInfo3 *r)
        printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype);
 }
 
-static void display_print_driver_3(DRIVER_INFO_3 *i1)
-{
-       fstring name = "";
-       fstring architecture = "";
-       fstring driverpath = "";
-       fstring datafile = "";
-       fstring configfile = "";
-       fstring helpfile = "";
-       fstring dependentfiles = "";
-       fstring monitorname = "";
-       fstring defaultdatatype = "";
-
-       int length=0;
-       bool valid = true;
-
-       if (i1 == NULL)
-               return;
-
-       rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
-       rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
-       rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
-       rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
-       rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
-       rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
-       rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
-       rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
-
-       d_printf ("Printer Driver Info 3:\n");
-       d_printf ("\tVersion: [%x]\n", i1->version);
-       d_printf ("\tDriver Name: [%s]\n",name);
-       d_printf ("\tArchitecture: [%s]\n", architecture);
-       d_printf ("\tDriver Path: [%s]\n", driverpath);
-       d_printf ("\tDatafile: [%s]\n", datafile);
-       d_printf ("\tConfigfile: [%s]\n", configfile);
-       d_printf ("\tHelpfile: [%s]\n\n", helpfile);
-
-       while (valid) {
-               rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
-
-               length+=strlen(dependentfiles)+1;
-
-               if (strlen(dependentfiles) > 0) {
-                       d_printf ("\tDependentfiles: [%s]\n", dependentfiles);
-               } else {
-                       valid = false;
-               }
-       }
-
-       printf ("\n");
-
-       d_printf ("\tMonitorname: [%s]\n", monitorname);
-       d_printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
-
-       return;
-}
-
 static void display_reg_value(const char *subkey, REGISTRY_VALUE value)
 {
        char *text;
@@ -713,14 +657,19 @@ static bool net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd,
                                        uint32 flags,
                                        uint32 level,
                                        uint32 *num_printers,
-                                       PRINTER_INFO_CTR *ctr)
+                                       union spoolss_PrinterInfo **info)
 {
        WERROR result;
 
        /* enum printers */
-       result = rpccli_spoolss_enum_printers(pipe_hnd, mem_ctx, name, flags,
-               level, num_printers, ctr);
 
+       result = rpccli_spoolss_enumprinters(pipe_hnd, mem_ctx,
+                                            flags,
+                                            name,
+                                            level,
+                                            0,
+                                            num_printers,
+                                            info);
        if (!W_ERROR_IS_OK(result)) {
                printf("cannot enum printers: %s\n", win_errstr(result));
                return false;
@@ -978,16 +927,19 @@ static bool net_spoolss_enumforms(struct rpc_pipe_client *pipe_hnd,
 static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd,
                                        TALLOC_CTX *mem_ctx,
                                        uint32 level, const char *env,
-                                       uint32 *num_drivers,
-                                       PRINTER_DRIVER_CTR *ctr)
+                                       uint32 *count,
+                                       union spoolss_DriverInfo **info)
 {
        WERROR result;
 
        /* enumprinterdrivers call */
-       result = rpccli_spoolss_enumprinterdrivers(
-                       pipe_hnd, mem_ctx, level,
-                       env, num_drivers, ctr);
-
+       result = rpccli_spoolss_enumprinterdrivers(pipe_hnd, mem_ctx,
+                                                  pipe_hnd->srv_name_slash,
+                                                  env,
+                                                  level,
+                                                  0,
+                                                  count,
+                                                  info);
        if (!W_ERROR_IS_OK(result)) {
                printf("cannot enum drivers: %s\n", win_errstr(result));
                return false;
@@ -1082,26 +1034,21 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd,
                        int argc,
                        const char **argv,
                        uint32 *num_printers,
-                       PRINTER_INFO_CTR *ctr)
+                       union spoolss_PrinterInfo **info_p)
 {
-
        POLICY_HND hnd;
-       union spoolss_PrinterInfo info;
 
        /* no arguments given, enumerate all printers */
        if (argc == 0) {
 
                if (!net_spoolss_enum_printers(pipe_hnd, mem_ctx, NULL,
                                PRINTER_ENUM_LOCAL|PRINTER_ENUM_SHARED,
-                               level, num_printers, ctr))
+                               level, num_printers, info_p))
                        return false;
 
                goto out;
        }
 
-       /* FIXME GD */
-       return false;
-
        /* argument given, get a single printer by name */
        if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, argv[0],
                                         MAXIMUM_ALLOWED_ACCESS,
@@ -1109,7 +1056,7 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd,
                                         &hnd))
                return false;
 
-       if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) {
+       if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, *info_p)) {
                rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL);
                return false;
        }
@@ -1154,26 +1101,19 @@ NTSTATUS rpc_printer_list_internals(struct net_context *c,
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        uint32 i, num_printers;
        uint32 level = 2;
-       char *printername, *sharename;
-       PRINTER_INFO_CTR ctr;
+       const char *printername, *sharename;
+       union spoolss_PrinterInfo *info;
 
        printf("listing printers\n");
 
-       if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr))
+       if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info))
                return nt_status;
 
        for (i = 0; i < num_printers; i++) {
+
                /* do some initialization */
-               rpcstr_pull_talloc(mem_ctx,
-                               &printername,
-                               ctr.printers_2[i].printername.buffer,
-                               -1,
-                               STR_TERMINATE);
-               rpcstr_pull_talloc(mem_ctx,
-                               &sharename,
-                               ctr.printers_2[i].sharename.buffer,
-                               -1,
-                               STR_TERMINATE);
+               printername = info[i].info2.printername;
+               sharename = info[i].info2.sharename;
 
                if (printername && sharename) {
                        d_printf("printer %d: %s, shared as: %s\n",
@@ -1213,11 +1153,9 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c,
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        uint32 i;
        uint32 level = 3;
-       PRINTER_DRIVER_CTR drv_ctr_enum;
+       union spoolss_DriverInfo *info;
        int d;
 
-       ZERO_STRUCT(drv_ctr_enum);
-
        printf("listing printer-drivers\n");
 
         for (i=0; archi_table[i].long_archi!=NULL; i++) {
@@ -1227,7 +1165,7 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c,
                /* enum remote drivers */
                if (!net_spoolss_enumprinterdrivers(pipe_hnd, mem_ctx, level,
                                archi_table[i].long_archi,
-                               &num_drivers, &drv_ctr_enum)) {
+                               &num_drivers, &info)) {
                        nt_status = NT_STATUS_UNSUCCESSFUL;
                        goto done;
                }
@@ -1244,7 +1182,7 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c,
 
                /* do something for all drivers for architecture */
                for (d = 0; d < num_drivers; d++) {
-                       display_print_driver_3(&(drv_ctr_enum.info3[d]));
+                       display_print_driver3(&info[d].info3);
                }
        }
 
@@ -1277,8 +1215,8 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        uint32 i, num_printers;
        uint32 level = 7;
-       char *printername, *sharename;
-       PRINTER_INFO_CTR ctr;
+       const char *printername, *sharename;
+       union spoolss_PrinterInfo *info_enum;
        union spoolss_PrinterInfo info;
        struct spoolss_SetPrinterInfoCtr info_ctr;
        struct spoolss_DevmodeContainer devmode_ctr;
@@ -1287,21 +1225,14 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_
        WERROR result;
        const char *action_str;
 
-       if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr))
+       if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum))
                return nt_status;
 
        for (i = 0; i < num_printers; i++) {
+
                /* do some initialization */
-               rpcstr_pull_talloc(mem_ctx,
-                               &printername,
-                               ctr.printers_2[i].printername.buffer,
-                               -1,
-                               STR_TERMINATE);
-               rpcstr_pull_talloc(mem_ctx,
-                               &sharename,
-                               ctr.printers_2[i].sharename.buffer,
-                               -1,
-                               STR_TERMINATE);
+               printername = info_enum[i].info2.printername;
+               sharename = info_enum[i].info2.sharename;
                if (!printername || !sharename) {
                        goto done;
                }
@@ -1429,29 +1360,21 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c,
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        uint32 i, num_printers;
        uint32 level = 7;
-       char *printername, *sharename;
-       PRINTER_INFO_CTR ctr, ctr_pub;
+       const char *printername, *sharename;
+       union spoolss_PrinterInfo *info_enum;
        union spoolss_PrinterInfo info;
        POLICY_HND hnd;
        int state;
 
-       if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr))
+       if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum))
                return nt_status;
 
        for (i = 0; i < num_printers; i++) {
-               ZERO_STRUCT(ctr_pub);
 
                /* do some initialization */
-               rpcstr_pull_talloc(mem_ctx,
-                               &printername,
-                               ctr.printers_2[i].printername.buffer,
-                               -1,
-                               STR_TERMINATE);
-               rpcstr_pull_talloc(mem_ctx,
-                               &sharename,
-                               ctr.printers_2[i].sharename.buffer,
-                               -1,
-                               STR_TERMINATE);
+               printername = info_enum[i].info2.printername;
+               sharename = info_enum[i].info2.sharename;
+
                if (!printername || !sharename) {
                        goto done;
                }
@@ -1530,15 +1453,13 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c,
        uint32 i = 0;
        uint32 num_printers;
        uint32 level = 2;
-       char *printername, *sharename;
+       const char *printername, *sharename;
        struct rpc_pipe_client *pipe_hnd_dst = NULL;
        POLICY_HND hnd_src, hnd_dst;
-       PRINTER_INFO_CTR ctr_src, ctr_enum;
+       union spoolss_PrinterInfo *info_enum;
        struct cli_state *cli_dst = NULL;
        union spoolss_PrinterInfo info_src, info_dst;
 
-       ZERO_STRUCT(ctr_src);
-
        DEBUG(3,("copying printer ACLs\n"));
 
        /* connect destination PI_SPOOLSS */
@@ -1549,7 +1470,7 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c,
 
 
        /* enum source printers */
-       if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) {
+       if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) {
                nt_status = NT_STATUS_UNSUCCESSFUL;
                goto done;
        }
@@ -1562,17 +1483,11 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c,
 
        /* do something for all printers */
        for (i = 0; i < num_printers; i++) {
+
                /* do some initialization */
-               rpcstr_pull_talloc(mem_ctx,
-                               &printername,
-                               ctr_enum.printers_2[i].printername.buffer,
-                               -1,
-                               STR_TERMINATE);
-               rpcstr_pull_talloc(mem_ctx,
-                               &sharename,
-                               ctr_enum.printers_2[i].sharename.buffer,
-                               -1,
-                               STR_TERMINATE);
+               printername = info_enum[i].info2.printername;
+               sharename = info_enum[i].info2.sharename;
+
                if (!printername || !sharename) {
                        nt_status = NT_STATUS_UNSUCCESSFUL;
                        goto done;
@@ -1684,17 +1599,15 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c,
        uint32 i, f;
        uint32 num_printers;
        uint32 level = 1;
-       char *printername, *sharename;
+       const char *printername, *sharename;
        struct rpc_pipe_client *pipe_hnd_dst = NULL;
        POLICY_HND hnd_src, hnd_dst;
-       PRINTER_INFO_CTR ctr_enum;
+       union spoolss_PrinterInfo *info_enum;
        union spoolss_PrinterInfo info_dst;
        uint32_t num_forms;
        union spoolss_FormInfo *forms;
        struct cli_state *cli_dst = NULL;
 
-       ZERO_STRUCT(ctr_enum);
-
        DEBUG(3,("copying forms\n"));
 
        /* connect destination PI_SPOOLSS */
@@ -1704,7 +1617,7 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c,
                return nt_status;
 
        /* enum src printers */
-       if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr_enum)) {
+       if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum)) {
                nt_status = NT_STATUS_UNSUCCESSFUL;
                goto done;
        }
@@ -1717,17 +1630,11 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c,
 
        /* do something for all printers */
        for (i = 0; i < num_printers; i++) {
+
                /* do some initialization */
-               rpcstr_pull_talloc(mem_ctx,
-                               &printername,
-                               ctr_enum.printers_2[i].printername.buffer,
-                               -1,
-                               STR_TERMINATE);
-               rpcstr_pull_talloc(mem_ctx,
-                               &sharename,
-                               ctr_enum.printers_2[i].sharename.buffer,
-                               -1,
-                               STR_TERMINATE);
+               printername = info_enum[i].info2.printername;
+               sharename = info_enum[i].info2.sharename;
+
                if (!printername || !sharename) {
                        nt_status = NT_STATUS_UNSUCCESSFUL;
                        goto done;
@@ -1852,22 +1759,19 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
        uint32 i, p;
        uint32 num_printers;
        uint32 level = 3;
-       char *printername, *sharename;
+       const char *printername, *sharename;
        bool got_src_driver_share = false;
        bool got_dst_driver_share = false;
        struct rpc_pipe_client *pipe_hnd_dst = NULL;
        POLICY_HND hnd_src, hnd_dst;
        union spoolss_DriverInfo drv_info_src;
-       PRINTER_INFO_CTR info_ctr_enum, info_ctr_dst;
+       union spoolss_PrinterInfo *info_enum;
        union spoolss_PrinterInfo info_dst;
        struct cli_state *cli_dst = NULL;
        struct cli_state *cli_share_src = NULL;
        struct cli_state *cli_share_dst = NULL;
        const char *drivername = NULL;
 
-       ZERO_STRUCT(info_ctr_enum);
-       ZERO_STRUCT(info_ctr_dst);
-
        DEBUG(3,("copying printer-drivers\n"));
 
        nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
@@ -1894,7 +1798,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
 
 
        /* enum src printers */
-       if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_ctr_enum)) {
+       if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum)) {
                nt_status = NT_STATUS_UNSUCCESSFUL;
                goto done;
        }
@@ -1908,17 +1812,11 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
 
        /* do something for all printers */
        for (p = 0; p < num_printers; p++) {
+
                /* do some initialization */
-               rpcstr_pull_talloc(mem_ctx,
-                               &printername,
-                               info_ctr_enum.printers_2[p].printername.buffer,
-                               -1,
-                               STR_TERMINATE);
-               rpcstr_pull_talloc(mem_ctx,
-                               &sharename,
-                               info_ctr_enum.printers_2[p].sharename.buffer,
-                               -1,
-                               STR_TERMINATE);
+               printername = info_enum[p].info2.printername;
+               sharename = info_enum[p].info2.sharename;
+
                if (!printername || !sharename) {
                        nt_status = NT_STATUS_UNSUCCESSFUL;
                        goto done;
@@ -2072,11 +1970,11 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c,
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        uint32 i = 0, num_printers;
        uint32 level = 2;
-       PRINTER_INFO_CTR ctr_enum;
        union spoolss_PrinterInfo info_dst, info_src;
+       union spoolss_PrinterInfo *info_enum;
        struct cli_state *cli_dst = NULL;
        POLICY_HND hnd_dst, hnd_src;
-       char *printername, *sharename;
+       const char *printername, *sharename;
        struct rpc_pipe_client *pipe_hnd_dst = NULL;
        struct spoolss_SetPrinterInfoCtr info_ctr;
 
@@ -2089,7 +1987,7 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c,
                return nt_status;
 
        /* enum printers */
-       if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) {
+       if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) {
                nt_status = NT_STATUS_UNSUCCESSFUL;
                goto done;
        }
@@ -2102,17 +2000,11 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c,
 
        /* do something for all printers */
        for (i = 0; i < num_printers; i++) {
+
                /* do some initialization */
-               rpcstr_pull_talloc(mem_ctx,
-                               &printername,
-                               ctr_enum.printers_2[i].printername.buffer,
-                               -1,
-                               STR_TERMINATE);
-               rpcstr_pull_talloc(mem_ctx,
-                               &sharename,
-                               ctr_enum.printers_2[i].sharename.buffer,
-                               -1,
-                               STR_TERMINATE);
+               printername = info_enum[i].info2.printername;
+               sharename = info_enum[i].info2.sharename;
+
                if (!printername || !sharename) {
                        nt_status = NT_STATUS_UNSUCCESSFUL;
                        goto done;
@@ -2235,11 +2127,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
        uint32 i = 0, p = 0, j = 0;
        uint32 num_printers, val_needed, data_needed;
        uint32 level = 2;
-       char *printername, *sharename;
+       const char *printername, *sharename;
        struct rpc_pipe_client *pipe_hnd_dst = NULL;
        POLICY_HND hnd_src, hnd_dst;
-       PRINTER_INFO_CTR ctr_enum;
-       union spoolss_PrinterInfo info_dst_publish, info_dst;
+       union spoolss_PrinterInfo *info_enum;
+       union spoolss_PrinterInfo info_dst_publish;
+       union spoolss_PrinterInfo info_dst;
        REGVAL_CTR *reg_ctr;
        struct cli_state *cli_dst = NULL;
        char *devicename = NULL, *unc_name = NULL, *url = NULL;
@@ -2247,7 +2140,6 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
 
        uint16 *keylist = NULL, *curkey;
 
-       ZERO_STRUCT(ctr_enum);
        /* FIXME GD */
        ZERO_STRUCT(info_dst_publish);
 
@@ -2260,7 +2152,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
                return nt_status;
 
        /* enum src printers */
-       if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) {
+       if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) {
                nt_status = NT_STATUS_UNSUCCESSFUL;
                goto done;
        }
@@ -2281,17 +2173,11 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
 
        /* do something for all printers */
        for (i = 0; i < num_printers; i++) {
+
                /* do some initialization */
-               rpcstr_pull_talloc(mem_ctx,
-                               &printername,
-                               ctr_enum.printers_2[i].printername.buffer,
-                               -1,
-                               STR_TERMINATE);
-               rpcstr_pull_talloc(mem_ctx,
-                               &sharename,
-                               ctr_enum.printers_2[i].sharename.buffer,
-                               -1,
-                               STR_TERMINATE);
+               printername = info_enum[i].info2.printername;
+               sharename = info_enum[i].info2.sharename;
+
                if (!printername || !sharename) {
                        nt_status = NT_STATUS_UNSUCCESSFUL;
                        goto done;
@@ -2319,20 +2205,19 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
                                level, &info_dst))
                        goto done;
 
-#if 0 /* FIXME GD */
 
                /* STEP 1: COPY DEVICE-MODE and other
                           PRINTER_INFO_2-attributes
                */
 
-               info_dst.info2 = &ctr_enum.printers_2[i];
+               info_dst.info2 = info_enum[i].info2;
 
                /* why is the port always disconnected when the printer
                   is correctly installed (incl. driver ???) */
                info_dst.info2.portname = SAMBA_PRINTER_PORT_NAME;
 
                /* check if printer is published */
-               if (ctr_enum.printers_2[i].attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
+               if (info_enum[i].info2.attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
 
                        /* check for existing dst printer */
                        if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish))
@@ -2346,13 +2231,10 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
                        DEBUG(3,("republished printer\n"));
                }
 
-               if (ctr_enum.printers_2[i].devmode != NULL) {
+               if (info_enum[i].info2.devmode != NULL) {
 
                        /* copy devmode (info level 2) */
-                       info_dst.info2.devmode = (DEVICEMODE *)
-                               TALLOC_MEMDUP(mem_ctx,
-                                             ctr_enum.printers_2[i].devmode,
-                                             sizeof(DEVICEMODE));
+                       info_dst.info2.devmode = info_enum[i].info2.devmode;
 
                        /* do not copy security descriptor (we have another
                         * command for that) */
@@ -2374,7 +2256,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
 
                        DEBUGADD(1,("\tSetPrinter of DEVICEMODE succeeded\n"));
                }
-#endif
+
                /* STEP 2: COPY REGISTRY VALUES */
 
                /* please keep in mind that samba parse_spools gives horribly
index 9abf425f3e54284cc67c37d37c30f7108acd2a1f..ad4a7ddd997f6fc742a9c66193a067fb5bf2f95f 100644 (file)
@@ -18,6 +18,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
 
 #include "includes.h"
+#include "winbindd.h"
+#include "winbindd_proto.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_IDMAP
@@ -36,7 +38,8 @@ NTSTATUS idmap_uid_to_sid(const char *domname, DOM_SID *sid, uid_t uid)
        DEBUG(10,("idmap_uid_to_sid: uid = [%lu], domain = '%s'\n",
                  (unsigned long)uid, domname?domname:"NULL"));
 
-       if (idmap_cache_find_uid2sid(uid, sid, &expired)) {
+       if (winbindd_use_idmap_cache()
+           && idmap_cache_find_uid2sid(uid, sid, &expired)) {
                DEBUG(10, ("idmap_cache_find_uid2sid found %d%s\n", uid,
                           expired ? " (expired)": ""));
                if (expired && idmap_is_online()) {
@@ -63,14 +66,18 @@ backend:
        }
 
        if (map.status != ID_MAPPED) {
-               struct dom_sid null_sid;
-               ZERO_STRUCT(null_sid);
-               idmap_cache_set_sid2uid(&null_sid, uid);
+               if (winbindd_use_idmap_cache()) {
+                       struct dom_sid null_sid;
+                       ZERO_STRUCT(null_sid);
+                       idmap_cache_set_sid2uid(&null_sid, uid);
+               }
                DEBUG(10, ("uid [%lu] not mapped\n", (unsigned long)uid));
                return NT_STATUS_NONE_MAPPED;
        }
 
-       idmap_cache_set_sid2uid(sid, uid);
+       if (winbindd_use_idmap_cache()) {
+               idmap_cache_set_sid2uid(sid, uid);
+       }
 
        return NT_STATUS_OK;
 }
@@ -89,7 +96,8 @@ NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid)
        DEBUG(10,("idmap_gid_to_si: gid = [%lu], domain = '%s'\n",
                  (unsigned long)gid, domname?domname:"NULL"));
 
-       if (idmap_cache_find_gid2sid(gid, sid, &expired)) {
+       if (winbindd_use_idmap_cache()
+           && idmap_cache_find_gid2sid(gid, sid, &expired)) {
                DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n", gid,
                           expired ? " (expired)": ""));
                if (expired && idmap_is_online()) {
@@ -116,14 +124,18 @@ backend:
        }
 
        if (map.status != ID_MAPPED) {
-               struct dom_sid null_sid;
-               ZERO_STRUCT(null_sid);
-               idmap_cache_set_sid2uid(&null_sid, gid);
+               if (winbindd_use_idmap_cache()) {
+                       struct dom_sid null_sid;
+                       ZERO_STRUCT(null_sid);
+                       idmap_cache_set_sid2uid(&null_sid, gid);
+               }
                DEBUG(10, ("gid [%lu] not mapped\n", (unsigned long)gid));
                return NT_STATUS_NONE_MAPPED;
        }
 
-       idmap_cache_set_sid2gid(sid, gid);
+       if (winbindd_use_idmap_cache()) {
+               idmap_cache_set_sid2gid(sid, gid);
+       }
 
        return NT_STATUS_OK;
 }
@@ -142,7 +154,8 @@ NTSTATUS idmap_sid_to_uid(const char *dom_name, DOM_SID *sid, uid_t *uid)
        DEBUG(10,("idmap_sid_to_uid: sid = [%s], domain = '%s'\n",
                  sid_string_dbg(sid), dom_name));
 
-       if (idmap_cache_find_sid2uid(sid, uid, &expired)) {
+       if (winbindd_use_idmap_cache()
+           && idmap_cache_find_sid2uid(sid, uid, &expired)) {
                DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n",
                           (int)(*uid), expired ? " (expired)": ""));
                if (expired && idmap_is_online()) {
@@ -171,7 +184,9 @@ backend:
                                   map.status,
                                   map.xid.type,
                                   map.xid.id));
-                       idmap_cache_set_sid2uid(sid, -1);
+                       if (winbindd_use_idmap_cache()) {
+                               idmap_cache_set_sid2uid(sid, -1);
+                       }
                        return NT_STATUS_NONE_MAPPED;
                }
                goto done;
@@ -182,7 +197,9 @@ backend:
                 * We had the task to go to a specific domain which
                 * could not answer our request. Fail.
                 */
-               idmap_cache_set_sid2uid(sid, -1);
+               if (winbindd_use_idmap_cache()) {
+                       idmap_cache_set_sid2uid(sid, -1);
+               }
                return NT_STATUS_NONE_MAPPED;
        }
 
@@ -191,13 +208,17 @@ backend:
        if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(10, ("idmap_new_mapping failed: %s\n",
                           nt_errstr(ret)));
-               idmap_cache_set_sid2uid(sid, -1);
+               if (winbindd_use_idmap_cache()) {
+                       idmap_cache_set_sid2uid(sid, -1);
+               }
                return ret;
        }
 
 done:
        *uid = (uid_t)map.xid.id;
-       idmap_cache_set_sid2uid(sid, *uid);
+       if (winbindd_use_idmap_cache()) {
+               idmap_cache_set_sid2uid(sid, *uid);
+       }
        return NT_STATUS_OK;
 }
 
@@ -215,7 +236,8 @@ NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid)
        DEBUG(10,("idmap_sid_to_gid: sid = [%s], domain = '%s'\n",
                  sid_string_dbg(sid), domname));
 
-       if (idmap_cache_find_sid2gid(sid, gid, &expired)) {
+       if (winbindd_use_idmap_cache()
+           && idmap_cache_find_sid2gid(sid, gid, &expired)) {
                DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n",
                           (int)(*gid), expired ? " (expired)": ""));
                if (expired && idmap_is_online()) {
@@ -243,7 +265,9 @@ backend:
                                   map.status,
                                   map.xid.type,
                                   map.xid.id));
-                       idmap_cache_set_sid2gid(sid, -1);
+                       if (winbindd_use_idmap_cache()) {
+                               idmap_cache_set_sid2gid(sid, -1);
+                       }
                        return NT_STATUS_NONE_MAPPED;
                }
                goto done;
@@ -254,7 +278,9 @@ backend:
                 * We had the task to go to a specific domain which
                 * could not answer our request. Fail.
                 */
-               idmap_cache_set_sid2uid(sid, -1);
+               if (winbindd_use_idmap_cache()) {
+                       idmap_cache_set_sid2uid(sid, -1);
+               }
                return NT_STATUS_NONE_MAPPED;
        }
 
@@ -263,12 +289,16 @@ backend:
        if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(10, ("idmap_new_mapping failed: %s\n",
                           nt_errstr(ret)));
-               idmap_cache_set_sid2gid(sid, -1);
+               if (winbindd_use_idmap_cache()) {
+                       idmap_cache_set_sid2gid(sid, -1);
+               }
                return ret;
        }
 
 done:
        *gid = map.xid.id;
-       idmap_cache_set_sid2gid(sid, *gid);
+       if (winbindd_use_idmap_cache()) {
+               idmap_cache_set_sid2gid(sid, *gid);
+       }
        return NT_STATUS_OK;
 }
index e455d936e0503643b341e49c9765434e6f006553..f5812f9e6524c26d771fa97b677f73a69ef7cbe1 100644 (file)
@@ -28,7 +28,7 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
-bool opt_nocache = False;
+static bool opt_nocache = False;
 static bool interactive = False;
 
 extern bool override_logfile;
@@ -1090,6 +1090,16 @@ static void process_loop(void)
 #endif
 }
 
+bool winbindd_use_idmap_cache(void)
+{
+       return !opt_nocache;
+}
+
+bool winbindd_use_cache(void)
+{
+       return !opt_nocache;
+}
+
 /* Main function */
 
 int main(int argc, char **argv, char **envp)
index 02d0b5bc4e4a67611ce51bfe8697e15311284595..66166bf29250aa4e226c4ca8b585efcfcc348bb1 100644 (file)
@@ -34,7 +34,6 @@
 #define WINBINDD_CACHE_VERSION_KEYSTR "WINBINDD_CACHE_VERSION"
 
 extern struct winbindd_methods reconnect_methods;
-extern bool opt_nocache;
 #ifdef HAVE_ADS
 extern struct winbindd_methods ads_methods;
 #endif
@@ -632,7 +631,7 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
        char *kstr;
        struct cache_entry *centry;
 
-       if (opt_nocache) {
+       if (!winbindd_use_cache()) {
                return NULL;
        }
 
@@ -834,7 +833,7 @@ static void centry_end(struct cache_entry *centry, const char *format, ...)
        char *kstr;
        TDB_DATA key, data;
 
-       if (opt_nocache) {
+       if (!winbindd_use_cache()) {
                return;
        }
 
@@ -2861,8 +2860,9 @@ void wcache_flush_cache(void)
                tdb_close(wcache->tdb);
                wcache->tdb = NULL;
        }
-       if (opt_nocache)
+       if (!winbindd_use_cache()) {
                return;
+       }
 
        /* when working offline we must not clear the cache on restart */
        wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"),
index 7a53f19ffd4ee94ced4f3a717277043d66b3a063..e06e30e0a89fdbe1a40cd9011c0b6b321b8fd0a6 100644 (file)
@@ -866,7 +866,10 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
                        result = ads_ntstatus(ads_status);
                        if (NT_STATUS_IS_OK(result)) {
                                /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
-                               cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
+                               result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
+                               if (!NT_STATUS_IS_OK(result)) {
+                                       goto done;
+                               }
                                goto session_setup_done;
                        }
                }
@@ -891,7 +894,10 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
                result = ads_ntstatus(ads_status);
                if (NT_STATUS_IS_OK(result)) {
                        /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
-                       cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
+                       result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
+                       if (!NT_STATUS_IS_OK(result)) {
+                               goto done;
+                       }
                        goto session_setup_done;
                }
        }
@@ -917,7 +923,10 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
                                            ipc_password, strlen(ipc_password)+1,
                                            ipc_domain))) {
                        /* Successful logon with given username. */
-                       cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
+                       result = cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
+                       if (!NT_STATUS_IS_OK(result)) {
+                               goto done;
+                       }
                        goto session_setup_done;
                } else {
                        DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
@@ -935,7 +944,10 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
        if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
                                              NULL, 0, ""))) {
                DEBUG(5, ("Connected anonymously\n"));
-               cli_init_creds(*cli, "", "", "");
+               result = cli_init_creds(*cli, "", "", "");
+               if (!NT_STATUS_IS_OK(result)) {
+                       goto done;
+               }
                goto session_setup_done;
        }
 
@@ -970,8 +982,11 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
        *retry = False;
 
        /* set the domain if empty; needed for schannel connections */
-       if ( !*(*cli)->domain ) {
-               fstrcpy( (*cli)->domain, domain->name );
+       if ( !(*cli)->domain[0] ) {
+               result = cli_set_domain((*cli), domain->name);
+               if (!NT_STATUS_IS_OK(result)) {
+                       return result;
+               }
        }
 
        result = NT_STATUS_OK;
@@ -1979,7 +1994,6 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
 {
        struct winbindd_cm_conn *conn;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       fstring conn_pwd;
        struct dcinfo *p_dcinfo;
        char *machine_password = NULL;
        char *machine_account = NULL;
@@ -2004,10 +2018,9 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
         * anonymous.
         */
 
-       pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
        if ((conn->cli->user_name[0] == '\0') ||
            (conn->cli->domain[0] == '\0') || 
-           (conn_pwd[0] == '\0'))
+           (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
        {
                result = get_trust_creds(domain, &machine_password,
                                         &machine_account, NULL);
@@ -2018,7 +2031,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
                }
                domain_name = domain->name;
        } else {
-               machine_password = SMB_STRDUP(conn_pwd);                
+               machine_password = SMB_STRDUP(conn->cli->password);
                machine_account = SMB_STRDUP(conn->cli->user_name);
                domain_name = conn->cli->domain;
        }
@@ -2147,7 +2160,6 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
 {
        struct winbindd_cm_conn *conn;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       fstring conn_pwd;
        struct dcinfo *p_dcinfo;
 
        result = init_dc_connection(domain);
@@ -2160,10 +2172,9 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
                goto done;
        }
 
-       pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
        if ((conn->cli->user_name[0] == '\0') ||
            (conn->cli->domain[0] == '\0') || 
-           (conn_pwd[0] == '\0')) {
+           (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
                DEBUG(10, ("cm_connect_lsa: No no user available for "
                           "domain %s, trying schannel\n", conn->cli->domain));
                goto schannel;
@@ -2174,7 +2185,7 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
        result = cli_rpc_pipe_open_spnego_ntlmssp
                (conn->cli, &ndr_table_lsarpc.syntax_id,
                 PIPE_AUTH_LEVEL_PRIVACY,
-                conn->cli->domain, conn->cli->user_name, conn_pwd,
+                conn->cli->domain, conn->cli->user_name, conn->cli->password,
                 &conn->lsa_pipe);
 
        if (!NT_STATUS_IS_OK(result)) {
index 043f26e57863f1d3c8181d810db06c2055e2bd6c..6ad93adf4a2049c33c2bc97ac440acd26d3f995a 100644 (file)
@@ -25,8 +25,6 @@
 #include "includes.h"
 #include "winbindd.h"
 
-extern bool opt_nocache;
-
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
index c6e8803ce863b015f78418eb0b066b78176289eb..4fc96e8a4bb4b0db17a7a4871f7d3c545f0a1645 100644 (file)
@@ -65,6 +65,8 @@ void request_error(struct winbindd_cli_state *state);
 void request_ok(struct winbindd_cli_state *state);
 bool winbindd_setup_sig_term_handler(bool parent);
 bool winbindd_setup_sig_hup_handler(const char *lfile);
+bool winbindd_use_idmap_cache(void);
+bool winbindd_use_cache(void);
 int main(int argc, char **argv, char **envp);
 
 /* The following definitions come from winbindd/winbindd_ads.c  */
index 15b1b8ba40382573716ed20fd20566f360e14ff9..c42f0ba9fff60c44ab6b1ce8bc76f71dd9407d3a 100644 (file)
@@ -77,7 +77,7 @@ nsswrappersrcdir := ../lib/nss_wrapper
 appwebsrcdir := lib/appweb
 libstreamsrcdir := lib/stream
 libutilsrcdir := ../lib/util
-libtdrsrcdir := lib/tdr
+libtdrsrcdir := ../lib/tdr
 libcryptosrcdir := ../lib/crypto
 libtorturesrcdir := ../lib/torture
 smb_serversrcdir := smb_server
index a271a9f6fe4c8eca6e4e6486689bac29a1d0ac55..fb9ee58c60faeef47b527fb2b4374c826150deb4 100644 (file)
@@ -27,6 +27,7 @@ if test x"$ac_cv_header_sasl_sasl_h" = x"yes" -a x"$ac_cv_lib_ext_sasl2_sasl_cli
        SASL_CFLAGS="$CFLAGS"
        SASL_CPPFLAGS="$CPPFLAGS"
        SASL_LDFLAGS="$LDFLAGS"
+       LIB_REMOVE_USR_LIB(SASL_LDFLAGS)
 else
        SMB_ENABLE(cyrus_sasl,NO)
 fi
index ffdf92f78444a100315be4579b8f4a8e607ceb62..6860e56e7fc1f41c5f9046780aee9f6f450136c2 100644 (file)
@@ -99,11 +99,13 @@ AC_DEFUN([SMB_EXT_LIB_FROM_PKGCONFIG],
                                        AC_MSG_WARN([cannot run when cross-compiling]))
                                CFLAGS="$OLD_CFLAGS"
 
+                               ac_cv_$1_libs_only_other="`$PKG_CONFIG --libs-only-other '$2'` `$PKG_CONFIG --libs-only-L '$2'`"
+                               LIB_REMOVE_USR_LIB(ac_cv_$1_libs_only_other)
                                SMB_EXT_LIB($1, 
                                        [`$PKG_CONFIG --libs-only-l '$2'`], 
                                        [`$PKG_CONFIG --cflags-only-other '$2'`],
                                        [`$PKG_CONFIG --cflags-only-I '$2'`],
-                                       [`$PKG_CONFIG --libs-only-other '$2'` `$PKG_CONFIG --libs-only-L '$2'`])
+                                       [$ac_cv_$1_libs_only_other])
                                ac_cv_$1_found=yes
 
                        else
index 3c84a91a59e9f8641dafc765d987dc9eb0d61d7f..0d19e418270a0344925d64803fe3cf1e4b1526c7 100644 (file)
@@ -73,7 +73,7 @@ foreach my $key (values %$OUTPUT) {
                $shared_libs_used = 1;
        }
        if ($key->{TYPE} eq "MODULE" and @{$key->{OUTPUT_TYPE}}[0] eq "MERGED_OBJ" and defined($key->{INIT_FUNCTION})) {
-               $mkenv->output("$key->{SUBSYSTEM}_INIT_FUNCTIONS += $key->{INIT_FUNCTION},\n");
+               $mkenv->output("$key->{SUBSYSTEM}_INIT_FUNCTIONS +=$key->{INIT_FUNCTION},\n");
        }
        $mkenv->CFlags($key);
 }
index 792e90131a9d4b1539d97198229fa8e1b5a5ae9d..a1eb4f4b468d9f194f26f1bcf7ac4737487afda4 100644 (file)
@@ -59,7 +59,7 @@ SMB_INCLUDED_LIB_PKGCONFIG(LIBTDB, tdb >= 1.1.3,
 
 SMB_INCLUDE_MK(../lib/tdb/python.mk) 
 
-SMB_INCLUDED_LIB_PKGCONFIG(LIBTEVENT, tevent = 0.9.3,
+SMB_INCLUDED_LIB_PKGCONFIG(LIBTEVENT, tevent = 0.9.4,
        [],[m4_include(../lib/tevent/samba.m4)]
 )
 
index 89ca7bbe5ca6833c7c05c52f3adc27958485094e..06bfbf61edd809b20b20b3d6f54e8a76700c5d1d 100644 (file)
@@ -17,6 +17,7 @@
 */
 
 #include "includes.h"
+#define TEVENT_DEPRECATED 1
 #include "lib/events/events.h"
 
 /*
@@ -65,6 +66,7 @@ struct tevent_context *s4_event_context_init(TALLOC_CTX *mem_ctx)
        ev = tevent_context_init_byname(mem_ctx, NULL);
        if (ev) {
                tevent_set_debug(ev, ev_wrap_debug, NULL);
+               tevent_loop_allow_nesting(ev);
        }
        return ev;
 }
index f1b28b6819b7cb20152d44a232b5d4c3d2d1ea79..86ce2069a51e8ebd7ea1e5d32a49b465ad4d1d12 100644 (file)
@@ -32,6 +32,7 @@
  *  Author: Andrew Tridgell
  */
 
+#define TEVENT_DEPRECATED 1
 #include "ldb_private.h"
 
 static int ldb_context_destructor(void *ptr)
@@ -47,6 +48,40 @@ static int ldb_context_destructor(void *ptr)
        return 0;
 }
 
+/*
+  this is used to catch debug messages from events
+*/
+static void ldb_tevent_debug(void *context, enum tevent_debug_level level,
+                            const char *fmt, va_list ap)  PRINTF_ATTRIBUTE(3,0);
+
+static void ldb_tevent_debug(void *context, enum tevent_debug_level level,
+                            const char *fmt, va_list ap)
+{
+       struct ldb_context *ldb = talloc_get_type(context, struct ldb_context);
+       enum ldb_debug_level ldb_level = LDB_DEBUG_FATAL;
+       char *s = NULL;
+
+       switch (level) {
+       case TEVENT_DEBUG_FATAL:
+               ldb_level = LDB_DEBUG_FATAL;
+               break;
+       case TEVENT_DEBUG_ERROR:
+               ldb_level = LDB_DEBUG_ERROR;
+               break;
+       case TEVENT_DEBUG_WARNING:
+               ldb_level = LDB_DEBUG_WARNING;
+               break;
+       case TEVENT_DEBUG_TRACE:
+               ldb_level = LDB_DEBUG_TRACE;
+               break;
+       };
+
+       vasprintf(&s, fmt, ap);
+       if (!s) return;
+       ldb_debug(ldb, ldb_level, "tevent: %s", s);
+       free(s);
+}
+
 /*
    initialise a ldb context
    The mem_ctx is required
@@ -62,6 +97,8 @@ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx)
         * until we have them all converted */
        if (ev_ctx == NULL) {
                ev_ctx = tevent_context_init(talloc_autofree_context());
+               tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb);
+               tevent_loop_allow_nesting(ev_ctx);
        }
 
        ret = ldb_setup_wellknown_attributes(ldb);
index ee2018fb694f7dae00683c77eba272f8aac6a6a4..8ea9727ed3bc2a92a3c92339ce642f4b65b0073a 100644 (file)
@@ -20,7 +20,7 @@ mkinclude ../lib/socket_wrapper/config.mk
 mkinclude ../lib/nss_wrapper/config.mk
 mkinclude lib/stream/config.mk
 mkinclude ../lib/util/config.mk
-mkinclude lib/tdr/config.mk
+mkinclude ../lib/tdr/config.mk
 mkinclude ../lib/crypto/config.mk
 mkinclude ../lib/torture/config.mk
 mkinclude lib/basic.mk
index 614970d3ec5b6bfadd144853fd29d99ebfcb76ef..b92a91e2ef562a8cffa0004581a2331254bc3d6f 100644 (file)
@@ -28,6 +28,7 @@ import ldb
 from samba.idmap import IDmapDB
 import pwd
 import time
+import base64
 
 __docformat__ = "restructuredText"
 
@@ -59,7 +60,7 @@ dn: CN=%s,CN=ForeignSecurityPrincipals,%s
 objectClass: top
 objectClass: foreignSecurityPrincipal
 description: %s
-        """ % (sid, domaindn, desc)
+""" % (sid, domaindn, desc)
         # deliberately ignore errors from this, as the records may
         # already exist
         for msg in self.parse_ldif(add):
@@ -175,11 +176,11 @@ userAccountControl: %u
             user_dn = res[0].dn
 
             setpw = """
-    dn: %s
-    changetype: modify
-    replace: userPassword
-    userPassword: %s
-    """ % (user_dn, password)
+dn: %s
+changetype: modify
+replace: userPassword
+userPassword:: %s
+""" % (user_dn, base64.b64encode(password))
 
             self.modify_ldif(setpw)
 
@@ -229,13 +230,13 @@ userAccountControl: %u
                 accountExpires = glue.unix2nttime(expiry_seconds + int(time.time()))
 
             mod = """
-    dn: %s
-    changetype: modify
-    replace: userAccountControl
-    userAccountControl: %u
-    replace: accountExpires
-    accountExpires: %u
-    """ % (res[0].dn, userAccountControl, accountExpires)
+dn: %s
+changetype: modify
+replace: userAccountControl
+userAccountControl: %u
+replace: accountExpires
+accountExpires: %u
+""" % (res[0].dn, userAccountControl, accountExpires)
             # now change the database
             self.modify_ldif(mod)
         except:
index 1fcfe5a050802e0260d8301dd1a674773ea0f0bc..ae2cb808360d93f3ee065496a524805ce4400eda 100644 (file)
@@ -30,7 +30,7 @@ struct bench_state {
        int pass_count, fail_count;
 };
 
-static void request_handler(struct cldap_request *req)
+static void request_netlogon_handler(struct cldap_request *req)
 {
        struct cldap_netlogon io;
        struct bench_state *state = talloc_get_type(req->async.private_data, struct bench_state);
@@ -47,9 +47,9 @@ static void request_handler(struct cldap_request *req)
 }
 
 /*
-  benchmark cldap calls
+  benchmark cldap netlogon calls
 */
-static bool bench_cldap(struct torture_context *tctx, const char *address)
+static bool bench_cldap_netlogon(struct torture_context *tctx, const char *address)
 {
        struct cldap_socket *cldap;
        int num_sent=0;
@@ -69,14 +69,14 @@ static bool bench_cldap(struct torture_context *tctx, const char *address)
        search.in.acct_control = -1;
        search.in.version = 6;
 
-       printf("Running for %d seconds\n", timelimit);
+       printf("Running CLDAP/netlogon for %d seconds\n", timelimit);
        while (timeval_elapsed(&tv) < timelimit) {
                while (num_sent - (state->pass_count+state->fail_count) < 10) {
                        struct cldap_request *req;
                        req = cldap_netlogon_send(cldap, &search);
 
                        req->async.private_data = state;
-                       req->async.fn = request_handler;
+                       req->async.fn = request_netlogon_handler;
                        num_sent++;
                        if (num_sent % 50 == 0) {
                                if (torture_setting_bool(tctx, "progress", true)) {
@@ -103,6 +103,78 @@ static bool bench_cldap(struct torture_context *tctx, const char *address)
        return ret;
 }
 
+static void request_rootdse_handler(struct cldap_request *req)
+{
+       struct cldap_search io;
+       struct bench_state *state = talloc_get_type(req->async.private_data, struct bench_state);
+       NTSTATUS status;
+       TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+       status = cldap_search_recv(req, tmp_ctx, &io);
+       if (NT_STATUS_IS_OK(status)) {
+               state->pass_count++;
+       } else {
+               state->fail_count++;
+       }
+       talloc_free(tmp_ctx);
+}
+
+/*
+  benchmark cldap netlogon calls
+*/
+static bool bench_cldap_rootdse(struct torture_context *tctx, const char *address)
+{
+       struct cldap_socket *cldap;
+       int num_sent=0;
+       struct timeval tv = timeval_current();
+       bool ret = true;
+       int timelimit = torture_setting_int(tctx, "timelimit", 10);
+       struct cldap_search search;
+       struct bench_state *state;
+
+       cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
+
+       state = talloc_zero(tctx, struct bench_state);
+
+       ZERO_STRUCT(search);
+       search.in.dest_address  = address;
+       search.in.dest_port     = lp_cldap_port(tctx->lp_ctx);
+       search.in.filter        = "(objectClass=*)";
+       search.in.timeout       = 2;
+       search.in.retries       = 1;
+
+       printf("Running CLDAP/rootdse for %d seconds\n", timelimit);
+       while (timeval_elapsed(&tv) < timelimit) {
+               while (num_sent - (state->pass_count+state->fail_count) < 10) {
+                       struct cldap_request *req;
+                       req = cldap_search_send(cldap, &search);
+
+                       req->async.private_data = state;
+                       req->async.fn = request_rootdse_handler;
+                       num_sent++;
+                       if (num_sent % 50 == 0) {
+                               if (torture_setting_bool(tctx, "progress", true)) {
+                                       printf("%.1f queries per second (%d failures)  \r",
+                                              state->pass_count / timeval_elapsed(&tv),
+                                              state->fail_count);
+                                       fflush(stdout);
+                               }
+                       }
+               }
+
+               tevent_loop_once(tctx->ev);
+       }
+
+       while (num_sent != (state->pass_count + state->fail_count)) {
+               tevent_loop_once(tctx->ev);
+       }
+
+       printf("%.1f queries per second (%d failures)  \n",
+              state->pass_count / timeval_elapsed(&tv),
+              state->fail_count);
+
+       talloc_free(cldap);
+       return ret;
+}
 
 /*
   benchmark how fast a CLDAP server can respond to a series of parallel
@@ -125,7 +197,8 @@ bool torture_bench_cldap(struct torture_context *torture)
                return false;
        }
 
-       ret &= bench_cldap(torture, address);
+       ret &= bench_cldap_netlogon(torture, address);
+       ret &= bench_cldap_rootdse(torture, address);
 
        return ret;
 }
index 36f4f08072a3fcde5a2586b183bb9494724baefa..967e545225a53fc029e80bcbd8d34adeed43e9a9 100644 (file)
@@ -44,7 +44,7 @@ TORTURE_LOCAL_OBJ_FILES = \
                $(torturesrcdir)/../../lib/compression/testsuite.o \
                $(torturesrcdir)/../../lib/util/charset/tests/charset.o \
                $(torturesrcdir)/../libcli/security/tests/sddl.o \
-               $(torturesrcdir)/../lib/tdr/testsuite.o \
+               $(libtdrsrcdir)/testsuite.o \
                $(torturesrcdir)/../../lib/tevent/testsuite.o \
                $(torturesrcdir)/../param/tests/share.o \
                $(torturesrcdir)/../param/tests/loadparm.o \
index ad8158d9562c6d11676e1a42abe8a9c2403c7c41..f8029b246b99b56bc11540fdd765187b62c316c8 100644 (file)
@@ -575,7 +575,7 @@ static bool test_EnumPrintProcDataTypes(struct torture_context *tctx,
        NTSTATUS status;
        struct spoolss_EnumPrintProcDataTypes r;
        uint16_t levels[] = { 1 };
-       int i, j;
+       int i;
 
        for (i=0;i<ARRAY_SIZE(levels);i++) {
                int level = levels[i];