Merge branch 'master' of git://git.samba.org/samba into minschema
authorJelmer Vernooij <jelmer@samba.org>
Fri, 20 Mar 2009 00:30:36 +0000 (01:30 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Fri, 20 Mar 2009 00:30:36 +0000 (01:30 +0100)
312 files changed:
.gitignore
docs-xml/manpages-3/idmap_hash.8.xml
docs-xml/manpages-3/vfs_preopen.8.xml [new file with mode: 0644]
docs-xml/smbdotconf/security/clientlanmanauth.xml
lib/async_req/async_req.c
lib/async_req/async_req.h
lib/async_req/async_sock.c
lib/async_req/async_sock.h
lib/replace/libreplace_network.m4
lib/replace/system/network.h
lib/smbconf/smbconf.c
lib/socket_wrapper/socket_wrapper.c
lib/socket_wrapper/socket_wrapper.h
lib/talloc/configure.ac
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/libtevent.m4
lib/tevent/tevent.c
lib/tevent/tevent.h
lib/tevent/tevent_epoll.c
lib/tevent/tevent_immediate.c [new file with mode: 0644]
lib/tevent/tevent_internal.h
lib/tevent/tevent_queue.c
lib/tevent/tevent_req.c
lib/tevent/tevent_select.c
lib/tevent/tevent_standard.c
lib/tsocket/config.mk [new file with mode: 0644]
lib/tsocket/tsocket.c [new file with mode: 0644]
lib/tsocket/tsocket.h [new file with mode: 0644]
lib/tsocket/tsocket_bsd.c [new file with mode: 0644]
lib/tsocket/tsocket_connect.c [new file with mode: 0644]
lib/tsocket/tsocket_guide.txt [new file with mode: 0644]
lib/tsocket/tsocket_helpers.c [new file with mode: 0644]
lib/tsocket/tsocket_internal.h [new file with mode: 0644]
lib/tsocket/tsocket_readv.c [new file with mode: 0644]
lib/tsocket/tsocket_recvfrom.c [new file with mode: 0644]
lib/tsocket/tsocket_sendto.c [new file with mode: 0644]
lib/tsocket/tsocket_writev.c [new file with mode: 0644]
lib/util/charset/charcnv.c
lib/util/charset/charset.h
lib/util/charset/iconv.c
lib/util/charset/util_unistr.c
lib/util/config.mk
lib/util/fault.m4
lib/util/util.c
lib/util/util.h
libcli/cldap/cldap.c [new file with mode: 0644]
libcli/cldap/cldap.h [new file with mode: 0644]
libcli/cldap/config.mk [new file with mode: 0644]
libcli/security/secace.c
libcli/security/secacl.c
libcli/util/doserr.c
libcli/util/werror.h
librpc/gen_ndr/cli_spoolss.c
librpc/gen_ndr/cli_spoolss.h
librpc/gen_ndr/ndr_drsblobs.c
librpc/gen_ndr/ndr_spoolss.c
librpc/gen_ndr/ndr_spoolss.h
librpc/gen_ndr/spoolss.h
librpc/gen_ndr/srv_spoolss.c
librpc/idl/spoolss.idl
librpc/ndr/ndr.c
librpc/ndr/ndr_spoolss_buf.c
librpc/ndr/ndr_spoolss_buf.h
m4/check_python.m4
m4/pkg.m4 [new file with mode: 0644]
nsswitch/pam_winbind.h
packaging/RHEL/samba.spec.tmpl
packaging/bin/fill-templates
pidl/README
pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
pidl/lib/Parse/Pidl/Samba4/TDR.pm
source3/Makefile.in
source3/autogen.sh
source3/client/client.c
source3/client/clitar.c
source3/client/mount.cifs.c
source3/configure.in
source3/include/client.h
source3/include/includes.h
source3/include/libsmb_internal.h
source3/include/nt_printing.h
source3/include/ntdomain.h
source3/include/passdb.h
source3/include/popt_common.h
source3/include/proto.h
source3/include/rpc_client.h
source3/include/rpc_dce.h
source3/include/rpc_misc.h
source3/include/rpc_spoolss.h [deleted file]
source3/include/smb.h
source3/include/smb_macros.h
source3/include/smbprofile.h
source3/include/vfs.h
source3/include/vfs_macros.h
source3/include/wbc_async.h
source3/lib/charcnv.c
source3/lib/dbwrap_ctdb.c
source3/lib/dbwrap_rbt.c
source3/lib/errmap_unix.c
source3/lib/events.c
source3/lib/iconv.c
source3/lib/interfaces.c
source3/lib/messages.c
source3/lib/netapi/cm.c
source3/lib/netapi/group.c
source3/lib/netapi/user.c
source3/lib/smbconf/smbconf_reg.c
source3/lib/smbconf/testsuite.c
source3/lib/util.c
source3/lib/util_sock.c
source3/lib/util_unistr.c
source3/lib/version_test.c [new file with mode: 0644]
source3/lib/wb_reqtrans.c
source3/lib/wbclient.c
source3/lib/winbind_util.c
source3/libaddns/dns.h
source3/libads/cldap.c
source3/libads/krb5_errs.c
source3/libads/ldap_printer.c
source3/libnet/libnet_join.c
source3/libsmb/cliconnect.c
source3/libsmb/clidfs.c
source3/libsmb/clientgen.c
source3/libsmb/clilist.c
source3/libsmb/clireadwrite.c
source3/libsmb/clitrans.c
source3/libsmb/libsmb_context.c
source3/libsmb/libsmb_dir.c
source3/libsmb/libsmb_file.c
source3/libsmb/libsmb_stat.c
source3/libsmb/libsmb_xattr.c
source3/libsmb/passchange.c
source3/libsmb/pwd_cache.c [deleted file]
source3/libsmb/smb_signing.c
source3/libsmb/trusts_util.c
source3/locking/locking.c
source3/m4/aclocal.m4
source3/modules/gpfs.c
source3/modules/onefs.h
source3/modules/onefs_cbrl.c
source3/modules/onefs_config.h
source3/modules/onefs_open.c
source3/modules/onefs_streams.c
source3/modules/onefs_system.c
source3/modules/vfs_acl_tdb.c
source3/modules/vfs_acl_xattr.c
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_gpfs.c
source3/modules/vfs_onefs.c
source3/modules/vfs_preopen.c [new file with mode: 0644]
source3/nmbd/nmbd_nameregister.c
source3/param/loadparm.c
source3/passdb/lookup_sid.c
source3/passdb/pdb_interface.c
source3/passdb/pdb_ldap.c
source3/passdb/pdb_smbpasswd.c
source3/passdb/pdb_tdb.c
source3/passdb/pdb_wbc_sam.c
source3/printing/notify.c
source3/printing/nt_printing.c
source3/printing/printing.c
source3/registry/reg_backend_printing.c
source3/registry/reg_perfcount.c
source3/rpc_client/cli_lsarpc.c
source3/rpc_client/cli_pipe.c
source3/rpc_client/cli_reg.c
source3/rpc_client/cli_samr.c
source3/rpc_client/cli_spoolss.c
source3/rpc_client/init_spoolss.c
source3/rpc_client/rpc_transport_sock.c
source3/rpc_parse/parse_buffer.c [deleted file]
source3/rpc_parse/parse_misc.c
source3/rpc_parse/parse_prs.c
source3/rpc_parse/parse_rpc.c
source3/rpc_parse/parse_spoolss.c [deleted file]
source3/rpc_server/srv_eventlog_nt.c
source3/rpc_server/srv_lsa_hnd.c
source3/rpc_server/srv_pipe.c
source3/rpc_server/srv_pipe_hnd.c
source3/rpc_server/srv_samr_nt.c
source3/rpc_server/srv_spoolss.c [deleted file]
source3/rpc_server/srv_spoolss_nt.c
source3/rpc_server/srv_svcctl_nt.c
source3/rpc_server/srv_winreg_nt.c
source3/rpcclient/cmd_lsarpc.c
source3/rpcclient/cmd_samr.c
source3/rpcclient/cmd_spoolss.c
source3/rpcclient/cmd_test.c
source3/rpcclient/rpcclient.c
source3/samba4.m4
source3/samba4.mk
source3/script/installmo.sh
source3/script/mkversion.sh
source3/script/tests/selftest.sh
source3/script/tests/test_smbtorture_s3.sh
source3/smbd/aio.c
source3/smbd/conn.c
source3/smbd/file_access.c
source3/smbd/ipc.c
source3/smbd/nttrans.c
source3/smbd/open.c
source3/smbd/pipes.c
source3/smbd/reply.c
source3/smbd/server.c
source3/smbd/service.c
source3/smbd/uid.c
source3/torture/torture.c
source3/utils/net.c
source3/utils/net_ads.c
source3/utils/net_conf.c
source3/utils/net_rpc.c
source3/utils/net_rpc_audit.c
source3/utils/net_rpc_join.c
source3/utils/net_rpc_printer.c
source3/utils/net_rpc_registry.c
source3/utils/net_rpc_rights.c
source3/utils/net_rpc_service.c
source3/utils/net_rpc_sh_acct.c
source3/utils/net_sam.c
source3/utils/net_util.c
source3/utils/netlookup.c
source3/utils/pdbedit.c
source3/utils/smbcacls.c
source3/utils/smbcontrol.c
source3/utils/smbcquotas.c
source3/utils/smbtree.c
source3/winbindd/idmap_ad.c
source3/winbindd/idmap_adex/idmap_adex.c
source3/winbindd/idmap_hash/idmap_hash.c
source3/winbindd/idmap_nss.c
source3/winbindd/idmap_rid.c
source3/winbindd/idmap_tdb.c
source3/winbindd/idmap_tdb2.c
source3/winbindd/idmap_util.c
source3/winbindd/winbindd.c
source3/winbindd/winbindd.h
source3/winbindd/winbindd_ads.c
source3/winbindd/winbindd_cache.c
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_group.c
source3/winbindd/winbindd_pam.c
source3/winbindd/winbindd_passdb.c
source3/winbindd/winbindd_proto.h
source3/winbindd/winbindd_rpc.c
source3/winbindd/winbindd_util.c
source4/Makefile
source4/aclocal.m4
source4/auth/config.m4
source4/build/m4/public.m4
source4/build/smb_build/main.pl
source4/cldap_server/cldap_server.c
source4/cldap_server/netlogon.c
source4/cldap_server/rootdse.c
source4/configure.ac
source4/dsdb/samdb/ldb_modules/objectclass.c
source4/dsdb/samdb/ldb_modules/password_hash.c
source4/dsdb/schema/schema_init.c
source4/headermap.txt
source4/include/includes.h
source4/lib/cmdline/popt_common.h
source4/lib/events/tevent_s4.c
source4/lib/ldb/common/ldb.c
source4/lib/ldb/ldb_tdb/ldb_index.c
source4/lib/ldb/ldb_tdb/ldb_search.c
source4/lib/ldb/ldb_tdb/ldb_tdb.c
source4/lib/ldb/ldb_tdb/ldb_tdb.h
source4/lib/ldb/tests/python/ldap.py
source4/lib/ldb/tools/cmdline.h
source4/libcli/cldap/cldap.c [deleted file]
source4/libcli/cldap/cldap.h [deleted file]
source4/libcli/config.mk
source4/libcli/smb2/connect.c
source4/libcli/smb2/smb2.h
source4/libcli/util/errormap.c
source4/libcli/util/nterr.c
source4/libnet/libnet_become_dc.c
source4/libnet/libnet_site.c
source4/libnet/libnet_unbecome_dc.c
source4/main.mk
source4/min_versions.m4 [new file with mode: 0644]
source4/ntptr/simple_ldb/ntptr_simple_ldb.c
source4/ntvfs/unixuid/vfs_unixuid.c
source4/param/provision.c
source4/param/util.c
source4/rpc_server/spoolss/dcesrv_spoolss.c
source4/script/installman.sh
source4/script/uninstallman.sh
source4/scripting/python/samba/provision.py
source4/scripting/python/samba/samdb.py
source4/scripting/python/samba/tests/dcerpc/rpcecho.py
source4/selftest/tests.sh
source4/setup/schema.ldif
source4/torture/ldap/cldap.c
source4/torture/ldap/cldapbench.c
source4/torture/local/config.mk
source4/torture/raw/notify.c
source4/torture/rpc/dssync.c
source4/torture/rpc/samba3rpc.c
source4/torture/rpc/spoolss.c
source4/torture/rpc/spoolss_notify.c
source4/torture/rpc/spoolss_win.c
source4/torture/smb2/create.c
source4/torture/smb2/lock.c
testprogs/blackbox/test_ldb.sh

index f1440ca3169022659f438314068ba882335b49b5..7a2462c77c7a2b170afccf7e949718796fc3c6f4 100644 (file)
@@ -280,6 +280,7 @@ source4/tests
 source4/torture/auth/proto.h
 source4/torture/basic/proto.h
 source4/torture/ldap/proto.h
+source4/torture/ldb/proto.h
 source4/torture/libnet/proto.h
 source4/torture/local/proto.h
 source4/torture/nbench/proto.h
index fbafd71627ff3fead2cf63b243e6678235537c48..dfaece24d608354f393d3e8ae73ef60a3f635f14 100644 (file)
 
 <refsynopsisdiv>
        <title>DESCRIPTION</title>
-       <para>The idmap_hash plugin implements a hashing algorithm used
-         map SIDs for domain users and groups to a 31-bit uid and gid.
+       <para>The idmap_hash plugin implements a hashing algorithm used to map
+         SIDs for domain users and groups to 31-bit uids and gids, respectively.
          This plugin also implements the nss_info API and can be used
          to support a local name mapping files if enabled via the
-         &quot;winbind normlaize names&quot; and &quot;winbind nss info&quot;
+         &quot;winbind normalize names&quot; and &quot;winbind nss info&quot;
          parameters in smb.conf.
        </para>
 </refsynopsisdiv>
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 967eacf85bb199bff4011b88a71589f44c1b307d..9c61dedeb90e67e58d2b535a098fec6018f6d58f 100644 (file)
@@ -17,7 +17,7 @@
     this option.  </para>
 
     <para>Disabling this option will also disable the <command
-    moreinfo="none">client plaintext auth</command> option</para>
+    moreinfo="none">client plaintext auth</command> option.</para>
 
     <para>Likewise, if the <command moreinfo="none">client ntlmv2
     auth</command> parameter is enabled, then only NTLMv2 logins will be
index 054c9f97cc6d328e4fec4698f6c5f0b405b864ab..4dfe809738e516f14cbc9423b65873a03f4c621a 100644 (file)
@@ -194,48 +194,6 @@ bool async_req_is_error(struct async_req *req, enum async_req_state *state,
        return true;
 }
 
-static void async_req_timedout(struct tevent_context *ev,
-                              struct tevent_timer *te,
-                              struct timeval now,
-                              void *priv)
-{
-       struct async_req *req = talloc_get_type_abort(priv, struct async_req);
-       TALLOC_FREE(te);
-       async_req_finish(req, ASYNC_REQ_TIMED_OUT);
-}
-
-bool async_req_set_timeout(struct async_req *req, struct tevent_context *ev,
-                          struct timeval to)
-{
-       return (tevent_add_timer(
-                       ev, req,
-                       tevent_timeval_current_ofs(to.tv_sec, to.tv_usec),
-                       async_req_timedout, req)
-               != NULL);
-}
-
-struct async_req *async_wait_send(TALLOC_CTX *mem_ctx,
-                                 struct tevent_context *ev,
-                                 struct timeval to)
-{
-       struct async_req *result;
-
-       result = async_req_new(mem_ctx);
-       if (result == NULL) {
-               return result;
-       }
-       if (!async_req_set_timeout(result, ev, to)) {
-               TALLOC_FREE(result);
-               return NULL;
-       }
-       return result;
-}
-
-bool async_wait_recv(struct async_req *req)
-{
-       return true;
-}
-
 struct async_queue_entry {
        struct async_queue_entry *prev, *next;
        struct async_req_queue *queue;
index fc849880cd65fa64665bfac7eed8c95ae6c099b6..fdec1b708e275f23709169f06bed57d64d6e5bc3 100644 (file)
@@ -139,15 +139,6 @@ bool async_post_error(struct async_req *req, struct tevent_context *ev,
 bool async_req_is_error(struct async_req *req, enum async_req_state *state,
                        uint64_t *error);
 
-bool async_req_set_timeout(struct async_req *req, struct tevent_context *ev,
-                          struct timeval to);
-
-struct async_req *async_wait_send(TALLOC_CTX *mem_ctx,
-                                 struct tevent_context *ev,
-                                 struct timeval to);
-
-bool async_wait_recv(struct async_req *req);
-
 struct async_req_queue;
 
 struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx);
index 1f48697f26f825a729c618165b36f0846de4fd9e..77df4060449f939fedbc709946cbfb491c89d4d1 100644 (file)
@@ -123,8 +123,8 @@ static void async_send_handler(struct tevent_context *ev,
 {
        struct tevent_req *req = talloc_get_type_abort(
                private_data, struct tevent_req);
-       struct async_send_state *state = talloc_get_type_abort(
-               req->private_state, struct async_send_state);
+       struct async_send_state *state =
+               tevent_req_data(req, struct async_send_state);
 
        state->sent = send(state->fd, state->buf, state->len, state->flags);
        if (state->sent == -1) {
@@ -136,8 +136,8 @@ static void async_send_handler(struct tevent_context *ev,
 
 ssize_t async_send_recv(struct tevent_req *req, int *perrno)
 {
-       struct async_send_state *state = talloc_get_type_abort(
-               req->private_state, struct async_send_state);
+       struct async_send_state *state =
+               tevent_req_data(req, struct async_send_state);
 
        if (tevent_req_is_unix_error(req, perrno)) {
                return -1;
@@ -189,8 +189,8 @@ static void async_recv_handler(struct tevent_context *ev,
 {
        struct tevent_req *req = talloc_get_type_abort(
                private_data, struct tevent_req);
-       struct async_recv_state *state = talloc_get_type_abort(
-               req->private_state, struct async_recv_state);
+       struct async_recv_state *state =
+               tevent_req_data(req, struct async_recv_state);
 
        state->received = recv(state->fd, state->buf, state->len,
                               state->flags);
@@ -203,8 +203,8 @@ static void async_recv_handler(struct tevent_context *ev,
 
 ssize_t async_recv_recv(struct tevent_req *req, int *perrno)
 {
-       struct async_recv_state *state = talloc_get_type_abort(
-               req->private_state, struct async_recv_state);
+       struct async_recv_state *state =
+               tevent_req_data(req, struct async_recv_state);
 
        if (tevent_req_is_unix_error(req, perrno)) {
                return -1;
@@ -317,8 +317,8 @@ static void async_connect_connected(struct tevent_context *ev,
 {
        struct tevent_req *req = talloc_get_type_abort(
                priv, struct tevent_req);
-       struct async_connect_state *state = talloc_get_type_abort(
-               req->private_state, struct async_connect_state);
+       struct async_connect_state *state =
+               tevent_req_data(req, struct async_connect_state);
 
        TALLOC_FREE(fde);
 
@@ -352,8 +352,8 @@ static void async_connect_connected(struct tevent_context *ev,
 
 int async_connect_recv(struct tevent_req *req, int *perrno)
 {
-       struct async_connect_state *state = talloc_get_type_abort(
-               req->private_state, struct async_connect_state);
+       struct async_connect_state *state =
+               tevent_req_data(req, struct async_connect_state);
        int err;
 
        fcntl(state->fd, F_SETFL, state->old_sockflags);
@@ -379,15 +379,16 @@ struct writev_state {
        size_t total_size;
 };
 
+static void writev_trigger(struct tevent_req *req, void *private_data);
 static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
                           uint16_t flags, void *private_data);
 
 struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
-                              int fd, struct iovec *iov, int count)
+                              struct tevent_queue *queue, int fd,
+                              struct iovec *iov, int count)
 {
        struct tevent_req *result;
        struct writev_state *state;
-       struct tevent_fd *fde;
 
        result = tevent_req_create(mem_ctx, &state, struct writev_state);
        if (result == NULL) {
@@ -403,25 +404,34 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
                goto fail;
        }
 
-       fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, writev_handler,
-                           result);
-       if (fde == NULL) {
+       if (!tevent_queue_add(queue, ev, result, writev_trigger, NULL)) {
                goto fail;
        }
        return result;
-
  fail:
        TALLOC_FREE(result);
        return NULL;
 }
 
+static void writev_trigger(struct tevent_req *req, void *private_data)
+{
+       struct writev_state *state = tevent_req_data(req, struct writev_state);
+       struct tevent_fd *fde;
+
+       fde = tevent_add_fd(state->ev, state, state->fd, TEVENT_FD_WRITE,
+                           writev_handler, req);
+       if (fde == NULL) {
+               tevent_req_error(req, ENOMEM);
+       }
+}
+
 static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
                           uint16_t flags, void *private_data)
 {
        struct tevent_req *req = talloc_get_type_abort(
                private_data, struct tevent_req);
-       struct writev_state *state = talloc_get_type_abort(
-               req->private_state, struct writev_state);
+       struct writev_state *state =
+               tevent_req_data(req, struct writev_state);
        size_t to_write, written;
        int i;
 
@@ -459,7 +469,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;
        }
@@ -467,8 +477,8 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
 
 ssize_t writev_recv(struct tevent_req *req, int *perrno)
 {
-       struct writev_state *state = talloc_get_type_abort(
-               req->private_state, struct writev_state);
+       struct writev_state *state =
+               tevent_req_data(req, struct writev_state);
 
        if (tevent_req_is_unix_error(req, perrno)) {
                return -1;
@@ -531,8 +541,8 @@ static void read_packet_handler(struct tevent_context *ev,
 {
        struct tevent_req *req = talloc_get_type_abort(
                private_data, struct tevent_req);
-       struct read_packet_state *state = talloc_get_type_abort(
-               req->private_state, struct read_packet_state);
+       struct read_packet_state *state =
+               tevent_req_data(req, struct read_packet_state);
        size_t total = talloc_get_size(state->buf);
        ssize_t nread, more;
        uint8_t *tmp;
@@ -584,8 +594,8 @@ static void read_packet_handler(struct tevent_context *ev,
 ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                         uint8_t **pbuf, int *perrno)
 {
-       struct read_packet_state *state = talloc_get_type_abort(
-               req->private_state, struct read_packet_state);
+       struct read_packet_state *state =
+               tevent_req_data(req, struct read_packet_state);
 
        if (tevent_req_is_unix_error(req, perrno)) {
                return -1;
index e001709d2783b4f5696875e208bab330bc55fb9f..c5d9400eb60e3ea6d3bcabfe894615b4747b1e0a 100644 (file)
@@ -43,7 +43,8 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
 int async_connect_recv(struct tevent_req *req, int *perrno);
 
 struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
-                              int fd, struct iovec *iov, int count);
+                              struct tevent_queue *queue, int fd,
+                              struct iovec *iov, int count);
 ssize_t writev_recv(struct tevent_req *req, int *perrno);
 
 struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx,
index 78fb1abaf014e247808731cbd7085ac141a50753..3bac72d136a3be4f6c96db7874e746c1794d8997 100644 (file)
@@ -8,14 +8,18 @@ LIBREPLACE_NETWORK_LIBS=""
 
 AC_CHECK_HEADERS(sys/socket.h netinet/in.h netdb.h arpa/inet.h)
 AC_CHECK_HEADERS(netinet/in_systm.h)
-AC_CHECK_HEADERS([netinet/ip.h], [], [],[#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_NETINET_IN_SYSTM_H
-#include <netinet/in_systm.h>
-#endif])
+AC_CHECK_HEADERS([netinet/ip.h], [], [],[
+       #include <sys/types.h>
+       #ifdef HAVE_NETINET_IN_H
+       #include <netinet/in.h>
+       #endif
+       #ifdef HAVE_NETINET_IN_SYSTM_H
+       #include <netinet/in_systm.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
@@ -241,7 +245,7 @@ AC_CHECK_MEMBERS([struct sockaddr.sa_len],
 
 dnl test for getifaddrs and freeifaddrs
 AC_CACHE_CHECK([for getifaddrs and freeifaddrs],libreplace_cv_HAVE_GETIFADDRS,[
-AC_TRY_COMPILE([
+AC_TRY_LINK([
 #include <sys/types.h>
 #if STDC_HEADERS
 #include <stdlib.h>
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 f25ccae0d41c9f819bb8256ec3824e904ff41dcd..80fe9aac3722c22772b3bf8e93d22430f2d8f008 100644 (file)
@@ -226,10 +226,6 @@ WERROR smbconf_set_parameter(struct smbconf_ctx *ctx,
                             const char *param,
                             const char *valstr)
 {
-       if (!smbconf_share_exists(ctx, service)) {
-               return WERR_NO_SUCH_SERVICE;
-       }
-
        return ctx->ops->set_parameter(ctx, service, param, valstr);
 }
 
@@ -265,10 +261,6 @@ WERROR smbconf_get_parameter(struct smbconf_ctx *ctx,
                return WERR_INVALID_PARAM;
        }
 
-       if (!smbconf_share_exists(ctx, service)) {
-               return WERR_NO_SUCH_SERVICE;
-       }
-
        return ctx->ops->get_parameter(ctx, mem_ctx, service, param, valstr);
 }
 
@@ -299,10 +291,6 @@ WERROR smbconf_get_global_parameter(struct smbconf_ctx *ctx,
 WERROR smbconf_delete_parameter(struct smbconf_ctx *ctx,
                                const char *service, const char *param)
 {
-       if (!smbconf_share_exists(ctx, service)) {
-               return WERR_NO_SUCH_SERVICE;
-       }
-
        return ctx->ops->delete_parameter(ctx, service, param);
 }
 
@@ -329,10 +317,6 @@ WERROR smbconf_get_includes(struct smbconf_ctx *ctx,
                            const char *service,
                            uint32_t *num_includes, char ***includes)
 {
-       if (!smbconf_share_exists(ctx, service)) {
-               return WERR_NO_SUCH_SERVICE;
-       }
-
        return ctx->ops->get_includes(ctx, mem_ctx, service, num_includes,
                                      includes);
 }
@@ -356,10 +340,6 @@ WERROR smbconf_set_includes(struct smbconf_ctx *ctx,
                            const char *service,
                            uint32_t num_includes, const char **includes)
 {
-       if (!smbconf_share_exists(ctx, service)) {
-               return WERR_NO_SUCH_SERVICE;
-       }
-
        return ctx->ops->set_includes(ctx, service, num_includes, includes);
 }
 
@@ -381,10 +361,6 @@ WERROR smbconf_set_global_includes(struct smbconf_ctx *ctx,
 
 WERROR smbconf_delete_includes(struct smbconf_ctx *ctx, const char *service)
 {
-       if (!smbconf_share_exists(ctx, service)) {
-               return WERR_NO_SUCH_SERVICE;
-       }
-
        return ctx->ops->delete_includes(ctx, service);
 }
 
index 1e3927705b215ba85bccd05522f4c70540ca9c00..44082e78a1e97ca86ac9b1f6cdefe061c66cd8f1 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) Jelmer Vernooij 2005,2008 <jelmer@samba.org>
- * Copyright (C) Stefan Metzmacher 2006 <metze@samba.org>
+ * Copyright (C) Stefan Metzmacher 2006-2009 <metze@samba.org>
  *
  * All rights reserved.
  * 
 #define real_ioctl ioctl
 #define real_recv recv
 #define real_send send
+#define real_readv readv
+#define real_writev writev
 #define real_socket socket
 #define real_close close
 #endif
 
 #define MAX_WRAPPED_INTERFACES 16
 
-#define SW_IPV6_ADDRESS 1
+#ifdef HAVE_IPV6
+/*
+ * FD00::5357:5FXX
+ */
+static const struct in6_addr *swrap_ipv6(void)
+{
+       static struct in6_addr v;
+       static int initialized;
+       int ret;
+
+       if (initialized) {
+               return &v;
+       }
+       initialized = 1;
+
+       ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
+       if (ret <= 0) {
+               abort();
+       }
+
+       return &v;
+}
+#endif
 
 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
 {
@@ -193,6 +217,7 @@ struct socket_info
        int bound;
        int bcast;
        int is_server;
+       int connected;
 
        char *path;
        char *tmp_path;
@@ -295,7 +320,8 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, sock
 
                memset(in2, 0, sizeof(*in2));
                in2->sin6_family = AF_INET6;
-               in2->sin6_addr.s6_addr[0] = SW_IPV6_ADDRESS;
+               in2->sin6_addr = *swrap_ipv6();
+               in2->sin6_addr.s6_addr[15] = iface;
                in2->sin6_port = htons(prt);
 
                *len = sizeof(*in2);
@@ -367,6 +393,7 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
        case AF_INET6: {
                const struct sockaddr_in6 *in = 
                    (const struct sockaddr_in6 *)inaddr;
+               struct in6_addr cmp;
 
                switch (si->type) {
                case SOCK_STREAM:
@@ -380,8 +407,16 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
                /* XXX no multicast/broadcast */
 
                prt = ntohs(in->sin6_port);
-               iface = SW_IPV6_ADDRESS;
-               
+
+               cmp = in->sin6_addr;
+               cmp.s6_addr[15] = 0;
+               if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
+                       iface = in->sin6_addr.s6_addr[15];
+               } else {
+                       errno = ENETUNREACH;
+                       return -1;
+               }
+
                break;
        }
 #endif
@@ -474,6 +509,7 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
        case AF_INET6: {
                const struct sockaddr_in6 *in = 
                    (const struct sockaddr_in6 *)inaddr;
+               struct in6_addr cmp;
 
                switch (si->type) {
                case SOCK_STREAM:
@@ -487,13 +523,23 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
                /* XXX no multicast/broadcast */
 
                prt = ntohs(in->sin6_port);
-               iface = SW_IPV6_ADDRESS;
-               
+
+               cmp = in->sin6_addr;
+               cmp.s6_addr[15] = 0;
+               if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
+                       iface = socket_wrapper_default_iface();
+               } else if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
+                       iface = in->sin6_addr.s6_addr[15];
+               } else {
+                       errno = EADDRNOTAVAIL;
+                       return -1;
+               }
+
                break;
        }
 #endif
        default:
-               errno = ENETUNREACH;
+               errno = EADDRNOTAVAIL;
                return -1;
        }
 
@@ -636,69 +682,93 @@ struct swrap_file_hdr {
 };
 #define SWRAP_FILE_HDR_SIZE 24
 
-struct swrap_packet {
+struct swrap_packet_frame {
+       uint32_t seconds;
+       uint32_t micro_seconds;
+       uint32_t recorded_length;
+       uint32_t full_length;
+};
+#define SWRAP_PACKET_FRAME_SIZE 16
+
+union swrap_packet_ip {
+       struct {
+               uint8_t         ver_hdrlen;
+               uint8_t         tos;
+               uint16_t        packet_length;
+               uint16_t        identification;
+               uint8_t         flags;
+               uint8_t         fragment;
+               uint8_t         ttl;
+               uint8_t         protocol;
+               uint16_t        hdr_checksum;
+               uint32_t        src_addr;
+               uint32_t        dest_addr;
+       } v4;
+#define SWRAP_PACKET_IP_V4_SIZE 20
        struct {
-               uint32_t seconds;
-               uint32_t micro_seconds;
-               uint32_t recorded_length;
-               uint32_t full_length;
-       } frame;
-#define SWRAP_PACKET__FRAME_SIZE 16
+               uint8_t         ver_prio;
+               uint8_t         flow_label_high;
+               uint16_t        flow_label_low;
+               uint16_t        payload_length;
+               uint8_t         next_header;
+               uint8_t         hop_limit;
+               uint8_t         src_addr[16];
+               uint8_t         dest_addr[16];
+       } v6;
+#define SWRAP_PACKET_IP_V6_SIZE 40
+};
+#define SWRAP_PACKET_IP_SIZE 40
 
+union swrap_packet_payload {
+       struct {
+               uint16_t        source_port;
+               uint16_t        dest_port;
+               uint32_t        seq_num;
+               uint32_t        ack_num;
+               uint8_t         hdr_length;
+               uint8_t         control;
+               uint16_t        window;
+               uint16_t        checksum;
+               uint16_t        urg;
+       } tcp;
+#define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
+       struct {
+               uint16_t        source_port;
+               uint16_t        dest_port;
+               uint16_t        length;
+               uint16_t        checksum;
+       } udp;
+#define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
        struct {
-               struct {
-                       uint8_t         ver_hdrlen;
-                       uint8_t         tos;
-                       uint16_t        packet_length;
-                       uint16_t        identification;
-                       uint8_t         flags;
-                       uint8_t         fragment;
-                       uint8_t         ttl;
-                       uint8_t         protocol;
-                       uint16_t        hdr_checksum;
-                       uint32_t        src_addr;
-                       uint32_t        dest_addr;
-               } hdr;
-#define SWRAP_PACKET__IP_HDR_SIZE 20
-
-               union {
-                       struct {
-                               uint16_t        source_port;
-                               uint16_t        dest_port;
-                               uint32_t        seq_num;
-                               uint32_t        ack_num;
-                               uint8_t         hdr_length;
-                               uint8_t         control;
-                               uint16_t        window;
-                               uint16_t        checksum;
-                               uint16_t        urg;
-                       } tcp;
-#define SWRAP_PACKET__IP_P_TCP_SIZE 20
-                       struct {
-                               uint16_t        source_port;
-                               uint16_t        dest_port;
-                               uint16_t        length;
-                               uint16_t        checksum;
-                       } udp;
-#define SWRAP_PACKET__IP_P_UDP_SIZE 8
-                       struct {
-                               uint8_t         type;
-                               uint8_t         code;
-                               uint16_t        checksum;
-                               uint32_t        unused;
-                       } icmp;
-#define SWRAP_PACKET__IP_P_ICMP_SIZE 8
-               } p;
-       } ip;
+               uint8_t         type;
+               uint8_t         code;
+               uint16_t        checksum;
+               uint32_t        unused;
+       } icmp4;
+#define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
+       struct {
+               uint8_t         type;
+               uint8_t         code;
+               uint16_t        checksum;
+               uint32_t        unused;
+       } icmp6;
+#define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
 };
-#define SWRAP_PACKET_SIZE 56
+#define SWRAP_PACKET_PAYLOAD_SIZE 20
+
+#define SWRAP_PACKET_MIN_ALLOC \
+       (SWRAP_PACKET_FRAME_SIZE + \
+        SWRAP_PACKET_IP_SIZE + \
+        SWRAP_PACKET_PAYLOAD_SIZE)
 
 static const char *socket_wrapper_pcap_file(void)
 {
        static int initialized = 0;
        static const char *s = NULL;
-       static const struct swrap_file_hdr h = { 0, };
-       static const struct swrap_packet p = { { 0, }, { { 0, }, { { 0, } } } };
+       static const struct swrap_file_hdr h;
+       static const struct swrap_packet_frame f;
+       static const union swrap_packet_ip i;
+       static const union swrap_packet_payload p;
 
        if (initialized == 1) {
                return s;
@@ -715,22 +785,31 @@ static const char *socket_wrapper_pcap_file(void)
        if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
                return NULL;
        }
-       if (sizeof(p) != SWRAP_PACKET_SIZE) {
+       if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
+               return NULL;
+       }
+       if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
                return NULL;
        }
-       if (sizeof(p.frame) != SWRAP_PACKET__FRAME_SIZE) {
+       if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
                return NULL;
        }
-       if (sizeof(p.ip.hdr) != SWRAP_PACKET__IP_HDR_SIZE) {
+       if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
                return NULL;
        }
-       if (sizeof(p.ip.p.tcp) != SWRAP_PACKET__IP_P_TCP_SIZE) {
+       if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
                return NULL;
        }
-       if (sizeof(p.ip.p.udp) != SWRAP_PACKET__IP_P_UDP_SIZE) {
+       if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
                return NULL;
        }
-       if (sizeof(p.ip.p.icmp) != SWRAP_PACKET__IP_P_ICMP_SIZE) {
+       if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
+               return NULL;
+       }
+       if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
+               return NULL;
+       }
+       if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
                return NULL;
        }
 
@@ -744,41 +823,72 @@ static const char *socket_wrapper_pcap_file(void)
        return s;
 }
 
-static struct swrap_packet *swrap_packet_init(struct timeval *tval,
-                                             const struct sockaddr_in *src_addr,
-                                             const struct sockaddr_in *dest_addr,
-                                             int socket_type,
-                                             const unsigned char *payload,
-                                             size_t payload_len,
-                                             unsigned long tcp_seqno,
-                                             unsigned long tcp_ack,
-                                             unsigned char tcp_ctl,
-                                             int unreachable,
-                                             size_t *_packet_len)
+static uint8_t *swrap_packet_init(struct timeval *tval,
+                                 const struct sockaddr *src,
+                                 const struct sockaddr *dest,
+                                 int socket_type,
+                                 const uint8_t *payload,
+                                 size_t payload_len,
+                                 unsigned long tcp_seqno,
+                                 unsigned long tcp_ack,
+                                 unsigned char tcp_ctl,
+                                 int unreachable,
+                                 size_t *_packet_len)
 {
-       struct swrap_packet *ret;
-       struct swrap_packet *packet;
+       uint8_t *base;
+       uint8_t *buf;
+       struct swrap_packet_frame *frame;
+       union swrap_packet_ip *ip;
+       union swrap_packet_payload *pay;
        size_t packet_len;
        size_t alloc_len;
-       size_t nonwire_len = sizeof(packet->frame);
+       size_t nonwire_len = sizeof(*frame);
        size_t wire_hdr_len = 0;
        size_t wire_len = 0;
+       size_t ip_hdr_len = 0;
        size_t icmp_hdr_len = 0;
        size_t icmp_truncate_len = 0;
-       unsigned char protocol = 0, icmp_protocol = 0;
-       unsigned short src_port = src_addr->sin_port;
-       unsigned short dest_port = dest_addr->sin_port;
+       uint8_t protocol = 0, icmp_protocol = 0;
+       const struct sockaddr_in *src_in = NULL;
+       const struct sockaddr_in *dest_in = NULL;
+#ifdef HAVE_IPV6
+       const struct sockaddr_in6 *src_in6 = NULL;
+       const struct sockaddr_in6 *dest_in6 = NULL;
+#endif
+       uint16_t src_port;
+       uint16_t dest_port;
+
+       switch (src->sa_family) {
+       case AF_INET:
+               src_in = (const struct sockaddr_in *)src;
+               dest_in = (const struct sockaddr_in *)dest;
+               src_port = src_in->sin_port;
+               dest_port = dest_in->sin_port;
+               ip_hdr_len = sizeof(ip->v4);
+               break;
+#ifdef HAVE_IPV6
+       case AF_INET6:
+               src_in6 = (const struct sockaddr_in6 *)src;
+               dest_in6 = (const struct sockaddr_in6 *)dest;
+               src_port = src_in6->sin6_port;
+               dest_port = dest_in6->sin6_port;
+               ip_hdr_len = sizeof(ip->v6);
+               break;
+#endif
+       default:
+               return NULL;
+       }
 
        switch (socket_type) {
        case SOCK_STREAM:
                protocol = 0x06; /* TCP */
-               wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.tcp);
+               wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
                wire_len = wire_hdr_len + payload_len;
                break;
 
        case SOCK_DGRAM:
                protocol = 0x11; /* UDP */
-               wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.udp);
+               wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
                wire_len = wire_hdr_len + payload_len;
                break;
 
@@ -788,98 +898,160 @@ static struct swrap_packet *swrap_packet_init(struct timeval *tval,
 
        if (unreachable) {
                icmp_protocol = protocol;
-               protocol = 0x01; /* ICMP */
+               switch (src->sa_family) {
+               case AF_INET:
+                       protocol = 0x01; /* ICMPv4 */
+                       icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
+                       break;
+#ifdef HAVE_IPV6
+               case AF_INET6:
+                       protocol = 0x3A; /* ICMPv6 */
+                       icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
+                       break;
+#endif
+               }
                if (wire_len > 64 ) {
                        icmp_truncate_len = wire_len - 64;
                }
-               icmp_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.icmp);
                wire_hdr_len += icmp_hdr_len;
                wire_len += icmp_hdr_len;
        }
 
        packet_len = nonwire_len + wire_len;
        alloc_len = packet_len;
-       if (alloc_len < sizeof(struct swrap_packet)) {
-               alloc_len = sizeof(struct swrap_packet);
-       }
-       ret = (struct swrap_packet *)malloc(alloc_len);
-       if (!ret) return NULL;
-
-       packet = ret;
-
-       packet->frame.seconds           = tval->tv_sec;
-       packet->frame.micro_seconds     = tval->tv_usec;
-       packet->frame.recorded_length   = wire_len - icmp_truncate_len;
-       packet->frame.full_length       = wire_len - icmp_truncate_len;
-
-       packet->ip.hdr.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
-       packet->ip.hdr.tos              = 0x00;
-       packet->ip.hdr.packet_length    = htons(wire_len - icmp_truncate_len);
-       packet->ip.hdr.identification   = htons(0xFFFF);
-       packet->ip.hdr.flags            = 0x40; /* BIT 1 set - means don't fraqment */
-       packet->ip.hdr.fragment         = htons(0x0000);
-       packet->ip.hdr.ttl              = 0xFF;
-       packet->ip.hdr.protocol         = protocol;
-       packet->ip.hdr.hdr_checksum     = htons(0x0000);
-       packet->ip.hdr.src_addr         = src_addr->sin_addr.s_addr;
-       packet->ip.hdr.dest_addr        = dest_addr->sin_addr.s_addr;
+       if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
+               alloc_len = SWRAP_PACKET_MIN_ALLOC;
+       }
+
+       base = (uint8_t *)malloc(alloc_len);
+       if (!base) return NULL;
+
+       buf = base;
+
+       frame = (struct swrap_packet_frame *)buf;
+       frame->seconds          = tval->tv_sec;
+       frame->micro_seconds    = tval->tv_usec;
+       frame->recorded_length  = wire_len - icmp_truncate_len;
+       frame->full_length      = wire_len - icmp_truncate_len;
+       buf += SWRAP_PACKET_FRAME_SIZE;
+
+       ip = (union swrap_packet_ip *)buf;
+       switch (src->sa_family) {
+       case AF_INET:
+               ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
+               ip->v4.tos              = 0x00;
+               ip->v4.packet_length    = htons(wire_len - icmp_truncate_len);
+               ip->v4.identification   = htons(0xFFFF);
+               ip->v4.flags            = 0x40; /* BIT 1 set - means don't fraqment */
+               ip->v4.fragment         = htons(0x0000);
+               ip->v4.ttl              = 0xFF;
+               ip->v4.protocol         = protocol;
+               ip->v4.hdr_checksum     = htons(0x0000);
+               ip->v4.src_addr         = src_in->sin_addr.s_addr;
+               ip->v4.dest_addr        = dest_in->sin_addr.s_addr;
+               buf += SWRAP_PACKET_IP_V4_SIZE;
+               break;
+#ifdef HAVE_IPV6
+       case AF_INET6:
+               ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
+               ip->v6.flow_label_high  = 0x00;
+               ip->v6.flow_label_low   = 0x0000;
+               ip->v6.payload_length   = htons(wire_len - icmp_truncate_len);//TODO
+               ip->v6.next_header      = protocol;
+               memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
+               memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
+               buf += SWRAP_PACKET_IP_V6_SIZE;
+               break;
+#endif
+       }
 
        if (unreachable) {
-               packet->ip.p.icmp.type          = 0x03; /* destination unreachable */
-               packet->ip.p.icmp.code          = 0x01; /* host unreachable */
-               packet->ip.p.icmp.checksum      = htons(0x0000);
-               packet->ip.p.icmp.unused        = htonl(0x00000000);
-
-               /* set the ip header in the ICMP payload */
-               packet = (struct swrap_packet *)(((unsigned char *)ret) + icmp_hdr_len);
-               packet->ip.hdr.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
-               packet->ip.hdr.tos              = 0x00;
-               packet->ip.hdr.packet_length    = htons(wire_len - icmp_hdr_len);
-               packet->ip.hdr.identification   = htons(0xFFFF);
-               packet->ip.hdr.flags            = 0x40; /* BIT 1 set - means don't fraqment */
-               packet->ip.hdr.fragment         = htons(0x0000);
-               packet->ip.hdr.ttl              = 0xFF;
-               packet->ip.hdr.protocol         = icmp_protocol;
-               packet->ip.hdr.hdr_checksum     = htons(0x0000);
-               packet->ip.hdr.src_addr         = dest_addr->sin_addr.s_addr;
-               packet->ip.hdr.dest_addr        = src_addr->sin_addr.s_addr;
-
-               src_port = dest_addr->sin_port;
-               dest_port = src_addr->sin_port;
+               pay = (union swrap_packet_payload *)buf;
+               switch (src->sa_family) {
+               case AF_INET:
+                       pay->icmp4.type         = 0x03; /* destination unreachable */
+                       pay->icmp4.code         = 0x01; /* host unreachable */
+                       pay->icmp4.checksum     = htons(0x0000);
+                       pay->icmp4.unused       = htonl(0x00000000);
+                       buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
+
+                       /* set the ip header in the ICMP payload */
+                       ip = (union swrap_packet_ip *)buf;
+                       ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
+                       ip->v4.tos              = 0x00;
+                       ip->v4.packet_length    = htons(wire_len - icmp_hdr_len);
+                       ip->v4.identification   = htons(0xFFFF);
+                       ip->v4.flags            = 0x40; /* BIT 1 set - means don't fraqment */
+                       ip->v4.fragment         = htons(0x0000);
+                       ip->v4.ttl              = 0xFF;
+                       ip->v4.protocol         = icmp_protocol;
+                       ip->v4.hdr_checksum     = htons(0x0000);
+                       ip->v4.src_addr         = dest_in->sin_addr.s_addr;
+                       ip->v4.dest_addr        = src_in->sin_addr.s_addr;
+                       buf += SWRAP_PACKET_IP_V4_SIZE;
+
+                       src_port = dest_in->sin_port;
+                       dest_port = src_in->sin_port;
+                       break;
+#ifdef HAVE_IPV6
+               case AF_INET6:
+                       pay->icmp6.type         = 0x01; /* destination unreachable */
+                       pay->icmp6.code         = 0x03; /* address unreachable */
+                       pay->icmp6.checksum     = htons(0x0000);
+                       pay->icmp6.unused       = htonl(0x00000000);
+                       buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
+
+                       /* set the ip header in the ICMP payload */
+                       ip = (union swrap_packet_ip *)buf;
+                       ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
+                       ip->v6.flow_label_high  = 0x00;
+                       ip->v6.flow_label_low   = 0x0000;
+                       ip->v6.payload_length   = htons(wire_len - icmp_truncate_len);//TODO
+                       ip->v6.next_header      = protocol;
+                       memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
+                       memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
+                       buf += SWRAP_PACKET_IP_V6_SIZE;
+
+                       src_port = dest_in6->sin6_port;
+                       dest_port = src_in6->sin6_port;
+                       break;
+#endif
+               }
        }
 
+       pay = (union swrap_packet_payload *)buf;
+
        switch (socket_type) {
        case SOCK_STREAM:
-               packet->ip.p.tcp.source_port    = src_port;
-               packet->ip.p.tcp.dest_port      = dest_port;
-               packet->ip.p.tcp.seq_num        = htonl(tcp_seqno);
-               packet->ip.p.tcp.ack_num        = htonl(tcp_ack);
-               packet->ip.p.tcp.hdr_length     = 0x50; /* 5 * 32 bit words */
-               packet->ip.p.tcp.control        = tcp_ctl;
-               packet->ip.p.tcp.window         = htons(0x7FFF);
-               packet->ip.p.tcp.checksum       = htons(0x0000);
-               packet->ip.p.tcp.urg            = htons(0x0000);
+               pay->tcp.source_port    = src_port;
+               pay->tcp.dest_port      = dest_port;
+               pay->tcp.seq_num        = htonl(tcp_seqno);
+               pay->tcp.ack_num        = htonl(tcp_ack);
+               pay->tcp.hdr_length     = 0x50; /* 5 * 32 bit words */
+               pay->tcp.control        = tcp_ctl;
+               pay->tcp.window         = htons(0x7FFF);
+               pay->tcp.checksum       = htons(0x0000);
+               pay->tcp.urg            = htons(0x0000);
+               buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
 
                break;
 
        case SOCK_DGRAM:
-               packet->ip.p.udp.source_port    = src_addr->sin_port;
-               packet->ip.p.udp.dest_port      = dest_addr->sin_port;
-               packet->ip.p.udp.length         = htons(8 + payload_len);
-               packet->ip.p.udp.checksum       = htons(0x0000);
+               pay->udp.source_port    = src_port;
+               pay->udp.dest_port      = dest_port;
+               pay->udp.length         = htons(8 + payload_len);
+               pay->udp.checksum       = htons(0x0000);
+               buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
 
                break;
        }
 
        if (payload && payload_len > 0) {
-               unsigned char *p = (unsigned char *)ret;
-               p += nonwire_len;
-               p += wire_hdr_len;
-               memcpy(p, payload, payload_len);
+               memcpy(buf, payload, payload_len);
        }
 
        *_packet_len = packet_len - icmp_truncate_len;
-       return ret;
+       return base;
 }
 
 static int swrap_get_pcap_fd(const char *fname)
@@ -911,14 +1083,14 @@ static int swrap_get_pcap_fd(const char *fname)
        return fd;
 }
 
-static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
-                                                                 const struct sockaddr *addr,
-                                                                 enum swrap_packet_type type,
-                                                                 const void *buf, size_t len,
-                                                                 size_t *packet_len)
+static uint8_t *swrap_marshall_packet(struct socket_info *si,
+                                     const struct sockaddr *addr,
+                                     enum swrap_packet_type type,
+                                     const void *buf, size_t len,
+                                     size_t *packet_len)
 {
-       const struct sockaddr_in *src_addr;
-       const struct sockaddr_in *dest_addr;
+       const struct sockaddr *src_addr;
+       const struct sockaddr *dest_addr;
        unsigned long tcp_seqno = 0;
        unsigned long tcp_ack = 0;
        unsigned char tcp_ctl = 0;
@@ -929,6 +1101,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
        switch (si->family) {
        case AF_INET:
                break;
+       case AF_INET6:
+               break;
        default:
                return NULL;
        }
@@ -937,8 +1111,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
        case SWRAP_CONNECT_SEND:
                if (si->type != SOCK_STREAM) return NULL;
 
-               src_addr = (const struct sockaddr_in *)si->myname;
-               dest_addr = (const struct sockaddr_in *)addr;
+               src_addr = si->myname;
+               dest_addr = addr;
 
                tcp_seqno = si->io.pck_snd;
                tcp_ack = si->io.pck_rcv;
@@ -951,8 +1125,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
        case SWRAP_CONNECT_RECV:
                if (si->type != SOCK_STREAM) return NULL;
 
-               dest_addr = (const struct sockaddr_in *)si->myname;
-               src_addr = (const struct sockaddr_in *)addr;
+               dest_addr = si->myname;
+               src_addr = addr;
 
                tcp_seqno = si->io.pck_rcv;
                tcp_ack = si->io.pck_snd;
@@ -965,8 +1139,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
        case SWRAP_CONNECT_UNREACH:
                if (si->type != SOCK_STREAM) return NULL;
 
-               dest_addr = (const struct sockaddr_in *)si->myname;
-               src_addr = (const struct sockaddr_in *)addr;
+               dest_addr = si->myname;
+               src_addr = addr;
 
                /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
                tcp_seqno = si->io.pck_snd - 1;
@@ -979,8 +1153,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
        case SWRAP_CONNECT_ACK:
                if (si->type != SOCK_STREAM) return NULL;
 
-               src_addr = (const struct sockaddr_in *)si->myname;
-               dest_addr = (const struct sockaddr_in *)addr;
+               src_addr = si->myname;
+               dest_addr = addr;
 
                tcp_seqno = si->io.pck_snd;
                tcp_ack = si->io.pck_rcv;
@@ -991,8 +1165,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
        case SWRAP_ACCEPT_SEND:
                if (si->type != SOCK_STREAM) return NULL;
 
-               dest_addr = (const struct sockaddr_in *)si->myname;
-               src_addr = (const struct sockaddr_in *)addr;
+               dest_addr = si->myname;
+               src_addr = addr;
 
                tcp_seqno = si->io.pck_rcv;
                tcp_ack = si->io.pck_snd;
@@ -1005,8 +1179,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
        case SWRAP_ACCEPT_RECV:
                if (si->type != SOCK_STREAM) return NULL;
 
-               src_addr = (const struct sockaddr_in *)si->myname;
-               dest_addr = (const struct sockaddr_in *)addr;
+               src_addr = si->myname;
+               dest_addr = addr;
 
                tcp_seqno = si->io.pck_snd;
                tcp_ack = si->io.pck_rcv;
@@ -1019,8 +1193,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
        case SWRAP_ACCEPT_ACK:
                if (si->type != SOCK_STREAM) return NULL;
 
-               dest_addr = (const struct sockaddr_in *)si->myname;
-               src_addr = (const struct sockaddr_in *)addr;
+               dest_addr = si->myname;
+               src_addr = addr;
 
                tcp_seqno = si->io.pck_rcv;
                tcp_ack = si->io.pck_snd;
@@ -1029,8 +1203,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
                break;
 
        case SWRAP_SEND:
-               src_addr = (const struct sockaddr_in *)si->myname;
-               dest_addr = (const struct sockaddr_in *)si->peername;
+               src_addr = si->myname;
+               dest_addr = si->peername;
 
                tcp_seqno = si->io.pck_snd;
                tcp_ack = si->io.pck_rcv;
@@ -1041,8 +1215,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
                break;
 
        case SWRAP_SEND_RST:
-               dest_addr = (const struct sockaddr_in *)si->myname;
-               src_addr = (const struct sockaddr_in *)si->peername;
+               dest_addr = si->myname;
+               src_addr = si->peername;
 
                if (si->type == SOCK_DGRAM) {
                        return swrap_marshall_packet(si, si->peername,
@@ -1057,8 +1231,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
                break;
 
        case SWRAP_PENDING_RST:
-               dest_addr = (const struct sockaddr_in *)si->myname;
-               src_addr = (const struct sockaddr_in *)si->peername;
+               dest_addr = si->myname;
+               src_addr = si->peername;
 
                if (si->type == SOCK_DGRAM) {
                        return NULL;
@@ -1071,8 +1245,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
                break;
 
        case SWRAP_RECV:
-               dest_addr = (const struct sockaddr_in *)si->myname;
-               src_addr = (const struct sockaddr_in *)si->peername;
+               dest_addr = si->myname;
+               src_addr = si->peername;
 
                tcp_seqno = si->io.pck_rcv;
                tcp_ack = si->io.pck_snd;
@@ -1083,8 +1257,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
                break;
 
        case SWRAP_RECV_RST:
-               dest_addr = (const struct sockaddr_in *)si->myname;
-               src_addr = (const struct sockaddr_in *)si->peername;
+               dest_addr = si->myname;
+               src_addr = si->peername;
 
                if (si->type == SOCK_DGRAM) {
                        return NULL;
@@ -1097,24 +1271,24 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
                break;
 
        case SWRAP_SENDTO:
-               src_addr = (const struct sockaddr_in *)si->myname;
-               dest_addr = (const struct sockaddr_in *)addr;
+               src_addr = si->myname;
+               dest_addr = addr;
 
                si->io.pck_snd += len;
 
                break;
 
        case SWRAP_SENDTO_UNREACH:
-               dest_addr = (const struct sockaddr_in *)si->myname;
-               src_addr = (const struct sockaddr_in *)addr;
+               dest_addr = si->myname;
+               src_addr = addr;
 
                unreachable = 1;
 
                break;
 
        case SWRAP_RECVFROM:
-               dest_addr = (const struct sockaddr_in *)si->myname;
-               src_addr = (const struct sockaddr_in *)addr;
+               dest_addr = si->myname;
+               src_addr = addr;
 
                si->io.pck_rcv += len;
 
@@ -1123,8 +1297,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
        case SWRAP_CLOSE_SEND:
                if (si->type != SOCK_STREAM) return NULL;
 
-               src_addr = (const struct sockaddr_in *)si->myname;
-               dest_addr = (const struct sockaddr_in *)si->peername;
+               src_addr = si->myname;
+               dest_addr = si->peername;
 
                tcp_seqno = si->io.pck_snd;
                tcp_ack = si->io.pck_rcv;
@@ -1137,8 +1311,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
        case SWRAP_CLOSE_RECV:
                if (si->type != SOCK_STREAM) return NULL;
 
-               dest_addr = (const struct sockaddr_in *)si->myname;
-               src_addr = (const struct sockaddr_in *)si->peername;
+               dest_addr = si->myname;
+               src_addr = si->peername;
 
                tcp_seqno = si->io.pck_rcv;
                tcp_ack = si->io.pck_snd;
@@ -1151,8 +1325,8 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
        case SWRAP_CLOSE_ACK:
                if (si->type != SOCK_STREAM) return NULL;
 
-               src_addr = (const struct sockaddr_in *)si->myname;
-               dest_addr = (const struct sockaddr_in *)si->peername;
+               src_addr = si->myname;
+               dest_addr = si->peername;
 
                tcp_seqno = si->io.pck_snd;
                tcp_ack = si->io.pck_rcv;
@@ -1166,18 +1340,18 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si,
        swrapGetTimeOfDay(&tv);
 
        return swrap_packet_init(&tv, src_addr, dest_addr, si->type,
-                                  (const unsigned char *)buf, len,
-                                  tcp_seqno, tcp_ack, tcp_ctl, unreachable,
-                                  packet_len);
+                                (const uint8_t *)buf, len,
+                                tcp_seqno, tcp_ack, tcp_ctl, unreachable,
+                                packet_len);
 }
 
-static void swrap_dump_packet(struct socket_info *si, 
-                                                         const struct sockaddr *addr,
-                                                         enum swrap_packet_type type,
-                                                         const void *buf, size_t len)
+static void swrap_dump_packet(struct socket_info *si,
+                             const struct sockaddr *addr,
+                             enum swrap_packet_type type,
+                             const void *buf, size_t len)
 {
        const char *file_name;
-       struct swrap_packet *packet;
+       uint8_t *packet;
        size_t packet_len = 0;
        int fd;
 
@@ -1329,6 +1503,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
        child_si->protocol = parent_si->protocol;
        child_si->bound = 1;
        child_si->is_server = 1;
+       child_si->connected = 1;
 
        child_si->peername_len = len;
        child_si->peername = sockaddr_dup(my_addr, len);
@@ -1376,8 +1551,10 @@ static int autobind_start;
 /* using sendto() or connect() on an unbound socket would give the
    recipient no way to reply, as unlike UDP and TCP, a unix domain
    socket can't auto-assign emphemeral port numbers, so we need to
-   assign it here */
-static int swrap_auto_bind(struct socket_info *si)
+   assign it here.
+   Note: this might change the family from ipv6 to ipv4
+*/
+static int swrap_auto_bind(struct socket_info *si, int family)
 {
        struct sockaddr_un un_addr;
        int i;
@@ -1395,7 +1572,7 @@ static int swrap_auto_bind(struct socket_info *si)
 
        un_addr.sun_family = AF_UNIX;
 
-       switch (si->family) {
+       switch (family) {
        case AF_INET: {
                struct sockaddr_in in;
 
@@ -1424,6 +1601,11 @@ static int swrap_auto_bind(struct socket_info *si)
        case AF_INET6: {
                struct sockaddr_in6 in6;
 
+               if (si->family != family) {
+                       errno = ENETUNREACH;
+                       return -1;
+               }
+
                switch (si->type) {
                case SOCK_STREAM:
                        type = SOCKET_TYPE_CHAR_TCP_V6;
@@ -1432,13 +1614,14 @@ static int swrap_auto_bind(struct socket_info *si)
                        type = SOCKET_TYPE_CHAR_UDP_V6;
                        break;
                default:
-                   errno = ESOCKTNOSUPPORT;
-                   return -1;
+                       errno = ESOCKTNOSUPPORT;
+                       return -1;
                }
 
                memset(&in6, 0, sizeof(in6));
                in6.sin6_family = AF_INET6;
-               in6.sin6_addr.s6_addr[0] = SW_IPV6_ADDRESS;
+               in6.sin6_addr = *swrap_ipv6();
+               in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
                si->myname_len = sizeof(in6);
                si->myname = sockaddr_dup(&in6, si->myname_len);
                break;
@@ -1473,6 +1656,7 @@ static int swrap_auto_bind(struct socket_info *si)
                return -1;
        }
 
+       si->family = family;
        set_port(si->family, port, si->myname);
 
        return 0;
@@ -1490,7 +1674,7 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad
        }
 
        if (si->bound == 0) {
-               ret = swrap_auto_bind(si);
+               ret = swrap_auto_bind(si, serv_addr->sa_family);
                if (ret == -1) return -1;
        }
 
@@ -1515,6 +1699,7 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad
        if (ret == 0) {
                si->peername_len = addrlen;
                si->peername = sockaddr_dup(serv_addr, addrlen);
+               si->connected = 1;
 
                swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
                swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
@@ -1644,11 +1829,18 @@ _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct
        socklen_t un_addrlen = sizeof(un_addr);
        int ret;
        struct socket_info *si = find_socket_info(s);
+       struct sockaddr_storage ss;
+       socklen_t ss_len = sizeof(ss);
 
        if (!si) {
                return real_recvfrom(s, buf, len, flags, from, fromlen);
        }
 
+       if (!from) {
+               from = (struct sockaddr *)&ss;
+               fromlen = &ss_len;
+       }
+
        len = MIN(len, 1500);
 
        /* irix 6.4 forgets to null terminate the sun_path string :-( */
@@ -1679,6 +1871,16 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con
                return real_sendto(s, buf, len, flags, to, tolen);
        }
 
+       if (si->connected) {
+               if (to) {
+                       errno = EISCONN;
+                       return -1;
+               }
+
+               to = si->peername;
+               tolen = si->peername_len;
+       }
+
        len = MIN(len, 1500);
 
        switch (si->type) {
@@ -1687,7 +1889,7 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con
                break;
        case SOCK_DGRAM:
                if (si->bound == 0) {
-                       ret = swrap_auto_bind(si);
+                       ret = swrap_auto_bind(si, si->family);
                        if (ret == -1) return -1;
                }
                
@@ -1781,7 +1983,7 @@ _PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
                swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
        } else if (ret == 0) { /* END OF FILE */
                swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
-       } else {
+       } else if (ret > 0) {
                swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
        }
 
@@ -1812,6 +2014,128 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
        return ret;
 }
 
+int swrap_readv(int s, const struct iovec *vector, size_t count)
+{
+       int ret;
+       struct socket_info *si = find_socket_info(s);
+       struct iovec v;
+
+       if (!si) {
+               return real_readv(s, vector, count);
+       }
+
+       /* we read 1500 bytes as maximum */
+       if (count > 0) {
+               size_t i, len = 0;
+
+               for (i=0; i < count; i++) {
+                       size_t nlen;
+                       nlen = len + vector[i].iov_len;
+                       if (nlen > 1500) {
+                               break;
+                       }
+               }
+               count = i;
+               if (count == 0) {
+                       v = vector[0];
+                       v.iov_len = MIN(v.iov_len, 1500);
+                       vector = &v;
+                       count = 1;
+               }
+       }
+
+       ret = real_readv(s, vector, count);
+       if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
+               swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
+       } else if (ret == 0) { /* END OF FILE */
+               swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
+       } else if (ret > 0) {
+               uint8_t *buf;
+               off_t ofs = 0;
+               size_t i;
+
+               /* we capture it as one single packet */
+               buf = (uint8_t *)malloc(ret);
+               if (!buf) {
+                       /* we just not capture the packet */
+                       errno = 0;
+                       return ret;
+               }
+
+               for (i=0; i < count; i++) {
+                       memcpy(buf + ofs,
+                              vector[i].iov_base,
+                              vector[i].iov_len);
+                       ofs += vector[i].iov_len;
+               }
+
+               swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
+               free(buf);
+       }
+
+       return ret;
+}
+
+int swrap_writev(int s, const struct iovec *vector, size_t count)
+{
+       int ret;
+       struct socket_info *si = find_socket_info(s);
+       struct iovec v;
+
+       if (!si) {
+               return real_writev(s, vector, count);
+       }
+
+       /* we write 1500 bytes as maximum */
+       if (count > 0) {
+               size_t i, len = 0;
+
+               for (i=0; i < count; i++) {
+                       size_t nlen;
+                       nlen = len + vector[i].iov_len;
+                       if (nlen > 1500) {
+                               break;
+                       }
+               }
+               count = i;
+               if (count == 0) {
+                       v = vector[0];
+                       v.iov_len = MIN(v.iov_len, 1500);
+                       vector = &v;
+                       count = 1;
+               }
+       }
+
+       ret = real_writev(s, vector, count);
+       if (ret == -1) {
+               swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
+       } else {
+               uint8_t *buf;
+               off_t ofs = 0;
+               size_t i;
+
+               /* we capture it as one single packet */
+               buf = (uint8_t *)malloc(ret);
+               if (!buf) {
+                       /* we just not capture the packet */
+                       errno = 0;
+                       return ret;
+               }
+
+               for (i=0; i < count; i++) {
+                       memcpy(buf + ofs,
+                              vector[i].iov_base,
+                              vector[i].iov_len);
+                       ofs += vector[i].iov_len;
+               }
+
+               swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
+               free(buf);
+       }
+
+       return ret;
+}
+
 _PUBLIC_ int swrap_close(int fd)
 {
        struct socket_info *si = find_socket_info(fd);
index cc8b93760864d69db27ec7f02f2303283b721c94..b2d44769ff93bdf98a488b12dfd44793d9bdbc61 100644 (file)
@@ -52,6 +52,8 @@ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct
 int swrap_ioctl(int s, int req, void *ptr);
 ssize_t swrap_recv(int s, void *buf, size_t len, int flags);
 ssize_t swrap_send(int s, const void *buf, size_t len, int flags);
+int swrap_readv(int s, const struct iovec *vector, size_t count);
+int swrap_writev(int s, const struct iovec *vector, size_t count);
 int swrap_close(int);
 
 #ifdef SOCKET_WRAPPER_REPLACE
@@ -121,6 +123,16 @@ int swrap_close(int);
 #endif
 #define send(s,buf,len,flags)          swrap_send(s,buf,len,flags)
 
+#ifdef readv
+#undef readv
+#endif
+#define readv(s, vector, count)                swrap_readv(s,vector, count)
+
+#ifdef writev
+#undef writev
+#endif
+#define writev(s, vector, count)       swrap_writev(s,vector, count)
+
 #ifdef socket
 #undef socket
 #endif
index d2538f92221cf7a5452c3970c7174fbcf52b276c..00e8242d4ef073d326a46c211ce9210a06cafb6a 100644 (file)
@@ -1,5 +1,5 @@
 AC_PREREQ(2.50)
-AC_INIT(talloc, 1.2.0)
+AC_INIT(talloc, 1.3.0)
 AC_CONFIG_SRCDIR([talloc.c])
 AC_SUBST(datarootdir)
 AC_CONFIG_HEADER(config.h)
index 1f7e52439f81619ae6f6cb78fdb09f140f878ecd..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;
@@ -806,6 +822,41 @@ void *talloc_check_name(const void *ptr, const char *name)
        return NULL;
 }
 
+static void talloc_abort_type_missmatch(const char *location,
+                                       const char *name,
+                                       const char *expected)
+{
+       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)
+{
+       const char *pname;
+
+       if (unlikely(ptr == NULL)) {
+               talloc_abort_type_missmatch(location, NULL, name);
+               return NULL;
+       }
+
+       pname = talloc_get_name(ptr);
+       if (likely(pname == name || strcmp(pname, name) == 0)) {
+               return discard_const_p(void, ptr);
+       }
+
+       talloc_abort_type_missmatch(location, pname, name);
+       return NULL;
+}
 
 /*
   this is for compatibility with older versions of talloc
index 5431971655ed7093a2e9d2db3c3239da69c18177..5c8d5c5fe2c05ae19543d889df66dd61685a4080 100644 (file)
@@ -94,6 +94,7 @@ typedef void TALLOC_CTX;
 #define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)
 #define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__)
 #define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count)
+#define talloc_array_length(ctx) ((ctx) ? talloc_get_size(ctx)/sizeof(*ctx) : 0)
 
 #define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type)
 #define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__)
@@ -102,6 +103,7 @@ typedef void TALLOC_CTX;
 
 #define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
 #define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
+#define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__)
 
 #define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type)
 
@@ -114,6 +116,8 @@ typedef void TALLOC_CTX;
 #define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a))
 #endif
 
+#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
+
 /* The following definitions come from talloc.c  */
 void *_talloc(const void *context, size_t size);
 void *talloc_pool(const void *context, size_t size);
@@ -129,6 +133,7 @@ void *talloc_named(const void *context, size_t size,
 void *talloc_named_const(const void *context, size_t size, const char *name);
 const char *talloc_get_name(const void *ptr);
 void *talloc_check_name(const void *ptr, const char *name);
+void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location);
 void *talloc_parent(const void *ptr);
 const char *talloc_parent_name(const void *ptr);
 void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
@@ -180,4 +185,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..171a4088bac2c011d75892b574106a895cdc6a48 100644 (file)
@@ -1,5 +1,5 @@
 AC_PREREQ(2.50)
-AC_INIT(tevent, 0.9.3)
+AC_INIT(tevent, 0.9.5)
 AC_CONFIG_SRCDIR([tevent.c])
 AC_CONFIG_HEADER(config.h)
 
index c316823a715c42928d95288591b372b6b72ecf63..20730b17d646efd78fb5057ae45c14e6aed853f3 100644 (file)
@@ -26,7 +26,8 @@ AC_SUBST(TEVENT_LIBS)
 
 TEVENT_CFLAGS="-I$teventdir"
 
-TEVENT_OBJ="tevent.o tevent_fd.o tevent_timed.o tevent_signal.o tevent_debug.o tevent_util.o"
+TEVENT_OBJ="tevent.o tevent_debug.o tevent_util.o"
+TEVENT_OBJ="$TEVENT_OBJ tevent_fd.o tevent_timed.o tevent_immediate.o tevent_signal.o"
 TEVENT_OBJ="$TEVENT_OBJ tevent_req.o tevent_wakeup.o tevent_queue.o"
 TEVENT_OBJ="$TEVENT_OBJ tevent_standard.o tevent_select.o"
 
index fc8252960ae2d8c9b0efde71e1401e314246649f..0c02e46f3ca16e6478fe820ae459d5272e4dfcbc 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"
@@ -142,6 +143,7 @@ int tevent_common_context_destructor(struct tevent_context *ev)
 {
        struct tevent_fd *fd, *fn;
        struct tevent_timer *te, *tn;
+       struct tevent_immediate *ie, *in;
        struct tevent_signal *se, *sn;
 
        if (ev->pipe_fde) {
@@ -161,6 +163,13 @@ int tevent_common_context_destructor(struct tevent_context *ev)
                DLIST_REMOVE(ev->timer_events, te);
        }
 
+       for (ie = ev->immediate_events; ie; ie = in) {
+               in = ie->next;
+               ie->event_ctx = NULL;
+               ie->cancel_fn = NULL;
+               DLIST_REMOVE(ev->immediate_events, ie);
+       }
+
        for (se = ev->signal_events; se; se = sn) {
                sn = se->next;
                se->event_ctx = NULL;
@@ -305,6 +314,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
@@ -321,6 +357,47 @@ struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
                                  handler_name, location);
 }
 
+/*
+  allocate an immediate event
+  return NULL on failure (memory allocation error)
+*/
+struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx,
+                                                 const char *location)
+{
+       struct tevent_immediate *im;
+
+       im = talloc(mem_ctx, struct tevent_immediate);
+       if (im == NULL) return NULL;
+
+       im->prev                = NULL;
+       im->next                = NULL;
+       im->event_ctx           = NULL;
+       im->create_location     = location;
+       im->handler             = NULL;
+       im->private_data        = NULL;
+       im->handler_name        = NULL;
+       im->schedule_location   = NULL;
+       im->cancel_fn           = NULL;
+       im->additional_data     = NULL;
+
+       return im;
+}
+
+/*
+  schedule an immediate event
+  return NULL on failure
+*/
+void _tevent_schedule_immediate(struct tevent_immediate *im,
+                               struct tevent_context *ev,
+                               tevent_immediate_handler_t handler,
+                               void *private_data,
+                               const char *handler_name,
+                               const char *location)
+{
+       ev->ops->schedule_immediate(im, ev, handler, private_data,
+                                   handler_name, location);
+}
+
 /*
   add a signal event
 
@@ -341,18 +418,192 @@ 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)
+{
+       if (ev->nesting.hook_fn && 
+           (ev->nesting.hook_fn != hook ||
+            ev->nesting.hook_private != private_data)) {
+               /* the way the nesting hook code is currently written
+                  we cannot support two different nesting hooks at the
+                  same time. */
+               tevent_abort(ev, "tevent: Violation of nesting hook rules\n");
+       }
+       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)
+{
+       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.level > 0) {
+               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 > 0) {
+               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.level > 0) {
+               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 > 0) {
+               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_common_loop_wait(struct tevent_context *ev,
+                           const char *location)
 {
-       return ev->ops->loop_once(ev);
+       /*
+        * loop as long as we have events pending
+        */
+       while (ev->fd_events ||
+              ev->timer_events ||
+              ev->immediate_events ||
+              ev->signal_events) {
+               int ret;
+               ret = _tevent_loop_once(ev, location);
+               if (ret != 0) {
+                       tevent_debug(ev, TEVENT_DEBUG_FATAL,
+                                    "_tevent_loop_once() failed: %d - %s\n",
+                                    ret, strerror(errno));
+                       return ret;
+               }
+       }
+
+       tevent_debug(ev, TEVENT_DEBUG_WARNING,
+                    "tevent_common_loop_wait() out of events\n");
+       return 0;
 }
 
 /*
   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 8c119ffb8ed032fcdaa1a716d38148fb526a6c92..6c5df6321a5be6d972bc7588ed33f639773401ef 100644 (file)
@@ -37,6 +37,7 @@ struct tevent_context;
 struct tevent_ops;
 struct tevent_fd;
 struct tevent_timer;
+struct tevent_immediate;
 struct tevent_signal;
 
 /* event handler types */
@@ -52,6 +53,9 @@ typedef void (*tevent_timer_handler_t)(struct tevent_context *ev,
                                       struct tevent_timer *te,
                                       struct timeval current_time,
                                       void *private_data);
+typedef void (*tevent_immediate_handler_t)(struct tevent_context *ctx,
+                                          struct tevent_immediate *im,
+                                          void *private_data);
 typedef void (*tevent_signal_handler_t)(struct tevent_context *ev,
                                        struct tevent_signal *se,
                                        int signum,
@@ -87,6 +91,21 @@ struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
        _tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \
                          #handler, __location__)
 
+struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx,
+                                                 const char *location);
+#define tevent_create_immediate(mem_ctx) \
+       _tevent_create_immediate(mem_ctx, __location__)
+
+void _tevent_schedule_immediate(struct tevent_immediate *im,
+                               struct tevent_context *ctx,
+                               tevent_immediate_handler_t handler,
+                               void *private_data,
+                               const char *handler_name,
+                               const char *location);
+#define tevent_schedule_immediate(im, ctx, handler, private_data) \
+       _tevent_schedule_immediate(im, ctx, handler, private_data, \
+                                  #handler, __location__);
+
 struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
                                         TALLOC_CTX *mem_ctx,
                                         int signum,
@@ -99,8 +118,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 +132,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
@@ -165,7 +193,11 @@ enum tevent_req_state {
        /**
         * No memory in between
         */
-       TEVENT_REQ_NO_MEMORY
+       TEVENT_REQ_NO_MEMORY,
+       /**
+        * the request is already received by the caller
+        */
+       TEVENT_REQ_RECEIVED
 };
 
 /**
@@ -183,98 +215,24 @@ enum tevent_req_state {
  * finished. This can happen while the completion function is called.
  */
 
-struct tevent_req {
-       /**
-        * @brief What to do on completion
-        *
-        * This is used for the user of an async request, fn is called when
-        * the request completes, either successfully or with an error.
-        */
-       struct {
-               /**
-                * @brief Completion function
-                * Completion function, to be filled by the API user
-                */
-               void (*fn)(struct tevent_req *);
-               /**
-                * @brief Private data for the completion function
-                */
-               void *private_data;
-       } async;
+struct tevent_req;
 
-       /**
-        * @brief Private state pointer for the actual implementation
-        *
-        * The implementation doing the work for the async request needs a
-        * current state like for example a fd event. The user of an async
-        * request should not touch this.
-        */
-       void *private_state;
+typedef void (*tevent_req_fn)(struct tevent_req *);
 
-       /**
-        * @brief A function to overwrite the default print function
-        *
-        * The implementation doing the work may want to imeplement a
-        * custom function to print the text representation of the async
-        * request.
-        */
-       char *(*private_print)(struct tevent_req *req, TALLOC_CTX *mem_ctx);
+void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt);
+void *_tevent_req_callback_data(struct tevent_req *req);
+void *_tevent_req_data(struct tevent_req *req);
 
-       /**
-        * @brief Internal state of the request
-        *
-        * Callers should only access this via functions and never directly.
-        */
-       struct {
-               /**
-                * @brief The talloc type of the private_state pointer
-                *
-                * This is filled by the tevent_req_create() macro.
-                *
-                * This for debugging only.
-                */
-               const char *private_type;
-
-               /**
-                * @brief The location where the request was created
-                *
-                * This uses the __location__ macro via the tevent_req_create()
-                * macro.
-                *
-                * This for debugging only.
-                */
-               const char *location;
-
-               /**
-                * @brief The external state - will be queried by the caller
-                *
-                * While the async request is being processed, state will remain in
-                * TEVENT_REQ_IN_PROGRESS. A request is finished if
-                * req->state>=TEVENT_REQ_DONE.
-                */
-               enum tevent_req_state state;
-
-               /**
-                * @brief status code when finished
-                *
-                * This status can be queried in the async completion function. It
-                * will be set to 0 when everything went fine.
-                */
-               uint64_t error;
-
-               /**
-                * @brief the timer event if tevent_req_post was used
-                *
-                */
-               struct tevent_timer *trigger;
-
-               /**
-                * @brief the timer event if tevent_req_set_timeout was used
-                *
-                */
-               struct tevent_timer *timer;
-       } internal;
-};
+#define tevent_req_callback_data(_req, _type) \
+       talloc_get_type_abort(_tevent_req_callback_data(_req), _type)
+#define tevent_req_callback_data_void(_req) \
+       _tevent_req_callback_data(_req)
+#define tevent_req_data(_req, _type) \
+       talloc_get_type_abort(_tevent_req_data(_req), _type)
+
+typedef char *(*tevent_req_print_fn)(struct tevent_req *, TALLOC_CTX *);
+
+void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn);
 
 char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx);
 
@@ -294,13 +252,22 @@ bool tevent_req_set_endtime(struct tevent_req *req,
                            struct tevent_context *ev,
                            struct timeval endtime);
 
-void tevent_req_done(struct tevent_req *req);
+void _tevent_req_done(struct tevent_req *req,
+                     const char *location);
+#define tevent_req_done(req) \
+       _tevent_req_done(req, __location__)
 
-bool tevent_req_error(struct tevent_req *req,
-                     uint64_t error);
+bool _tevent_req_error(struct tevent_req *req,
+                      uint64_t error,
+                      const char *location);
+#define tevent_req_error(req, error) \
+       _tevent_req_error(req, error, __location__)
 
-bool tevent_req_nomem(const void *p,
-                     struct tevent_req *req);
+bool _tevent_req_nomem(const void *p,
+                      struct tevent_req *req,
+                      const char *location);
+#define tevent_req_nomem(p, req) \
+       _tevent_req_nomem(p, req, __location__)
 
 struct tevent_req *tevent_req_post(struct tevent_req *req,
                                   struct tevent_context *ev);
@@ -314,6 +281,8 @@ bool tevent_req_is_error(struct tevent_req *req,
                         enum tevent_req_state *state,
                         uint64_t *error);
 
+void tevent_req_received(struct tevent_req *req);
+
 struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx,
                                      struct tevent_context *ev,
                                      struct timeval wakeup_time);
@@ -354,12 +323,37 @@ bool tevent_queue_add(struct tevent_queue *queue,
                      struct tevent_req *req,
                      tevent_queue_trigger_fn_t trigger,
                      void *private_data);
-bool tevent_queue_start(struct tevent_queue *queue,
-                       struct tevent_context *ev);
+void tevent_queue_start(struct tevent_queue *queue);
 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..7c7f389d5b9879889da4006fa7fd6a79abcb6995 100644 (file)
@@ -35,14 +35,6 @@ struct epoll_event_context {
        /* a pointer back to the generic event_context */
        struct tevent_context *ev;
 
-       /* this is changed by the destructors for the fd event
-          type. It is used to detect event destruction by event
-          handlers, which means the code that is calling the event
-          handler needs to assume that the linked list is no longer
-          valid
-       */
-       uint32_t destruction_count;
-
        /* when using epoll this is the handle from epoll_create */
        int epoll_fd;
 
@@ -242,9 +234,8 @@ static void epoll_change_event(struct epoll_event_context *epoll_ev, struct teve
 static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval *tvalp)
 {
        int ret, i;
-#define MAXEVENTS 32
+#define MAXEVENTS 1
        struct epoll_event events[MAXEVENTS];
-       uint32_t destruction_count = ++epoll_ev->destruction_count;
        int timeout = -1;
 
        if (epoll_ev->epoll_fd == -1) return -1;
@@ -305,9 +296,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
                if (events[i].events & EPOLLOUT) flags |= TEVENT_FD_WRITE;
                if (flags) {
                        fde->handler(epoll_ev->ev, fde, flags, fde->private_data);
-                       if (destruction_count != epoll_ev->destruction_count) {
-                               break;
-                       }
+                       break;
                }
        }
 
@@ -351,8 +340,6 @@ static int epoll_event_fd_destructor(struct tevent_fd *fde)
 
                epoll_check_reopen(epoll_ev);
 
-               epoll_ev->destruction_count++;
-
                epoll_del_event(epoll_ev, fde);
        }
 
@@ -411,12 +398,22 @@ 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);
        struct timeval tval;
 
+       if (ev->signal_events &&
+           tevent_common_check_signal(ev)) {
+               return 0;
+       }
+
+       if (ev->immediate_events &&
+           tevent_common_loop_immediate(ev)) {
+               return 0;
+       }
+
        tval = tevent_common_loop_timer_delay(ev);
        if (tevent_timeval_is_zero(&tval)) {
                return 0;
@@ -427,32 +424,17 @@ static int epoll_event_loop_once(struct tevent_context *ev)
        return epoll_event_loop(epoll_ev, &tval);
 }
 
-/*
-  return on failure or (with 0) if all fd events are removed
-*/
-static int epoll_event_loop_wait(struct tevent_context *ev)
-{
-       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) {
-                       break;
-               }
-       }
-
-       return 0;
-}
-
 static const struct tevent_ops epoll_event_ops = {
-       .context_init   = epoll_event_context_init,
-       .add_fd         = epoll_event_add_fd,
-       .set_fd_close_fn= tevent_common_fd_set_close_fn,
-       .get_fd_flags   = tevent_common_fd_get_flags,
-       .set_fd_flags   = epoll_event_set_fd_flags,
-       .add_timer      = tevent_common_add_timer,
-       .add_signal     = tevent_common_add_signal,
-       .loop_once      = epoll_event_loop_once,
-       .loop_wait      = epoll_event_loop_wait,
+       .context_init           = epoll_event_context_init,
+       .add_fd                 = epoll_event_add_fd,
+       .set_fd_close_fn        = tevent_common_fd_set_close_fn,
+       .get_fd_flags           = tevent_common_fd_get_flags,
+       .set_fd_flags           = epoll_event_set_fd_flags,
+       .add_timer              = tevent_common_add_timer,
+       .schedule_immediate     = tevent_common_schedule_immediate,
+       .add_signal             = tevent_common_add_signal,
+       .loop_once              = epoll_event_loop_once,
+       .loop_wait              = tevent_common_loop_wait,
 };
 
 bool tevent_epoll_init(void)
diff --git a/lib/tevent/tevent_immediate.c b/lib/tevent/tevent_immediate.c
new file mode 100644 (file)
index 0000000..1ac293e
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   common events code for immediate events
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "tevent.h"
+#include "tevent_internal.h"
+#include "tevent_util.h"
+
+static void tevent_common_immediate_cancel(struct tevent_immediate *im)
+{
+       if (!im->event_ctx) {
+               return;
+       }
+
+       tevent_debug(im->event_ctx, TEVENT_DEBUG_TRACE,
+                    "Cancel immediate event %p \"%s\"\n",
+                    im, im->handler_name);
+
+       /* let the backend free im->additional_data */
+       if (im->cancel_fn) {
+               im->cancel_fn(im);
+       }
+
+       DLIST_REMOVE(im->event_ctx->immediate_events, im);
+       im->event_ctx           = NULL;
+       im->handler             = NULL;
+       im->private_data        = NULL;
+       im->handler_name        = NULL;
+       im->schedule_location   = NULL;
+       im->cancel_fn           = NULL;
+       im->additional_data     = NULL;
+
+       talloc_set_destructor(im, NULL);
+}
+
+/*
+  destroy an immediate event
+*/
+static int tevent_common_immediate_destructor(struct tevent_immediate *im)
+{
+       tevent_common_immediate_cancel(im);
+       return 0;
+}
+
+/*
+ * schedule an immediate event on
+ */
+void tevent_common_schedule_immediate(struct tevent_immediate *im,
+                                     struct tevent_context *ev,
+                                     tevent_immediate_handler_t handler,
+                                     void *private_data,
+                                     const char *handler_name,
+                                     const char *location)
+{
+       tevent_common_immediate_cancel(im);
+
+       if (!handler) {
+               return;
+       }
+
+       im->event_ctx           = ev;
+       im->handler             = handler;
+       im->private_data        = private_data;
+       im->handler_name        = handler_name;
+       im->schedule_location   = location;
+       im->cancel_fn           = NULL;
+       im->additional_data     = NULL;
+
+       DLIST_ADD_END(ev->immediate_events, im, struct tevent_immediate *);
+       talloc_set_destructor(im, tevent_common_immediate_destructor);
+
+       tevent_debug(ev, TEVENT_DEBUG_TRACE,
+                    "Schedule immediate event \"%s\": %p\n",
+                    handler_name, im);
+}
+
+/*
+  trigger the first immediate event and return true
+  if no event was triggered return false
+*/
+bool tevent_common_loop_immediate(struct tevent_context *ev)
+{
+       struct tevent_immediate *im = ev->immediate_events;
+       tevent_immediate_handler_t handler;
+       void *private_data;
+
+       if (!im) {
+               return false;
+       }
+
+       tevent_debug(ev, TEVENT_DEBUG_TRACE,
+                    "Run immediate event \"%s\": %p\n",
+                    im->handler_name, im);
+
+       /*
+        * remember the handler and then clear the event
+        * the handler might reschedule the event
+        */
+       handler = im->handler;
+       private_data = im->private_data;
+
+       DLIST_REMOVE(im->event_ctx->immediate_events, im);
+       im->event_ctx           = NULL;
+       im->handler             = NULL;
+       im->private_data        = NULL;
+       im->handler_name        = NULL;
+       im->schedule_location   = NULL;
+       im->cancel_fn           = NULL;
+       im->additional_data     = NULL;
+
+       talloc_set_destructor(im, NULL);
+
+       handler(ev, im, private_data);
+
+       return true;
+}
+
index 758bdb4628b44483dd6df0f3de0975e4087453c8..eebf76706773a51eb83d8cff158acba25a80ef9d 100644 (file)
    License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
 
+struct tevent_req {
+       /**
+        * @brief What to do on completion
+        *
+        * This is used for the user of an async request, fn is called when
+        * the request completes, either successfully or with an error.
+        */
+       struct {
+               /**
+                * @brief Completion function
+                * Completion function, to be filled by the API user
+                */
+               tevent_req_fn fn;
+               /**
+                * @brief Private data for the completion function
+                */
+               void *private_data;
+       } async;
+
+       /**
+        * @brief Private state pointer for the actual implementation
+        *
+        * The implementation doing the work for the async request needs to
+        * keep around current data like for example a fd event. The user of
+        * an async request should not touch this.
+        */
+       void *data;
+
+       /**
+        * @brief A function to overwrite the default print function
+        *
+        * The implementation doing the work may want to implement a
+        * custom function to print the text representation of the async
+        * request.
+        */
+       tevent_req_print_fn private_print;
+
+       /**
+        * @brief Internal state of the request
+        *
+        * Callers should only access this via functions and never directly.
+        */
+       struct {
+               /**
+                * @brief The talloc type of the data pointer
+                *
+                * This is filled by the tevent_req_create() macro.
+                *
+                * This for debugging only.
+                */
+               const char *private_type;
+
+               /**
+                * @brief The location where the request was created
+                *
+                * This uses the __location__ macro via the tevent_req_create()
+                * macro.
+                *
+                * This for debugging only.
+                */
+               const char *create_location;
+
+               /**
+                * @brief The location where the request was finished
+                *
+                * This uses the __location__ macro via the tevent_req_done(),
+                * tevent_req_error() or tevent_req_nomem() macro.
+                *
+                * This for debugging only.
+                */
+               const char *finish_location;
+
+               /**
+                * @brief The external state - will be queried by the caller
+                *
+                * While the async request is being processed, state will remain in
+                * TEVENT_REQ_IN_PROGRESS. A request is finished if
+                * req->state>=TEVENT_REQ_DONE.
+                */
+               enum tevent_req_state state;
+
+               /**
+                * @brief status code when finished
+                *
+                * This status can be queried in the async completion function. It
+                * will be set to 0 when everything went fine.
+                */
+               uint64_t error;
+
+               /**
+                * @brief the immediate event used by tevent_req_post
+                *
+                */
+               struct tevent_immediate *trigger;
+
+               /**
+                * @brief the timer event if tevent_req_set_timeout was used
+                *
+                */
+               struct tevent_timer *timer;
+       } internal;
+};
+
 struct tevent_ops {
        /* conntext init */
        int (*context_init)(struct tevent_context *ev);
@@ -50,6 +153,15 @@ struct tevent_ops {
                                          void *private_data,
                                          const char *handler_name,
                                          const char *location);
+
+       /* immediate event functions */
+       void (*schedule_immediate)(struct tevent_immediate *im,
+                                  struct tevent_context *ev,
+                                  tevent_immediate_handler_t handler,
+                                  void *private_data,
+                                  const char *handler_name,
+                                  const char *location);
+
        /* signal functions */
        struct tevent_signal *(*add_signal)(struct tevent_context *ev,
                                            TALLOC_CTX *mem_ctx,
@@ -60,8 +172,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 {
@@ -95,6 +207,21 @@ struct tevent_timer {
        void *additional_data;
 };
 
+struct tevent_immediate {
+       struct tevent_immediate *prev, *next;
+       struct tevent_context *event_ctx;
+       tevent_immediate_handler_t handler;
+       /* this is private for the specific handler */
+       void *private_data;
+       /* this is for debugging only! */
+       const char *handler_name;
+       const char *create_location;
+       const char *schedule_location;
+       /* this is private for the events_ops implementation */
+       void (*cancel_fn)(struct tevent_immediate *im);
+       void *additional_data;
+};
+
 struct tevent_signal {
        struct tevent_signal *prev, *next;
        struct tevent_context *event_ctx;
@@ -129,6 +256,9 @@ struct tevent_context {
        /* list of timed events - used by common code */
        struct tevent_timer *timer_events;
 
+       /* list of immediate events - used by common code */
+       struct tevent_immediate *immediate_events;
+
        /* list of signal events - used by common code */
        struct tevent_signal *signal_events;
 
@@ -140,12 +270,22 @@ 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;
 };
 
 
 bool tevent_register_backend(const char *name, const struct tevent_ops *ops);
 
 int tevent_common_context_destructor(struct tevent_context *ev);
+int tevent_common_loop_wait(struct tevent_context *ev,
+                           const char *location);
 
 int tevent_common_fd_destructor(struct tevent_fd *fde);
 struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev,
@@ -170,6 +310,14 @@ struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev,
                                             const char *location);
 struct timeval tevent_common_loop_timer_delay(struct tevent_context *);
 
+void tevent_common_schedule_immediate(struct tevent_immediate *im,
+                                     struct tevent_context *ev,
+                                     tevent_immediate_handler_t handler,
+                                     void *private_data,
+                                     const char *handler_name,
+                                     const char *location);
+bool tevent_common_loop_immediate(struct tevent_context *ev);
+
 struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
                                               TALLOC_CTX *mem_ctx,
                                               int signum,
index 6c8fbe4f95f0acf6042f72cdd04b29b1f9ea71de..3715c35e4f3416d5d9ce47b8e7ccf333feb08eb4 100644 (file)
@@ -34,6 +34,7 @@ struct tevent_queue_entry {
        bool triggered;
 
        struct tevent_req *req;
+       struct tevent_context *ev;
 
        tevent_queue_trigger_fn_t trigger;
        void *private_data;
@@ -44,12 +45,16 @@ struct tevent_queue {
        const char *location;
 
        bool running;
-       struct tevent_timer *timer;
+       struct tevent_immediate *immediate;
 
        size_t length;
        struct tevent_queue_entry *list;
 };
 
+static void tevent_queue_immediate_trigger(struct tevent_context *ev,
+                                          struct tevent_immediate *im,
+                                          void *private_data);
+
 static int tevent_queue_entry_destructor(struct tevent_queue_entry *e)
 {
        struct tevent_queue *q = e->queue;
@@ -61,14 +66,23 @@ static int tevent_queue_entry_destructor(struct tevent_queue_entry *e)
        DLIST_REMOVE(q->list, e);
        q->length--;
 
-       if (e->triggered &&
-           q->running &&
-           q->list) {
-               q->list->triggered = true;
-               q->list->trigger(q->list->req,
-                                q->list->private_data);
+       if (!q->running) {
+               return 0;
+       }
+
+       if (!q->list) {
+               return 0;
+       }
+
+       if (q->list->triggered) {
+               return 0;
        }
 
+       tevent_schedule_immediate(q->immediate,
+                                 q->list->ev,
+                                 tevent_queue_immediate_trigger,
+                                 q);
+
        return 0;
 }
 
@@ -100,6 +114,11 @@ struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx,
                talloc_free(queue);
                return NULL;
        }
+       queue->immediate = tevent_create_immediate(queue);
+       if (!queue->immediate) {
+               talloc_free(queue);
+               return NULL;
+       }
 
        queue->location = location;
 
@@ -110,16 +129,16 @@ struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx,
        return queue;
 }
 
-static void tevent_queue_timer_start(struct tevent_context *ev,
-                                    struct tevent_timer *te,
-                                    struct timeval now,
-                                    void *private_data)
+static void tevent_queue_immediate_trigger(struct tevent_context *ev,
+                                          struct tevent_immediate *im,
+                                          void *private_data)
 {
        struct tevent_queue *q = talloc_get_type(private_data,
                                  struct tevent_queue);
 
-       talloc_free(te);
-       q->timer = NULL;
+       if (!q->running) {
+               return;
+       }
 
        q->list->triggered = true;
        q->list->trigger(q->list->req, q->list->private_data);
@@ -140,56 +159,56 @@ bool tevent_queue_add(struct tevent_queue *queue,
 
        e->queue = queue;
        e->req = req;
+       e->ev = ev;
        e->trigger = trigger;
        e->private_data = private_data;
 
-       if (queue->running &&
-           !queue->timer &&
-           !queue->list) {
-               queue->timer = tevent_add_timer(ev, queue, tevent_timeval_zero(),
-                                               tevent_queue_timer_start,
-                                               queue);
-               if (!queue->timer) {
-                       talloc_free(e);
-                       return false;
-               }
-       }
-
        DLIST_ADD_END(queue->list, e, struct tevent_queue_entry *);
        queue->length++;
        talloc_set_destructor(e, tevent_queue_entry_destructor);
 
+       if (!queue->running) {
+               return true;
+       }
+
+       if (queue->list->triggered) {
+               return true;
+       }
+
+       tevent_schedule_immediate(queue->immediate,
+                                 queue->list->ev,
+                                 tevent_queue_immediate_trigger,
+                                 queue);
+
        return true;
 }
 
-bool tevent_queue_start(struct tevent_queue *queue,
-                       struct tevent_context *ev)
+void tevent_queue_start(struct tevent_queue *queue)
 {
        if (queue->running) {
                /* already started */
-               return true;
+               return;
        }
 
-       if (!queue->timer &&
-           queue->list) {
-               queue->timer = tevent_add_timer(ev, queue, tevent_timeval_zero(),
-                                               tevent_queue_timer_start,
-                                               queue);
-               if (!queue->timer) {
-                       return false;
-               }
+       queue->running = true;
+
+       if (!queue->list) {
+               return;
        }
 
-       queue->running = true;
+       if (queue->list->triggered) {
+               return;
+       }
 
-       return true;
+       tevent_schedule_immediate(queue->immediate,
+                                 queue->list->ev,
+                                 tevent_queue_immediate_trigger,
+                                 queue);
 }
 
 void tevent_queue_stop(struct tevent_queue *queue)
 {
        queue->running = false;
-       talloc_free(queue->timer);
-       queue->timer = NULL;
 }
 
 size_t tevent_queue_length(struct tevent_queue *queue)
index e243c7de5de3d4787bf4a3a962be9022dfe5c42c..380a6388e29bca675071d819894f55b2cae1d88b 100644 (file)
@@ -43,12 +43,12 @@ char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx)
        return talloc_asprintf(mem_ctx,
                               "tevent_req[%p/%s]: state[%d] error[%lld (0x%llX)] "
                               " state[%s (%p)] timer[%p]",
-                              req, req->internal.location,
+                              req, req->internal.create_location,
                               req->internal.state,
                               (unsigned long long)req->internal.error,
                               (unsigned long long)req->internal.error,
-                              talloc_get_name(req->private_state),
-                              req->private_state,
+                              talloc_get_name(req->data),
+                              req->data,
                               req->internal.timer
                               );
 }
@@ -81,39 +81,48 @@ char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req)
  */
 
 struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
-                                   void *pstate,
-                                   size_t state_size,
+                                   void *pdata,
+                                   size_t data_size,
                                    const char *type,
                                    const char *location)
 {
        struct tevent_req *req;
-       void **ppstate = (void **)pstate;
-       void *state;
+       void **ppdata = (void **)pdata;
+       void *data;
 
        req = talloc_zero(mem_ctx, struct tevent_req);
        if (req == NULL) {
                return NULL;
        }
        req->internal.private_type      = type;
-       req->internal.location          = location;
+       req->internal.create_location   = location;
+       req->internal.finish_location   = NULL;
        req->internal.state             = TEVENT_REQ_IN_PROGRESS;
+       req->internal.trigger           = tevent_create_immediate(req);
+       if (!req->internal.trigger) {
+               talloc_free(req);
+               return NULL;
+       }
 
-       state = talloc_size(req, state_size);
-       if (state == NULL) {
+       data = talloc_size(req, data_size);
+       if (data == NULL) {
                talloc_free(req);
                return NULL;
        }
-       talloc_set_name_const(state, type);
+       talloc_set_name_const(data, type);
 
-       req->private_state = state;
+       req->data = data;
 
-       *ppstate = state;
+       *ppdata = data;
        return req;
 }
 
-static void tevent_req_finish(struct tevent_req *req, enum tevent_req_state state)
+static void tevent_req_finish(struct tevent_req *req,
+                             enum tevent_req_state state,
+                             const char *location)
 {
        req->internal.state = state;
+       req->internal.finish_location = location;
        if (req->async.fn != NULL) {
                req->async.fn(req);
        }
@@ -128,9 +137,10 @@ static void tevent_req_finish(struct tevent_req *req, enum tevent_req_state stat
  * function.
  */
 
-void tevent_req_done(struct tevent_req *req)
+void _tevent_req_done(struct tevent_req *req,
+                     const char *location)
 {
-       tevent_req_finish(req, TEVENT_REQ_DONE);
+       tevent_req_finish(req, TEVENT_REQ_DONE, location);
 }
 
 /**
@@ -161,14 +171,16 @@ void tevent_req_done(struct tevent_req *req)
  * \endcode
  */
 
-bool tevent_req_error(struct tevent_req *req, uint64_t error)
+bool _tevent_req_error(struct tevent_req *req,
+                      uint64_t error,
+                      const char *location)
 {
        if (error == 0) {
                return false;
        }
 
        req->internal.error = error;
-       tevent_req_finish(req, TEVENT_REQ_USER_ERROR);
+       tevent_req_finish(req, TEVENT_REQ_USER_ERROR, location);
        return true;
 }
 
@@ -189,42 +201,39 @@ bool tevent_req_error(struct tevent_req *req, uint64_t error)
  * \endcode
  */
 
-bool tevent_req_nomem(const void *p, struct tevent_req *req)
+bool _tevent_req_nomem(const void *p,
+                      struct tevent_req *req,
+                      const char *location)
 {
        if (p != NULL) {
                return false;
        }
-       tevent_req_finish(req, TEVENT_REQ_NO_MEMORY);
+       tevent_req_finish(req, TEVENT_REQ_NO_MEMORY, location);
        return true;
 }
 
 /**
- * @brief Timed event callback
+ * @brief Immediate event callback
  * @param[in] ev       Event context
- * @param[in] te       The timed event
- * @param[in] now      zero time
+ * @param[in] im       The immediate event
  * @param[in] priv     The async request to be finished
  */
 static void tevent_req_trigger(struct tevent_context *ev,
-                              struct tevent_timer *te,
-                              struct timeval zero,
+                              struct tevent_immediate *im,
                               void *private_data)
 {
        struct tevent_req *req = talloc_get_type(private_data,
                                 struct tevent_req);
 
-       talloc_free(req->internal.trigger);
-       req->internal.trigger = NULL;
-
-       tevent_req_finish(req, req->internal.state);
+       tevent_req_finish(req, req->internal.state,
+                         req->internal.finish_location);
 }
 
 /**
  * @brief Finish a request before the caller had the change to set the callback
  * @param[in] req      The finished request
  * @param[in] ev       The tevent_context for the timed event
- * @retval             On success req will be returned,
- *                     on failure req will be destroyed
+ * @retval             req will be returned
  *
  * An implementation of an async request might find that it can either finish
  * the request without waiting for an external event, or it can't even start
@@ -237,13 +246,8 @@ static void tevent_req_trigger(struct tevent_context *ev,
 struct tevent_req *tevent_req_post(struct tevent_req *req,
                                   struct tevent_context *ev)
 {
-       req->internal.trigger = tevent_add_timer(ev, req, tevent_timeval_zero(),
-                                                tevent_req_trigger, req);
-       if (!req->internal.trigger) {
-               talloc_free(req);
-               return NULL;
-       }
-
+       tevent_schedule_immediate(req->internal.trigger,
+                                 ev, tevent_req_trigger, req);
        return req;
 }
 
@@ -256,6 +260,24 @@ bool tevent_req_is_in_progress(struct tevent_req *req)
        return false;
 }
 
+/**
+ * @brief This function destroys the attached private data
+ * @param[in] req      The finished request
+ *
+ * This function can be called as last action of a _recv()
+ * function, it destroys the data attached to the tevent_req.
+ */
+void tevent_req_received(struct tevent_req *req)
+{
+       TALLOC_FREE(req->data);
+       req->private_print = NULL;
+
+       TALLOC_FREE(req->internal.trigger);
+       TALLOC_FREE(req->internal.timer);
+
+       req->internal.state = TEVENT_REQ_RECEIVED;
+}
+
 bool tevent_req_poll(struct tevent_req *req,
                     struct tevent_context *ev)
 {
@@ -292,17 +314,16 @@ static void tevent_req_timedout(struct tevent_context *ev,
        struct tevent_req *req = talloc_get_type(private_data,
                                 struct tevent_req);
 
-       talloc_free(req->internal.timer);
-       req->internal.timer = NULL;
+       TALLOC_FREE(req->internal.timer);
 
-       tevent_req_finish(req, TEVENT_REQ_TIMED_OUT);
+       tevent_req_finish(req, TEVENT_REQ_TIMED_OUT, __FUNCTION__);
 }
 
 bool tevent_req_set_endtime(struct tevent_req *req,
                            struct tevent_context *ev,
                            struct timeval endtime)
 {
-       talloc_free(req->internal.timer);
+       TALLOC_FREE(req->internal.timer);
 
        req->internal.timer = tevent_add_timer(ev, req, endtime,
                                               tevent_req_timedout,
@@ -314,3 +335,23 @@ bool tevent_req_set_endtime(struct tevent_req *req,
        return true;
 }
 
+void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt)
+{
+       req->async.fn = fn;
+       req->async.private_data = pvt;
+}
+
+void *_tevent_req_callback_data(struct tevent_req *req)
+{
+       return req->async.private_data;
+}
+
+void *_tevent_req_data(struct tevent_req *req)
+{
+       return req->data;
+}
+
+void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn)
+{
+       req->private_print = fn;
+}
index 32678f0a156ccbd517e709f0810f9846ac12a751..d97418991ae3e3dd8bec6edd13d7fb5a0144b0ff 100644 (file)
@@ -38,10 +38,6 @@ struct select_event_context {
 
        /* information for exiting from the event loop */
        int exit_code;
-
-       /* this is incremented when the loop over events causes something which
-          could change the events yet to be processed */
-       uint32_t destruction_count;
 };
 
 /*
@@ -95,8 +91,6 @@ static int select_event_fd_destructor(struct tevent_fd *fde)
                if (select_ev->maxfd == fde->fd) {
                        select_ev->maxfd = EVENT_INVALID_MAXFD;
                }
-
-               select_ev->destruction_count++;
        }
 
        return tevent_common_fd_destructor(fde);
@@ -138,7 +132,6 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
        fd_set r_fds, w_fds;
        struct tevent_fd *fde;
        int selrtn;
-       uint32_t destruction_count = ++select_ev->destruction_count;
 
        /* we maybe need to recalculate the maxfd */
        if (select_ev->maxfd == EVENT_INVALID_MAXFD) {
@@ -200,61 +193,52 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
                        if (FD_ISSET(fde->fd, &w_fds)) flags |= TEVENT_FD_WRITE;
                        if (flags) {
                                fde->handler(select_ev->ev, fde, flags, fde->private_data);
-                               if (destruction_count != select_ev->destruction_count) {
-                                       break;
-                               }
+                               break;
                        }
                }
        }
 
        return 0;
-}              
+}
 
 /*
   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);
        struct timeval tval;
 
-       tval = tevent_common_loop_timer_delay(ev);
-       if (tevent_timeval_is_zero(&tval)) {
+       if (ev->signal_events &&
+           tevent_common_check_signal(ev)) {
                return 0;
        }
 
-       return select_event_loop_select(select_ev, &tval);
-}
-
-/*
-  return on failure or (with 0) if all fd events are removed
-*/
-static int select_event_loop_wait(struct tevent_context *ev)
-{
-       struct select_event_context *select_ev = talloc_get_type(ev->additional_data,
-                                                          struct select_event_context);
-       select_ev->exit_code = 0;
+       if (ev->immediate_events &&
+           tevent_common_loop_immediate(ev)) {
+               return 0;
+       }
 
-       while (ev->fd_events && select_ev->exit_code == 0) {
-               if (select_event_loop_once(ev) != 0) {
-                       break;
-               }
+       tval = tevent_common_loop_timer_delay(ev);
+       if (tevent_timeval_is_zero(&tval)) {
+               return 0;
        }
 
-       return select_ev->exit_code;
+       return select_event_loop_select(select_ev, &tval);
 }
 
 static const struct tevent_ops select_event_ops = {
-       .context_init   = select_event_context_init,
-       .add_fd         = select_event_add_fd,
-       .set_fd_close_fn= tevent_common_fd_set_close_fn,
-       .get_fd_flags   = tevent_common_fd_get_flags,
-       .set_fd_flags   = tevent_common_fd_set_flags,
-       .add_timer      = tevent_common_add_timer,
-       .add_signal     = tevent_common_add_signal,
-       .loop_once      = select_event_loop_once,
-       .loop_wait      = select_event_loop_wait,
+       .context_init           = select_event_context_init,
+       .add_fd                 = select_event_add_fd,
+       .set_fd_close_fn        = tevent_common_fd_set_close_fn,
+       .get_fd_flags           = tevent_common_fd_get_flags,
+       .set_fd_flags           = tevent_common_fd_set_flags,
+       .add_timer              = tevent_common_add_timer,
+       .schedule_immediate     = tevent_common_schedule_immediate,
+       .add_signal             = tevent_common_add_signal,
+       .loop_once              = select_event_loop_once,
+       .loop_wait              = tevent_common_loop_wait,
 };
 
 bool tevent_select_init(void)
index bbd5c5d78577f7d2b1486a1113b57491b4063375..c3f8b36e840faf52773d1e7c6327a23cf909c7c4 100644 (file)
@@ -48,14 +48,6 @@ struct std_event_context {
        /* information for exiting from the event loop */
        int exit_code;
 
-       /* this is changed by the destructors for the fd event
-          type. It is used to detect event destruction by event
-          handlers, which means the code that is calling the event
-          handler needs to assume that the linked list is no longer
-          valid
-       */
-       uint32_t destruction_count;
-
        /* when using epoll this is the handle from epoll_create */
        int epoll_fd;
 
@@ -253,9 +245,8 @@ static void epoll_change_event(struct std_event_context *std_ev, struct tevent_f
 static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tvalp)
 {
        int ret, i;
-#define MAXEVENTS 8
+#define MAXEVENTS 1
        struct epoll_event events[MAXEVENTS];
-       uint32_t destruction_count = ++std_ev->destruction_count;
        int timeout = -1;
 
        if (std_ev->epoll_fd == -1) return -1;
@@ -316,9 +307,7 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
                if (events[i].events & EPOLLOUT) flags |= TEVENT_FD_WRITE;
                if (flags) {
                        fde->handler(std_ev->ev, fde, flags, fde->private_data);
-                       if (destruction_count != std_ev->destruction_count) {
-                               break;
-                       }
+                       break;
                }
        }
 
@@ -390,8 +379,6 @@ static int std_event_fd_destructor(struct tevent_fd *fde)
                        std_ev->maxfd = EVENT_INVALID_MAXFD;
                }
 
-               std_ev->destruction_count++;
-
                epoll_del_event(std_ev, fde);
        }
 
@@ -459,7 +446,6 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
        fd_set r_fds, w_fds;
        struct tevent_fd *fde;
        int selrtn;
-       uint32_t destruction_count = ++std_ev->destruction_count;
 
        /* we maybe need to recalculate the maxfd */
        if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
@@ -521,9 +507,7 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
                        if (FD_ISSET(fde->fd, &w_fds)) flags |= TEVENT_FD_WRITE;
                        if (flags) {
                                fde->handler(std_ev->ev, fde, flags, fde->private_data);
-                               if (destruction_count != std_ev->destruction_count) {
-                                       break;
-                               }
+                               break;
                        }
                }
        }
@@ -534,12 +518,22 @@ 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);
        struct timeval tval;
 
+       if (ev->signal_events &&
+           tevent_common_check_signal(ev)) {
+               return 0;
+       }
+
+       if (ev->immediate_events &&
+           tevent_common_loop_immediate(ev)) {
+               return 0;
+       }
+
        tval = tevent_common_loop_timer_delay(ev);
        if (tevent_timeval_is_zero(&tval)) {
                return 0;
@@ -554,34 +548,17 @@ static int std_event_loop_once(struct tevent_context *ev)
        return std_event_loop_select(std_ev, &tval);
 }
 
-/*
-  return on failure or (with 0) if all fd events are removed
-*/
-static int std_event_loop_wait(struct tevent_context *ev)
-{
-       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) {
-                       break;
-               }
-       }
-
-       return std_ev->exit_code;
-}
-
 static const struct tevent_ops std_event_ops = {
-       .context_init   = std_event_context_init,
-       .add_fd         = std_event_add_fd,
-       .set_fd_close_fn= tevent_common_fd_set_close_fn,
-       .get_fd_flags   = tevent_common_fd_get_flags,
-       .set_fd_flags   = std_event_set_fd_flags,
-       .add_timer      = tevent_common_add_timer,
-       .add_signal     = tevent_common_add_signal,
-       .loop_once      = std_event_loop_once,
-       .loop_wait      = std_event_loop_wait,
+       .context_init           = std_event_context_init,
+       .add_fd                 = std_event_add_fd,
+       .set_fd_close_fn        = tevent_common_fd_set_close_fn,
+       .get_fd_flags           = tevent_common_fd_get_flags,
+       .set_fd_flags           = std_event_set_fd_flags,
+       .add_timer              = tevent_common_add_timer,
+       .schedule_immediate     = tevent_common_schedule_immediate,
+       .add_signal             = tevent_common_add_signal,
+       .loop_once              = std_event_loop_once,
+       .loop_wait              = tevent_common_loop_wait,
 };
 
 
diff --git a/lib/tsocket/config.mk b/lib/tsocket/config.mk
new file mode 100644 (file)
index 0000000..c35f0af
--- /dev/null
@@ -0,0 +1,17 @@
+[SUBSYSTEM::LIBTSOCKET]
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT LIBREPLACE_NETWORK
+
+LIBTSOCKET_OBJ_FILES = $(addprefix ../lib/tsocket/, \
+                                       tsocket.o \
+                                       tsocket_helpers.o \
+                                       tsocket_bsd.o \
+                                       tsocket_recvfrom.o \
+                                       tsocket_sendto.o \
+                                       tsocket_connect.o \
+                                       tsocket_writev.o \
+                                       tsocket_readv.o)
+
+PUBLIC_HEADERS += $(addprefix ../lib/tsocket/, \
+                                tsocket.h\
+                                tsocket_internal.h)
+
diff --git a/lib/tsocket/tsocket.c b/lib/tsocket/tsocket.c
new file mode 100644 (file)
index 0000000..1a12e69
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/network.h"
+#include "tsocket.h"
+#include "tsocket_internal.h"
+
+static int tsocket_context_destructor(struct tsocket_context *sock)
+{
+       tsocket_disconnect(sock);
+       return 0;
+}
+
+struct tsocket_context *_tsocket_context_create(TALLOC_CTX *mem_ctx,
+                                               const struct tsocket_context_ops *ops,
+                                               void *pstate,
+                                               size_t psize,
+                                               const char *type,
+                                               const char *location)
+{
+       void **ppstate = (void **)pstate;
+       struct tsocket_context *sock;
+
+       sock = talloc_zero(mem_ctx, struct tsocket_context);
+       if (!sock) {
+               return NULL;
+       }
+       sock->ops = ops;
+       sock->location = location;
+       sock->private_data = talloc_size(sock, psize);
+       if (!sock->private_data) {
+               talloc_free(sock);
+               return NULL;
+       }
+       talloc_set_name_const(sock->private_data, type);
+
+       talloc_set_destructor(sock, tsocket_context_destructor);
+
+       *ppstate = sock->private_data;
+       return sock;
+}
+
+int tsocket_set_event_context(struct tsocket_context *sock,
+                             struct tevent_context *ev)
+{
+       return sock->ops->set_event_context(sock, ev);
+}
+
+int tsocket_set_readable_handler(struct tsocket_context *sock,
+                                tsocket_event_handler_t handler,
+                                void *private_data)
+{
+       return sock->ops->set_read_handler(sock, handler, private_data);
+}
+
+int tsocket_set_writeable_handler(struct tsocket_context *sock,
+                                 tsocket_event_handler_t handler,
+                                 void *private_data)
+{
+       return sock->ops->set_write_handler(sock, handler, private_data);
+}
+
+int tsocket_connect(struct tsocket_context *sock,
+                   const struct tsocket_address *remote_addr)
+{
+       return sock->ops->connect_to(sock, remote_addr);
+}
+
+int tsocket_listen(struct tsocket_context *sock,
+                  int queue_size)
+{
+       return sock->ops->listen_on(sock, queue_size);
+}
+
+int _tsocket_accept(struct tsocket_context *sock,
+                   TALLOC_CTX *mem_ctx,
+                   struct tsocket_context **new_sock,
+                   const char *location)
+{
+       return sock->ops->accept_new(sock, mem_ctx, new_sock, location);
+}
+
+ssize_t tsocket_pending(struct tsocket_context *sock)
+{
+       return sock->ops->pending_data(sock);
+}
+
+int tsocket_readv(struct tsocket_context *sock,
+                 const struct iovec *vector, size_t count)
+{
+       return sock->ops->readv_data(sock, vector, count);
+}
+
+int tsocket_writev(struct tsocket_context *sock,
+                  const struct iovec *vector, size_t count)
+{
+       return sock->ops->writev_data(sock, vector, count);
+}
+
+ssize_t tsocket_recvfrom(struct tsocket_context *sock,
+                        uint8_t *data, size_t len,
+                        TALLOC_CTX *addr_ctx,
+                        struct tsocket_address **src_addr)
+{
+       return sock->ops->recvfrom_data(sock, data, len, addr_ctx, src_addr);
+}
+
+ssize_t tsocket_sendto(struct tsocket_context *sock,
+                      const uint8_t *data, size_t len,
+                      const struct tsocket_address *dest_addr)
+{
+       return sock->ops->sendto_data(sock, data, len, dest_addr);
+}
+
+int tsocket_get_status(const struct tsocket_context *sock)
+{
+       return sock->ops->get_status(sock);
+}
+
+int _tsocket_get_local_address(const struct tsocket_context *sock,
+                              TALLOC_CTX *mem_ctx,
+                              struct tsocket_address **local_addr,
+                              const char *location)
+{
+       return sock->ops->get_local_address(sock, mem_ctx,
+                                           local_addr, location);
+}
+
+int _tsocket_get_remote_address(const struct tsocket_context *sock,
+                               TALLOC_CTX *mem_ctx,
+                               struct tsocket_address **remote_addr,
+                               const char *location)
+{
+       return sock->ops->get_remote_address(sock, mem_ctx,
+                                            remote_addr, location);
+}
+
+int tsocket_get_option(const struct tsocket_context *sock,
+                      const char *option,
+                      TALLOC_CTX *mem_ctx,
+                      char **value)
+{
+       return sock->ops->get_option(sock, option, mem_ctx, value);
+}
+
+int tsocket_set_option(const struct tsocket_context *sock,
+                      const char *option,
+                      bool force,
+                      const char *value)
+{
+       return sock->ops->set_option(sock, option, force, value);
+}
+
+void tsocket_disconnect(struct tsocket_context *sock)
+{
+       sock->ops->disconnect(sock);
+}
+
+struct tsocket_address *_tsocket_address_create(TALLOC_CTX *mem_ctx,
+                                               const struct tsocket_address_ops *ops,
+                                               void *pstate,
+                                               size_t psize,
+                                               const char *type,
+                                               const char *location)
+{
+       void **ppstate = (void **)pstate;
+       struct tsocket_address *addr;
+
+       addr = talloc_zero(mem_ctx, struct tsocket_address);
+       if (!addr) {
+               return NULL;
+       }
+       addr->ops = ops;
+       addr->location = location;
+       addr->private_data = talloc_size(addr, psize);
+       if (!addr->private_data) {
+               talloc_free(addr);
+               return NULL;
+       }
+       talloc_set_name_const(addr->private_data, type);
+
+       *ppstate = addr->private_data;
+       return addr;
+}
+
+char *tsocket_address_string(const struct tsocket_address *addr,
+                            TALLOC_CTX *mem_ctx)
+{
+       if (!addr) {
+               return talloc_strdup(mem_ctx, "NULL");
+       }
+       return addr->ops->string(addr, mem_ctx);
+}
+
+struct tsocket_address *_tsocket_address_copy(const struct tsocket_address *addr,
+                                             TALLOC_CTX *mem_ctx,
+                                             const char *location)
+{
+       return addr->ops->copy(addr, mem_ctx, location);
+}
+
+int _tsocket_address_create_socket(const struct tsocket_address *addr,
+                                  enum tsocket_type type,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct tsocket_context **sock,
+                                  const char *location)
+{
+       return addr->ops->create_socket(addr, type, mem_ctx, sock, location);
+}
+
diff --git a/lib/tsocket/tsocket.h b/lib/tsocket/tsocket.h
new file mode 100644 (file)
index 0000000..9bcfb5c
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _TSOCKET_H
+#define _TSOCKET_H
+
+#include <talloc.h>
+#include <tevent.h>
+
+struct tsocket_context;
+struct tsocket_address;
+struct iovec;
+
+enum tsocket_type {
+       TSOCKET_TYPE_STREAM = 1,
+       TSOCKET_TYPE_DGRAM,
+       TSOCKET_TYPE_MESSAGE
+};
+
+typedef void (*tsocket_event_handler_t)(struct tsocket_context *, void *);
+int tsocket_set_event_context(struct tsocket_context *sock,
+                             struct tevent_context *ev);
+int tsocket_set_readable_handler(struct tsocket_context *sock,
+                                tsocket_event_handler_t handler,
+                                void *private_data);
+int tsocket_set_writeable_handler(struct tsocket_context *sock,
+                                 tsocket_event_handler_t handler,
+                                 void *private_data);
+
+int tsocket_connect(struct tsocket_context *sock,
+                   const struct tsocket_address *remote_addr);
+
+int tsocket_listen(struct tsocket_context *sock,
+                  int queue_size);
+
+int _tsocket_accept(struct tsocket_context *sock,
+                   TALLOC_CTX *mem_ctx,
+                   struct tsocket_context **new_sock,
+                   const char *location);
+#define tsocket_accept(sock, mem_ctx, new_sock) \
+       _tsocket_accept(sock, mem_ctx, new_sock, __location__)
+
+ssize_t tsocket_pending(struct tsocket_context *sock);
+
+int tsocket_readv(struct tsocket_context *sock,
+                 const struct iovec *vector, size_t count);
+int tsocket_writev(struct tsocket_context *sock,
+                  const struct iovec *vector, size_t count);
+
+ssize_t tsocket_recvfrom(struct tsocket_context *sock,
+                        uint8_t *data, size_t len,
+                        TALLOC_CTX *addr_ctx,
+                        struct tsocket_address **src_addr);
+ssize_t tsocket_sendto(struct tsocket_context *sock,
+                      const uint8_t *data, size_t len,
+                      const struct tsocket_address *dest_addr);
+
+int tsocket_get_status(const struct tsocket_context *sock);
+
+int _tsocket_get_local_address(const struct tsocket_context *sock,
+                              TALLOC_CTX *mem_ctx,
+                              struct tsocket_address **local_addr,
+                              const char *location);
+#define tsocket_get_local_address(sock, mem_ctx, local_addr) \
+       _tsocket_get_local_address(sock, mem_ctx, local_addr, __location__)
+int _tsocket_get_remote_address(const struct tsocket_context *sock,
+                               TALLOC_CTX *mem_ctx,
+                               struct tsocket_address **remote_addr,
+                               const char *location);
+#define tsocket_get_remote_address(sock, mem_ctx, remote_addr) \
+       _tsocket_get_remote_address(sock, mem_ctx, remote_addr, __location__)
+
+int tsocket_get_option(const struct tsocket_context *sock,
+                      const char *option,
+                      TALLOC_CTX *mem_ctx,
+                      char **value);
+int tsocket_set_option(const struct tsocket_context *sock,
+                      const char *option,
+                      bool force,
+                      const char *value);
+
+void tsocket_disconnect(struct tsocket_context *sock);
+
+char *tsocket_address_string(const struct tsocket_address *addr,
+                            TALLOC_CTX *mem_ctx);
+
+struct tsocket_address *_tsocket_address_copy(const struct tsocket_address *addr,
+                                             TALLOC_CTX *mem_ctx,
+                                             const char *location);
+
+#define tsocket_address_copy(addr, mem_ctx) \
+       _tsocket_address_copy(addr, mem_ctx, __location__)
+
+int _tsocket_address_create_socket(const struct tsocket_address *addr,
+                                  enum tsocket_type type,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct tsocket_context **sock,
+                                  const char *location);
+#define tsocket_address_create_socket(addr, type, mem_ctx, sock) \
+       _tsocket_address_create_socket(addr, type, mem_ctx, sock,\
+                                      __location__)
+
+/*
+ * BSD sockets: inet, inet6 and unix
+ */
+
+int _tsocket_address_inet_from_strings(TALLOC_CTX *mem_ctx,
+                                      const char *fam,
+                                      const char *addr,
+                                      uint16_t port,
+                                      struct tsocket_address **_addr,
+                                      const char *location);
+#define tsocket_address_inet_from_strings(mem_ctx, fam, addr, port, _addr) \
+       _tsocket_address_inet_from_strings(mem_ctx, fam, addr, port, _addr, \
+                                          __location__)
+
+char *tsocket_address_inet_addr_string(const struct tsocket_address *addr,
+                                      TALLOC_CTX *mem_ctx);
+uint16_t tsocket_address_inet_port(const struct tsocket_address *addr);
+int tsocket_address_inet_set_port(struct tsocket_address *addr,
+                                 uint16_t port);
+void tsocket_address_inet_set_broadcast(struct tsocket_address *addr,
+                                       bool broadcast);
+
+int _tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx,
+                                   const char *path,
+                                   struct tsocket_address **_addr,
+                                   const char *location);
+#define tsocket_address_unix_from_path(mem_ctx, path, _addr) \
+       _tsocket_address_unix_from_path(mem_ctx, path, _addr, \
+                                       __location__)
+char *tsocket_address_unix_path(const struct tsocket_address *addr,
+                               TALLOC_CTX *mem_ctx);
+
+int _tsocket_context_bsd_wrap_existing(TALLOC_CTX *mem_ctx,
+                                      int fd, bool close_on_disconnect,
+                                      struct tsocket_context **_sock,
+                                      const char *location);
+#define tsocket_context_bsd_wrap_existing(mem_ctx, fd, cod, _sock) \
+       _tsocket_context_bsd_wrap_existing(mem_ctx, fd, cod, _sock, \
+                                          __location__)
+
+/*
+ * Async helpers
+ */
+
+struct tevent_req *tsocket_recvfrom_send(struct tsocket_context *sock,
+                                        TALLOC_CTX *mem_ctx);
+ssize_t tsocket_recvfrom_recv(struct tevent_req *req,
+                             int *perrno,
+                             TALLOC_CTX *mem_ctx,
+                             uint8_t **buf,
+                             struct tsocket_address **src);
+
+struct tevent_req *tsocket_sendto_send(struct tsocket_context *sock,
+                                      TALLOC_CTX *mem_ctx,
+                                      const uint8_t *buf,
+                                      size_t len,
+                                      const struct tsocket_address *dst);
+ssize_t tsocket_sendto_recv(struct tevent_req *req, int *perrno);
+
+struct tevent_req *tsocket_sendto_queue_send(TALLOC_CTX *mem_ctx,
+                                            struct tsocket_context *sock,
+                                            struct tevent_queue *queue,
+                                            const uint8_t *buf,
+                                            size_t len,
+                                            struct tsocket_address *dst);
+ssize_t tsocket_sendto_queue_recv(struct tevent_req *req, int *perrno);
+
+struct tevent_req *tsocket_connect_send(struct tsocket_context *sock,
+                                       TALLOC_CTX *mem_ctx,
+                                       const struct tsocket_address *dst);
+int tsocket_connect_recv(struct tevent_req *req, int *perrno);
+
+struct tevent_req *tsocket_writev_send(struct tsocket_context *sock,
+                                      TALLOC_CTX *mem_ctx,
+                                      const struct iovec *vector,
+                                      size_t count);
+int tsocket_writev_recv(struct tevent_req *req, int *perrno);
+
+struct tevent_req *tsocket_writev_queue_send(TALLOC_CTX *mem_ctx,
+                                            struct tsocket_context *sock,
+                                            struct tevent_queue *queue,
+                                            const struct iovec *vector,
+                                            size_t count);
+int tsocket_writev_queue_recv(struct tevent_req *req, int *perrno);
+
+typedef int (*tsocket_readv_next_iovec_t)(struct tsocket_context *sock,
+                                         void *private_data,
+                                         TALLOC_CTX *mem_ctx,
+                                         struct iovec **vector,
+                                         size_t *count);
+struct tevent_req *tsocket_readv_send(struct tsocket_context *sock,
+                                     TALLOC_CTX *mem_ctx,
+                                     tsocket_readv_next_iovec_t next_iovec_fn,
+                                     void *private_data);
+int tsocket_readv_recv(struct tevent_req *req, int *perrno);
+
+#endif /* _TSOCKET_H */
+
diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c
new file mode 100644 (file)
index 0000000..2811882
--- /dev/null
@@ -0,0 +1,1126 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/network.h"
+#include "tsocket.h"
+#include "tsocket_internal.h"
+
+static const struct tsocket_context_ops tsocket_context_bsd_ops;
+static const struct tsocket_address_ops tsocket_address_bsd_ops;
+
+static int tsocket_context_bsd_set_option(const struct tsocket_context *sock,
+                                         const char *option,
+                                         bool force,
+                                         const char *value);
+
+struct tsocket_context_bsd {
+       bool close_on_disconnect;
+       int fd;
+       struct tevent_fd *fde;
+};
+
+struct tsocket_address_bsd {
+       bool broadcast;
+       union {
+               struct sockaddr sa;
+               struct sockaddr_in sin;
+#ifdef HAVE_IPV6
+               struct sockaddr_in6 sin6;
+#endif
+               struct sockaddr_un sun;
+               struct sockaddr_storage ss;
+       } u;
+};
+
+static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
+                                             struct sockaddr *sa,
+                                             socklen_t sa_len,
+                                             struct tsocket_address **_addr,
+                                             const char *location)
+{
+       struct tsocket_address *addr;
+       struct tsocket_address_bsd *bsda;
+
+       switch (sa->sa_family) {
+       case AF_UNIX:
+               if (sa_len < sizeof(struct sockaddr_un)) {
+                       errno = EINVAL;
+                       return -1;
+               }
+               break;
+       case AF_INET:
+               if (sa_len < sizeof(struct sockaddr_in)) {
+                       errno = EINVAL;
+                       return -1;
+               }
+               break;
+#ifdef HAVE_IPV6
+       case AF_INET6:
+               if (sa_len < sizeof(struct sockaddr_in6)) {
+                       errno = EINVAL;
+                       return -1;
+               }
+               break;
+#endif
+       default:
+               errno = EAFNOSUPPORT;
+               return -1;
+       }
+
+       if (sa_len > sizeof(struct sockaddr_storage)) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       addr = tsocket_address_create(mem_ctx,
+                                     &tsocket_address_bsd_ops,
+                                     &bsda,
+                                     struct tsocket_address_bsd,
+                                     location);
+       if (!addr) {
+               errno = ENOMEM;
+               return -1;
+       }
+
+       ZERO_STRUCTP(bsda);
+
+       memcpy(&bsda->u.ss, sa, sa_len);
+
+       *_addr = addr;
+       return 0;
+}
+
+int _tsocket_address_inet_from_strings(TALLOC_CTX *mem_ctx,
+                                      const char *fam,
+                                      const char *addr,
+                                      uint16_t port,
+                                      struct tsocket_address **_addr,
+                                      const char *location)
+{
+       struct addrinfo hints;
+       struct addrinfo *result = NULL;
+       char port_str[6];
+       int ret;
+
+       ZERO_STRUCT(hints);
+       /*
+        * we use SOCKET_STREAM here to get just one result
+        * back from getaddrinfo().
+        */
+       hints.ai_socktype = SOCK_STREAM;
+       hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
+
+       if (strcasecmp(fam, "ip") == 0) {
+               hints.ai_family = AF_UNSPEC;
+               if (!addr) {
+#ifdef HAVE_IPV6
+                       addr = "::";
+#else
+                       addr = "0.0.0.0";
+#endif
+               }
+       } else if (strcasecmp(fam, "ipv4") == 0) {
+               hints.ai_family = AF_INET;
+               if (!addr) {
+                       addr = "0.0.0.0";
+               }
+#ifdef HAVE_IPV6
+       } else if (strcasecmp(fam, "ipv6") == 0) {
+               hints.ai_family = AF_INET6;
+               if (!addr) {
+                       addr = "::";
+               }
+#endif
+       } else {
+               errno = EAFNOSUPPORT;
+               return -1;
+       }
+
+       snprintf(port_str, sizeof(port_str) - 1, "%u", port);
+
+       ret = getaddrinfo(addr, port_str, &hints, &result);
+       if (ret != 0) {
+               switch (ret) {
+               case EAI_FAIL:
+                       errno = EINVAL;
+                       break;
+               }
+               ret = -1;
+               goto done;
+       }
+
+       if (result->ai_socktype != SOCK_STREAM) {
+               errno = EINVAL;
+               ret = -1;
+               goto done;
+       }
+
+       ret = _tsocket_address_bsd_from_sockaddr(mem_ctx,
+                                                 result->ai_addr,
+                                                 result->ai_addrlen,
+                                                 _addr,
+                                                 location);
+
+done:
+       if (result) {
+               freeaddrinfo(result);
+       }
+       return ret;
+}
+
+char *tsocket_address_inet_addr_string(const struct tsocket_address *addr,
+                                      TALLOC_CTX *mem_ctx)
+{
+       struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
+                                          struct tsocket_address_bsd);
+       char addr_str[INET6_ADDRSTRLEN+1];
+       const char *str;
+
+       if (!bsda) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       switch (bsda->u.sa.sa_family) {
+       case AF_INET:
+               str = inet_ntop(bsda->u.sin.sin_family,
+                               &bsda->u.sin.sin_addr,
+                               addr_str, sizeof(addr_str));
+               break;
+#ifdef HAVE_IPV6
+       case AF_INET6:
+               str = inet_ntop(bsda->u.sin6.sin6_family,
+                               &bsda->u.sin6.sin6_addr,
+                               addr_str, sizeof(addr_str));
+               break;
+#endif
+       default:
+               errno = EINVAL;
+               return NULL;
+       }
+
+       if (!str) {
+               return NULL;
+       }
+
+       return talloc_strdup(mem_ctx, str);
+}
+
+uint16_t tsocket_address_inet_port(const struct tsocket_address *addr)
+{
+       struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
+                                          struct tsocket_address_bsd);
+       uint16_t port = 0;
+
+       if (!bsda) {
+               errno = EINVAL;
+               return 0;
+       }
+
+       switch (bsda->u.sa.sa_family) {
+       case AF_INET:
+               port = ntohs(bsda->u.sin.sin_port);
+               break;
+#ifdef HAVE_IPV6
+       case AF_INET6:
+               port = ntohs(bsda->u.sin6.sin6_port);
+               break;
+#endif
+       default:
+               errno = EINVAL;
+               return 0;
+       }
+
+       return port;
+}
+
+int tsocket_address_inet_set_port(struct tsocket_address *addr,
+                                 uint16_t port)
+{
+       struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
+                                          struct tsocket_address_bsd);
+
+       if (!bsda) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       switch (bsda->u.sa.sa_family) {
+       case AF_INET:
+               bsda->u.sin.sin_port = htons(port);
+               break;
+#ifdef HAVE_IPV6
+       case AF_INET6:
+               bsda->u.sin6.sin6_port = htons(port);
+               break;
+#endif
+       default:
+               errno = EINVAL;
+               return -1;
+       }
+
+       return 0;
+}
+
+void tsocket_address_inet_set_broadcast(struct tsocket_address *addr,
+                                       bool broadcast)
+{
+       struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
+                                          struct tsocket_address_bsd);
+
+       if (!bsda) {
+               return;
+       }
+
+       bsda->broadcast = broadcast;
+}
+
+int _tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx,
+                                   const char *path,
+                                   struct tsocket_address **_addr,
+                                   const char *location)
+{
+       struct sockaddr_un sun;
+       void *p = &sun;
+       int ret;
+
+       if (!path) {
+               path = "";
+       }
+
+       ZERO_STRUCT(sun);
+       sun.sun_family = AF_UNIX;
+       strncpy(sun.sun_path, path, sizeof(sun.sun_path));
+
+       ret = _tsocket_address_bsd_from_sockaddr(mem_ctx,
+                                                (struct sockaddr *)p,
+                                                sizeof(sun),
+                                                _addr,
+                                                location);
+
+       return ret;
+}
+
+char *tsocket_address_unix_path(const struct tsocket_address *addr,
+                               TALLOC_CTX *mem_ctx)
+{
+       struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
+                                          struct tsocket_address_bsd);
+       const char *str;
+
+       if (!bsda) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       switch (bsda->u.sa.sa_family) {
+       case AF_UNIX:
+               str = bsda->u.sun.sun_path;
+               break;
+       default:
+               errno = EINVAL;
+               return NULL;
+       }
+
+       return talloc_strdup(mem_ctx, str);
+}
+
+static char *tsocket_address_bsd_string(const struct tsocket_address *addr,
+                                       TALLOC_CTX *mem_ctx)
+{
+       struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
+                                          struct tsocket_address_bsd);
+       char *str;
+       char *addr_str;
+       const char *prefix = NULL;
+       uint16_t port;
+
+       switch (bsda->u.sa.sa_family) {
+       case AF_UNIX:
+               return talloc_asprintf(mem_ctx, "unix:%s",
+                                      bsda->u.sun.sun_path);
+       case AF_INET:
+               prefix = "ipv4";
+               break;
+       case AF_INET6:
+               prefix = "ipv6";
+               break;
+       default:
+               errno = EINVAL;
+               return NULL;
+       }
+
+       addr_str = tsocket_address_inet_addr_string(addr, mem_ctx);
+       if (!addr_str) {
+               return NULL;
+       }
+
+       port = tsocket_address_inet_port(addr);
+
+       str = talloc_asprintf(mem_ctx, "%s:%s:%u",
+                             prefix, addr_str, port);
+       talloc_free(addr_str);
+
+       return str;
+}
+
+static struct tsocket_address *tsocket_address_bsd_copy(const struct tsocket_address *addr,
+                                                        TALLOC_CTX *mem_ctx,
+                                                        const char *location)
+{
+       struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
+                                          struct tsocket_address_bsd);
+       struct tsocket_address *copy;
+       int ret;
+
+       ret = _tsocket_address_bsd_from_sockaddr(mem_ctx,
+                                                &bsda->u.sa,
+                                                sizeof(bsda->u.ss),
+                                                &copy,
+                                                location);
+       if (ret != 0) {
+               return NULL;
+       }
+
+       tsocket_address_inet_set_broadcast(copy, bsda->broadcast);
+       return copy;
+}
+
+int _tsocket_context_bsd_wrap_existing(TALLOC_CTX *mem_ctx,
+                                      int fd, bool close_on_disconnect,
+                                      struct tsocket_context **_sock,
+                                      const char *location)
+{
+       struct tsocket_context *sock;
+       struct tsocket_context_bsd *bsds;
+
+       sock = tsocket_context_create(mem_ctx,
+                                     &tsocket_context_bsd_ops,
+                                     &bsds,
+                                     struct tsocket_context_bsd,
+                                     location);
+       if (!sock) {
+               return -1;
+       }
+
+       bsds->close_on_disconnect       = close_on_disconnect;
+       bsds->fd                        = fd;
+       bsds->fde                       = NULL;
+
+       *_sock = sock;
+       return 0;
+}
+
+static int tsocket_address_bsd_create_socket(const struct tsocket_address *addr,
+                                            enum tsocket_type type,
+                                            TALLOC_CTX *mem_ctx,
+                                            struct tsocket_context **_sock,
+                                            const char *location)
+{
+       struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
+                                          struct tsocket_address_bsd);
+       struct tsocket_context *sock;
+       int bsd_type;
+       int fd;
+       int ret;
+       bool do_bind = false;
+       bool do_reuseaddr = false;
+
+       switch (type) {
+       case TSOCKET_TYPE_STREAM:
+               if (bsda->broadcast) {
+                       errno = EINVAL;
+                       return -1;
+               }
+               bsd_type = SOCK_STREAM;
+               break;
+       case TSOCKET_TYPE_DGRAM:
+               bsd_type = SOCK_DGRAM;
+               break;
+       default:
+               errno = EPROTONOSUPPORT;
+               return -1;
+       }
+
+       switch (bsda->u.sa.sa_family) {
+       case AF_UNIX:
+               if (bsda->broadcast) {
+                       errno = EINVAL;
+                       return -1;
+               }
+               if (bsda->u.sun.sun_path[0] != 0) {
+                       do_bind = true;
+               }
+               break;
+       case AF_INET:
+               if (bsda->u.sin.sin_port != 0) {
+                       do_reuseaddr = true;
+                       do_bind = true;
+               }
+               if (bsda->u.sin.sin_addr.s_addr == INADDR_ANY) {
+                       do_bind = true;
+               }
+               break;
+#ifdef HAVE_IPV6
+       case AF_INET6:
+               if (bsda->u.sin6.sin6_port != 0) {
+                       do_reuseaddr = true;
+                       do_bind = true;
+               }
+               if (memcmp(&in6addr_any,
+                          &bsda->u.sin6.sin6_addr,
+                          sizeof(in6addr_any)) != 0) {
+                       do_bind = true;
+               }
+               break;
+#endif
+       default:
+               errno = EINVAL;
+               return -1;
+       }
+
+       fd = socket(bsda->u.sa.sa_family, bsd_type, 0);
+       if (fd < 0) {
+               return fd;
+       }
+
+       fd = tsocket_common_prepare_fd(fd, true);
+       if (fd < 0) {
+               return fd;
+       }
+
+       ret = _tsocket_context_bsd_wrap_existing(mem_ctx, fd, true,
+                                                &sock, location);
+       if (ret != 0) {
+               int saved_errno = errno;
+               close(fd);
+               errno = saved_errno;
+               return ret;
+       }
+
+       if (bsda->broadcast) {
+               ret = tsocket_context_bsd_set_option(sock, "SO_BROADCAST", true, "1");
+               if (ret != 0) {
+                       int saved_errno = errno;
+                       talloc_free(sock);
+                       errno = saved_errno;
+                       return ret;
+               }
+       }
+
+       if (do_reuseaddr) {
+               ret = tsocket_context_bsd_set_option(sock, "SO_REUSEADDR", true, "1");
+               if (ret != 0) {
+                       int saved_errno = errno;
+                       talloc_free(sock);
+                       errno = saved_errno;
+                       return ret;
+               }
+       }
+
+       if (do_bind) {
+               ret = bind(fd, &bsda->u.sa, sizeof(bsda->u.ss));
+               if (ret != 0) {
+                       int saved_errno = errno;
+                       talloc_free(sock);
+                       errno = saved_errno;
+                       return ret;
+               }
+       }
+
+       *_sock = sock;
+       return 0;
+}
+
+static const struct tsocket_address_ops tsocket_address_bsd_ops = {
+       .name           = "bsd",
+       .string         = tsocket_address_bsd_string,
+       .copy           = tsocket_address_bsd_copy,
+       .create_socket  = tsocket_address_bsd_create_socket
+};
+
+static void tsocket_context_bsd_fde_handler(struct tevent_context *ev,
+                                           struct tevent_fd *fde,
+                                           uint16_t flags,
+                                           void *private_data)
+{
+       struct tsocket_context *sock = talloc_get_type(private_data,
+                                      struct tsocket_context);
+
+       if (flags & TEVENT_FD_WRITE) {
+               sock->event.write_handler(sock, sock->event.write_private);
+               return;
+       }
+       if (flags & TEVENT_FD_READ) {
+               sock->event.read_handler(sock, sock->event.read_private);
+               return;
+       }
+}
+
+static int tsocket_context_bsd_set_event_context(struct tsocket_context *sock,
+                                                struct tevent_context *ev)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+
+       talloc_free(bsds->fde);
+       bsds->fde = NULL;
+       ZERO_STRUCT(sock->event);
+
+       if (!ev) {
+               return 0;
+       }
+
+       bsds->fde = tevent_add_fd(ev, bsds,
+                                 bsds->fd,
+                                 0,
+                                 tsocket_context_bsd_fde_handler,
+                                 sock);
+       if (!bsds->fde) {
+               if (errno == 0) {
+                       errno = ENOMEM;
+               }
+               return -1;
+       }
+
+       sock->event.ctx = ev;
+
+       return 0;
+}
+
+static int tsocket_context_bsd_set_read_handler(struct tsocket_context *sock,
+                                               tsocket_event_handler_t handler,
+                                               void *private_data)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+
+       if (sock->event.read_handler && !handler) {
+               TEVENT_FD_NOT_READABLE(bsds->fde);
+       } else if (!sock->event.read_handler && handler) {
+               TEVENT_FD_READABLE(bsds->fde);
+       }
+
+       sock->event.read_handler = handler;
+       sock->event.read_private = private_data;
+
+       return 0;
+}
+
+static int tsocket_context_bsd_set_write_handler(struct tsocket_context *sock,
+                                                tsocket_event_handler_t handler,
+                                                void *private_data)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+
+       if (sock->event.write_handler && !handler) {
+               TEVENT_FD_NOT_WRITEABLE(bsds->fde);
+       } else if (!sock->event.write_handler && handler) {
+               TEVENT_FD_WRITEABLE(bsds->fde);
+       }
+
+       sock->event.write_handler = handler;
+       sock->event.write_private = private_data;
+
+       return 0;
+}
+
+static int tsocket_context_bsd_connect_to(struct tsocket_context *sock,
+                                         const struct tsocket_address *remote)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       struct tsocket_address_bsd *bsda = talloc_get_type(remote->private_data,
+                                          struct tsocket_address_bsd);
+       int ret;
+
+       ret = connect(bsds->fd, &bsda->u.sa,
+                     sizeof(bsda->u.ss));
+
+       return ret;
+}
+
+static int tsocket_context_bsd_listen_on(struct tsocket_context *sock,
+                                         int queue_size)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       int ret;
+
+       ret = listen(bsds->fd, queue_size);
+
+       return ret;
+}
+
+static int tsocket_context_bsd_accept_new(struct tsocket_context *sock,
+                                          TALLOC_CTX *mem_ctx,
+                                          struct tsocket_context **_new_sock,
+                                          const char *location)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       int new_fd;
+       struct tsocket_context *new_sock;
+       struct tsocket_context_bsd *new_bsds;
+       struct sockaddr_storage ss;
+       void *p = &ss;
+       socklen_t ss_len = sizeof(ss);
+
+       new_fd = accept(bsds->fd, (struct sockaddr *)p, &ss_len);
+       if (new_fd < 0) {
+               return new_fd;
+       }
+
+       new_fd = tsocket_common_prepare_fd(new_fd, true);
+       if (new_fd < 0) {
+               return new_fd;
+       }
+
+       new_sock = tsocket_context_create(mem_ctx,
+                                         &tsocket_context_bsd_ops,
+                                         &new_bsds,
+                                         struct tsocket_context_bsd,
+                                         location);
+       if (!new_sock) {
+               int saved_errno = errno;
+               close(new_fd);
+               errno = saved_errno;
+               return -1;
+       }
+
+       new_bsds->close_on_disconnect   = true;
+       new_bsds->fd                    = new_fd;
+       new_bsds->fde                   = NULL;
+
+       *_new_sock = new_sock;
+       return 0;
+}
+
+static ssize_t tsocket_context_bsd_pending_data(struct tsocket_context *sock)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       int ret;
+       int value = 0;
+
+       ret = ioctl(bsds->fd, FIONREAD, &value);
+       if (ret == -1) {
+               return ret;
+       }
+
+       if (ret == 0) {
+               if (value == 0) {
+                       int error=0;
+                       socklen_t len = sizeof(error);
+                       /*
+                        * if no data is available check if the socket
+                        * is in error state. For dgram sockets
+                        * it's the way to return ICMP error messages
+                        * of connected sockets to the caller.
+                        */
+                       ret = getsockopt(bsds->fd, SOL_SOCKET, SO_ERROR,
+                                        &error, &len);
+                       if (ret == -1) {
+                               return ret;
+                       }
+                       if (error != 0) {
+                               errno = error;
+                               return -1;
+                       }
+               }
+               return value;
+       }
+
+       /* this should not be reached */
+       errno = EIO;
+       return -1;
+}
+
+static int tsocket_context_bsd_readv_data(struct tsocket_context *sock,
+                                         const struct iovec *vector,
+                                         size_t count)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       int ret;
+
+       ret = readv(bsds->fd, vector, count);
+
+       return ret;
+}
+
+static int tsocket_context_bsd_writev_data(struct tsocket_context *sock,
+                                          const struct iovec *vector,
+                                          size_t count)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       int ret;
+
+       ret = writev(bsds->fd, vector, count);
+
+       return ret;
+}
+
+static ssize_t tsocket_context_bsd_recvfrom_data(struct tsocket_context *sock,
+                                                 uint8_t *data, size_t len,
+                                                 TALLOC_CTX *addr_ctx,
+                                                 struct tsocket_address **remote)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       struct tsocket_address *addr = NULL;
+       struct tsocket_address_bsd *bsda;
+       ssize_t ret;
+       struct sockaddr *sa = NULL;
+       socklen_t sa_len = 0;
+
+       if (remote) {
+               addr = tsocket_address_create(addr_ctx,
+                                             &tsocket_address_bsd_ops,
+                                             &bsda,
+                                             struct tsocket_address_bsd,
+                                             __location__ "recvfrom");
+               if (!addr) {
+                       return -1;
+               }
+
+               ZERO_STRUCTP(bsda);
+
+               sa = &bsda->u.sa;
+               sa_len = sizeof(bsda->u.ss);
+       }
+
+       ret = recvfrom(bsds->fd, data, len, 0, sa, &sa_len);
+       if (ret < 0) {
+               int saved_errno = errno;
+               talloc_free(addr);
+               errno = saved_errno;
+               return ret;
+       }
+
+       if (remote) {
+               *remote = addr;
+       }
+       return ret;
+}
+
+static ssize_t tsocket_context_bsd_sendto_data(struct tsocket_context *sock,
+                                               const uint8_t *data, size_t len,
+                                               const struct tsocket_address *remote)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       struct sockaddr *sa = NULL;
+       socklen_t sa_len = 0;
+       ssize_t ret;
+
+       if (remote) {
+               struct tsocket_address_bsd *bsda =
+                       talloc_get_type(remote->private_data,
+                       struct tsocket_address_bsd);
+
+               sa = &bsda->u.sa;
+               sa_len = sizeof(bsda->u.ss);
+       }
+
+       ret = sendto(bsds->fd, data, len, 0, sa, sa_len);
+
+       return ret;
+}
+
+static int tsocket_context_bsd_get_status(const struct tsocket_context *sock)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       int ret;
+       int error=0;
+       socklen_t len = sizeof(error);
+
+       if (bsds->fd == -1) {
+               errno = EPIPE;
+               return -1;
+       }
+
+       ret = getsockopt(bsds->fd, SOL_SOCKET, SO_ERROR, &error, &len);
+       if (ret == -1) {
+               return ret;
+       }
+       if (error != 0) {
+               errno = error;
+               return -1;
+       }
+
+       return 0;
+}
+
+static int tsocket_context_bsd_get_local_address(const struct tsocket_context *sock,
+                                                 TALLOC_CTX *mem_ctx,
+                                                 struct tsocket_address **_addr,
+                                                 const char *location)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       struct tsocket_address *addr;
+       struct tsocket_address_bsd *bsda;
+       ssize_t ret;
+       socklen_t sa_len;
+
+       addr = tsocket_address_create(mem_ctx,
+                                     &tsocket_address_bsd_ops,
+                                     &bsda,
+                                     struct tsocket_address_bsd,
+                                     location);
+       if (!addr) {
+               return -1;
+       }
+
+       ZERO_STRUCTP(bsda);
+
+       sa_len = sizeof(bsda->u.ss);
+       ret = getsockname(bsds->fd, &bsda->u.sa, &sa_len);
+       if (ret < 0) {
+               int saved_errno = errno;
+               talloc_free(addr);
+               errno = saved_errno;
+               return ret;
+       }
+
+       *_addr = addr;
+       return 0;
+}
+
+static int tsocket_context_bsd_get_remote_address(const struct tsocket_context *sock,
+                                                  TALLOC_CTX *mem_ctx,
+                                                  struct tsocket_address **_addr,
+                                                  const char *location)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       struct tsocket_address *addr;
+       struct tsocket_address_bsd *bsda;
+       ssize_t ret;
+       socklen_t sa_len;
+
+       addr = tsocket_address_create(mem_ctx,
+                                     &tsocket_address_bsd_ops,
+                                     &bsda,
+                                     struct tsocket_address_bsd,
+                                     location);
+       if (!addr) {
+               return -1;
+       }
+
+       ZERO_STRUCTP(bsda);
+
+       sa_len = sizeof(bsda->u.ss);
+       ret = getpeername(bsds->fd, &bsda->u.sa, &sa_len);
+       if (ret < 0) {
+               int saved_errno = errno;
+               talloc_free(addr);
+               errno = saved_errno;
+               return ret;
+       }
+
+       *_addr = addr;
+       return 0;
+}
+
+static const struct tsocket_context_bsd_option {
+       const char *name;
+       int level;
+       int optnum;
+       int optval;
+} tsocket_context_bsd_options[] = {
+#define TSOCKET_OPTION(_level, _optnum, _optval) { \
+       .name = #_optnum, \
+       .level = _level, \
+       .optnum = _optnum, \
+       .optval = _optval \
+}
+       TSOCKET_OPTION(SOL_SOCKET, SO_REUSEADDR, 0),
+       TSOCKET_OPTION(SOL_SOCKET, SO_BROADCAST, 0)
+};
+
+static int tsocket_context_bsd_get_option(const struct tsocket_context *sock,
+                                         const char *option,
+                                         TALLOC_CTX *mem_ctx,
+                                         char **_value)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       const struct tsocket_context_bsd_option *opt = NULL;
+       uint32_t i;
+       int optval;
+       socklen_t optval_len = sizeof(optval);
+       char *value;
+       int ret;
+
+       for (i=0; i < ARRAY_SIZE(tsocket_context_bsd_options); i++) {
+               if (strcmp(option, tsocket_context_bsd_options[i].name) != 0) {
+                       continue;
+               }
+
+               opt = &tsocket_context_bsd_options[i];
+               break;
+       }
+
+       if (!opt) {
+               goto nosys;
+       }
+
+       ret = getsockopt(bsds->fd, opt->level, opt->optnum,
+                        (void *)&optval, &optval_len);
+       if (ret != 0) {
+               return ret;
+       }
+
+       if (optval_len != sizeof(optval)) {
+               value = NULL;
+       } if (opt->optval != 0) {
+               if (optval == opt->optval) {
+                       value = talloc_strdup(mem_ctx, "1");
+               } else {
+                       value = talloc_strdup(mem_ctx, "0");
+               }
+               if (!value) {
+                       goto nomem;
+               }
+       } else {
+               value = talloc_asprintf(mem_ctx, "%d", optval);
+               if (!value) {
+                       goto nomem;
+               }
+       }
+
+       *_value = value;
+       return 0;
+
+ nomem:
+       errno = ENOMEM;
+       return -1;
+ nosys:
+       errno = ENOSYS;
+       return -1;
+}
+
+static int tsocket_context_bsd_set_option(const struct tsocket_context *sock,
+                                         const char *option,
+                                         bool force,
+                                         const char *value)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+       const struct tsocket_context_bsd_option *opt = NULL;
+       uint32_t i;
+       int optval;
+       int ret;
+
+       for (i=0; i < ARRAY_SIZE(tsocket_context_bsd_options); i++) {
+               if (strcmp(option, tsocket_context_bsd_options[i].name) != 0) {
+                       continue;
+               }
+
+               opt = &tsocket_context_bsd_options[i];
+               break;
+       }
+
+       if (!opt) {
+               goto nosys;
+       }
+
+       if (value) {
+               if (opt->optval != 0) {
+                       errno = EINVAL;
+                       return -1;
+               }
+
+               optval = atoi(value);
+       } else {
+               optval = opt->optval;
+       }
+
+       ret = setsockopt(bsds->fd, opt->level, opt->optnum,
+                        (const void *)&optval, sizeof(optval));
+       if (ret != 0) {
+               if (!force) {
+                       errno = 0;
+                       return 0;
+               }
+               return ret;
+       }
+
+       return 0;
+
+ nosys:
+       if (!force) {
+               return 0;
+       }
+
+       errno = ENOSYS;
+       return -1;
+}
+
+static void tsocket_context_bsd_disconnect(struct tsocket_context *sock)
+{
+       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
+                                          struct tsocket_context_bsd);
+
+       tsocket_context_bsd_set_event_context(sock, NULL);
+
+       if (bsds->fd != -1) {
+               if (bsds->close_on_disconnect) {
+                       close(bsds->fd);
+               }
+               bsds->fd = -1;
+       }
+}
+
+static const struct tsocket_context_ops tsocket_context_bsd_ops = {
+       .name                   = "bsd",
+
+       .set_event_context      = tsocket_context_bsd_set_event_context,
+       .set_read_handler       = tsocket_context_bsd_set_read_handler,
+       .set_write_handler      = tsocket_context_bsd_set_write_handler,
+
+       .connect_to             = tsocket_context_bsd_connect_to,
+       .listen_on              = tsocket_context_bsd_listen_on,
+       .accept_new             = tsocket_context_bsd_accept_new,
+
+       .pending_data           = tsocket_context_bsd_pending_data,
+       .readv_data             = tsocket_context_bsd_readv_data,
+       .writev_data            = tsocket_context_bsd_writev_data,
+       .recvfrom_data          = tsocket_context_bsd_recvfrom_data,
+       .sendto_data            = tsocket_context_bsd_sendto_data,
+
+       .get_status             = tsocket_context_bsd_get_status,
+       .get_local_address      = tsocket_context_bsd_get_local_address,
+       .get_remote_address     = tsocket_context_bsd_get_remote_address,
+
+       .get_option             = tsocket_context_bsd_get_option,
+       .set_option             = tsocket_context_bsd_set_option,
+
+       .disconnect             = tsocket_context_bsd_disconnect
+};
diff --git a/lib/tsocket/tsocket_connect.c b/lib/tsocket/tsocket_connect.c
new file mode 100644 (file)
index 0000000..7a9d4b8
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/network.h"
+#include "tsocket.h"
+#include "tsocket_internal.h"
+
+struct tsocket_connect_state {
+       /* this structs are owned by the caller */
+       struct {
+               struct tsocket_context *sock;
+               const struct tsocket_address *dst;
+       } caller;
+};
+
+static void tsocket_connect_handler(struct tsocket_context *sock,
+                                   void *private_data);
+
+struct tevent_req *tsocket_connect_send(struct tsocket_context *sock,
+                                       TALLOC_CTX *mem_ctx,
+                                       const struct tsocket_address *dst)
+{
+       struct tevent_req *req;
+       struct tsocket_connect_state *state;
+       int ret;
+       int err;
+       bool retry;
+       bool dummy;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct tsocket_connect_state);
+       if (!req) {
+               return NULL;
+       }
+
+       state->caller.sock      = sock;
+       state->caller.dst       = dst;
+
+       ret = tsocket_connect(state->caller.sock,
+                             state->caller.dst);
+       err = tsocket_error_from_errno(ret, errno, &retry);
+       if (retry) {
+               /* retry later */
+               goto async;
+       }
+       if (tevent_req_error(req, err)) {
+               goto post;
+       }
+
+       tevent_req_done(req);
+       goto post;
+
+ async:
+       ret = tsocket_set_readable_handler(state->caller.sock,
+                                          tsocket_connect_handler,
+                                          req);
+       err = tsocket_error_from_errno(ret, errno, &dummy);
+       if (tevent_req_error(req, err)) {
+               goto post;
+       }
+
+       return req;
+
+ post:
+       return tevent_req_post(req, sock->event.ctx);
+}
+
+static void tsocket_connect_handler(struct tsocket_context *sock,
+                                   void *private_data)
+{
+       struct tevent_req *req = talloc_get_type(private_data,
+                                struct tevent_req);
+       struct tsocket_connect_state *state = tevent_req_data(req,
+                                             struct tsocket_connect_state);
+       int ret;
+       int err;
+       bool retry;
+
+       ret = tsocket_get_status(state->caller.sock);
+       err = tsocket_error_from_errno(ret, errno, &retry);
+       if (retry) {
+               /* retry later */
+               return;
+       }
+       if (tevent_req_error(req, err)) {
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+int tsocket_connect_recv(struct tevent_req *req, int *perrno)
+{
+       int ret;
+
+       ret = tsocket_simple_int_recv(req, perrno);
+
+       tevent_req_received(req);
+       return ret;
+}
+
diff --git a/lib/tsocket/tsocket_guide.txt b/lib/tsocket/tsocket_guide.txt
new file mode 100644 (file)
index 0000000..a02fa37
--- /dev/null
@@ -0,0 +1,503 @@
+
+Basic design of the tsocket abstraction
+=======================================
+
+The tsocket layer is designed to match more or less
+the bsd socket layer, but it hides the filedescriptor
+within a opaque 'tsocket_context' structure to make virtual
+sockets possible. The virtual sockets can be encrypted tunnels
+(like TLS, SASL or GSSAPI) or named pipes over smb.
+
+The tsocket layer is a bit like an abstract class, which defines
+common methods to work with sockets in a non blocking fashion.
+
+The whole library is based on the talloc(3) and 'tevent' libraries.
+
+The 'tsocket_address' structure is the 2nd abstracted class
+which represends the address of a socket endpoint.
+
+Each different type of socket has its own constructor.
+
+Typically the constructor for a tsocket_context is attached to
+the tsocket_address of the source endpoint. That means
+the tsocket_address_create_socket() function takes the
+tsocket_address of the local endpoint and creates a tsocket_context
+for the communication.
+
+For some usecases it's possible to wrap an existing socket into a
+tsocket_context, e.g. to wrap an existing pipe(2) into
+tsocket_context, so that you can use the same functions to
+communicate over the pipe.
+
+The tsocket_address abstraction
+===============================
+
+The tsocket_address represents an socket endpoint genericly.
+As it's like an abstract class it has no specific constructor.
+The specific constructors are descripted later sections.
+
+There's a function get the string representation of the
+endpoint for debugging. Callers should not try to parse
+the string! The should use additional methods of the specific
+tsocket_address implemention to get more details.
+
+   char *tsocket_address_string(const struct tsocket_address *addr,
+                                TALLOC_CTX *mem_ctx);
+
+There's a function to create a copy of the tsocket_address.
+This is useful when before doing modifications to a socket
+via additional methods of the specific tsocket_address implementation.
+
+   struct tsocket_address *tsocket_address_copy(const struct tsocket_address *addr,
+                                                TALLOC_CTX *mem_ctx);
+
+There's a function to create a tsocket_context based on the given local
+socket endpoint. The return value is 0 on success and -1 on failure
+with errno holding the specific error. Specific details are descripted in later
+sections. Note not all specific implementation have to implement all socket
+types.
+
+   enum tsocket_type {
+        TSOCKET_TYPE_STREAM = 1,
+        TSOCKET_TYPE_DGRAM,
+        TSOCKET_TYPE_MESSAGE
+   };
+
+   int tsocket_address_create_socket(const struct tsocket_address *addr,
+                                     enum tsocket_type type,
+                                     TALLOC_CTX *mem_ctx,
+                                     struct tsocket_context **sock);
+
+The tsocket_context abstraction
+===============================
+
+The tsocket_context is like an abstract class and represents
+a socket similar to bsd style sockets. The methods are more
+or less equal to the bsd socket api, while the filedescriptor
+is replaced by tsocket_context and sockaddr, socklen_t pairs
+are replaced by tsocket_address. The 'bind' operation happens
+in the specific constructor as the constructor is typically based
+on tsocket_address of local socket endpoint.
+
+All operations are by design non blocking and can return error
+values like EAGAIN, EINPROGRESS, EWOULDBLOCK or EINTR which
+indicate that the caller should retry the operation later.
+Also read the "The glue to tevent" section.
+
+The socket can of types:
+ - TSOCKET_TYPE_STREAM is the equivalent to SOCK_STREAM in the bsd socket api.
+ - TSOCKET_TYPE_DGRAM is the equivalent to SOCK_DGRAM in the bsd socket api.
+ - TSOCKET_TYPE_MESSAGE operates on a connected socket and is therefore
+   like TSOCKET_TYPE_STREAM, but the consumer needs to first read all
+   data of a message, which was generated by one message 'write' on the sender,
+   before the consumer gets data of the next message. This matches a bit
+   like message mode pipes on windows. The concept is to transfer ordered
+   messages between to endpoints.
+
+There's a function to connect to a remote endpoint. The behavior
+and error codes match the connect(2) function of the bsd socket api.
+Maybe the specific tsocket_context implementation speficied some
+further details.
+
+   int tsocket_connect(struct tsocket_context *sock,
+                       const struct tsocket_address *remote_addr);
+
+There's a function to listen for incoming connections. The behavior
+and error codes match the listen(2) function of the bsd socket api.
+Maybe the specific tsocket_context implementation speficied some
+further details.
+
+   int tsocket_listen(struct tsocket_context *sock,
+                      int queue_size);
+
+There's a function to accept incoming connections. The behavior
+and error codes match the accept(2) function of the bsd socket api.
+Maybe the specific tsocket_context implementation speficied some
+further details.
+
+   int tsocket_accept(struct tsocket_context *sock,
+                      TALLOC_CTX *mem_ctx,
+                      struct tsocket_context **new_sock);
+
+There's a function to ask how many bytes are in input buffer
+of the connection. For sockets of type TSOCKET_TYPE_DGRAM or
+TSOCKET_TYPE_MESSAGE the size of the next available dgram/message
+is returned. A return value of -1 indicates a socket error
+and errno will hold the specific error code. If no data
+is available 0 is returned, but retry error codes like
+EINTR can also be returned.
+
+   ssize_t tsocket_pending(struct tsocket_context *sock);
+
+There's a function to read data from the socket. The behavior
+and error codes match the readv(3) function, also take a look
+at the recv(2) function of the bsd socket api.
+Maybe the specific tsocket_context implementation speficied some
+further details.
+
+   int tsocket_readv(struct tsocket_context *sock,
+                     const struct iovec *vector, size_t count);
+
+There's a function to write data from the socket. The behavior
+and error codes match the writev(3) function, also take a look
+at the send(2) function of the bsd socket api.
+Maybe the specific tsocket_context implementation speficied some
+further details.
+
+   int tsocket_writev(struct tsocket_context *sock,
+                      const struct iovec *vector, size_t count);
+
+There's a function to read a datagram from a remote endpoint.
+The behavior and error codes match the recvfrom(2) function of
+the bsd socket api. As TSOCKET_TYPE_DGRAM sockets can also be
+used in connected mode src_addr can be NULL, if the caller don't
+want to get the source address. Maybe the specific tsocket_context
+implementation speficied some further details.
+
+   ssize_t tsocket_recvfrom(struct tsocket_context *sock,
+                            uint8_t *data, size_t len,
+                            TALLOC_CTX *addr_ctx,
+                            struct tsocket_address **src_addr);
+
+There's a function to send a datagram to a remote endpoint the socket.
+The behavior and error codes match the recvfrom(2) function of the
+bsd socket api. As TSOCKET_TYPE_DGRAM sockets can also be used in
+connected mode dest_addr must be NULL in connected mode and a valid
+tsocket_address otherwise. Maybe the specific tsocket_context
+implementation speficied some further details.
+
+   ssize_t tsocket_sendto(struct tsocket_context *sock,
+                          const uint8_t *data, size_t len,
+                          const struct tsocket_address *dest_addr);
+
+There's a function to get the current status of the socket.
+The behavior and error codes match the getsockopt(2) function
+of the bsd socket api, with SOL_SOCKET and SO_ERROR as arguments.
+Maybe the specific tsocket_context implementation speficied some
+further details.
+
+   int tsocket_get_status(const struct tsocket_context *sock);
+
+There's a function to get tsocket_address of the local endpoint.
+The behavior and error codes match the getsockname(2) function
+of the bsd socket api. Maybe the specific tsocket_context
+implementation speficied some further details.
+
+   int tsocket_get_local_address(const struct tsocket_context *sock,
+                                 TALLOC_CTX *mem_ctx,
+                                 struct tsocket_address **local_addr);
+
+There's a function to get tsocket_address of the remote endpoint
+of a connected socket. The behavior and error codes match the
+getpeername(2) function of the bsd socket api. Maybe the specific
+tsocket_context implementation speficied some further details.
+
+   int tsocket_get_remote_address(const struct tsocket_context *sock,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct tsocket_address **remote_addr,
+                                  const char *location);
+
+There's a function to ask for specific options of the socket.
+The behavior and error codes match the getsockopt(2) function
+of the bsd socket api. The option and value are represented as string
+values, where the 'value' parameter can be NULL is the caller don't want to
+get the value. The supported options and values are up to the specific
+tsocket_context implementation.
+
+   int tsocket_get_option(const struct tsocket_context *sock,
+                          const char *option,
+                          TALLOC_CTX *mem_ctx,
+                          char **value);
+
+There's a function to set specific options of the socket.
+The behavior and error codes match the setsockopt(2) function
+of the bsd socket api. The option and value are represented as string
+values, where the 'value' parameter can be NULL. The supported options
+and values are up to the specific tsocket_context implementation.
+The 'force' parameter specifies whether an error should be returned
+for unsupported options.
+
+   int tsocket_set_option(const struct tsocket_context *sock,
+                          const char *option,
+                          bool force,
+                          const char *value);
+
+There's a function to disconnect the socket. The behavior
+and error codes match the close(2) function of the bsd socket api.
+Maybe the specific tsocket_context implementation speficied some
+further details.
+
+   void tsocket_disconnect(struct tsocket_context *sock);
+
+The glue to tevent
+==================
+
+As the tsocket library is based on the tevent library,
+there need to be functions to let the caller register
+callback functions, which are triggered when the socket
+is writeable or readable. Typically one would use
+tevent fd events, but in order to hide the filedescriptor
+the tsocket_context abstraction has their own functions.
+
+There's a function to set the currently active tevent_context
+for the socket. It's important there's only one tevent_context
+actively used with the socket. A second call will cancel
+all low level events made on the old tevent_context, it will
+also resets the send and recv handlers to NULL. If the caller
+sets attaches a new event context to the socket, the callback
+function also need to be registered again. It's important
+that the caller keeps the given tevent_context in memory
+and actively calls tsocket_set_event_context(sock, NULL)
+before calling talloc_free(event_context).
+The function returns 0 on success and -1 together with an errno
+on failure.
+
+   int tsocket_set_event_context(struct tsocket_context *sock,
+                                 struct tevent_context *ev);
+
+There's a function to register a callback function which is called
+when the socket is readable. If the caller don't want to get notified
+anymore the function should be called with NULL as handler.
+The function returns 0 on success and -1 together with an errno
+on failure.
+
+   typedef void (*tsocket_event_handler_t)(struct tsocket_context *, void *);
+   int tsocket_set_readable_handler(struct tsocket_context *sock,
+                                    tsocket_event_handler_t handler,
+                                    void *private_data);
+
+There's a function to register a callback function which is called
+when the socket is writeable. If the caller don't want to get notified
+anymore the function should be called with NULL as handler.
+The function returns 0 on success and -1 together with an errno
+on failure.
+
+   typedef void (*tsocket_event_handler_t)(struct tsocket_context *, void *);
+   int tsocket_set_writeable_handler(struct tsocket_context *sock,
+                                     tsocket_event_handler_t handler,
+                                     void *private_data);
+
+Note: if the socket is readable and writeable, only the writeable
+      handler is called, this avoids deadlocks at the application level.
+
+Async helper functions
+======================
+
+To make the life easier for the callers, there're 'tevent_req' based
+helper functions for non-blocking io-operations. For each of this functions
+to work the caller must attach the tevent_context to the tsocket_context
+with tsocket_set_event_context(). Please remember that attching a new
+tevent_context will reset the event state of the socket and should only
+be done, when there's no async request is pending on the socket!
+
+The detailed calling conventions for 'tevent_req' based programming
+will be explained in the 'tevent' documentation.
+
+To receive the next availabe datagram from socket there's a wrapper
+for tsocket_recvfrom(). The caller virtually sends its desire to receive
+the next available datagram by calling the tsocket_recvfrom_send() function
+and attaches a callback function to the returned tevent_req via tevent_req_set_callback().
+The callback function is called when a datagram is available or an error has happened.
+The callback function needs to get the result by calling
+tsocket_recvfrom_recv(). The return value of tsocket_recvfrom_recv()
+matches the return value from tsocket_recvfrom(). A possible errno is delivered
+via the perrno parameter instead of the global errno variable. The datagram
+buffer and optional the source tsocket_address of the datagram are returned as talloc
+childs of the mem_ctx passed to tsocket_recvfrom_recv().
+It's important that the caller garanties that there's only one async
+read request on the socket at a time.
+
+   struct tevent_req *tsocket_recvfrom_send(struct tsocket_context *sock,
+                                            TALLOC_CTX *mem_ctx);
+   ssize_t tsocket_recvfrom_recv(struct tevent_req *req,
+                                 int *perrno,
+                                 TALLOC_CTX *mem_ctx,
+                                 uint8_t **buf,
+                                 struct tsocket_address **src);
+
+To send a datagram there's a wrapper for tsocket_sendto().
+The caller calls tsocket_sendto_send() instead of tsocket_sendto()
+which returns a tevent_req allocated on the given TALLOC_CTX.
+The caller attaches a callback function to the returned tevent_req via
+tevent_req_set_callback(). The callback function is called when a datagram was
+deliviered into the socket or an error has happened.
+The callback function needs to get the result by calling
+tsocket_sendto_recv(). The return value of tsocket_sendto_recv()
+matches the return value from tsocket_sendto(). A possible errno is delivered
+via the perrno parameter instead of the global errno variable.
+Normal callers should not use this function directly, they should use
+tsocket_sendto_queue_send/recv() instead.
+
+   struct tevent_req *tsocket_sendto_send(struct tsocket_context *sock,
+                                          TALLOC_CTX *mem_ctx,
+                                          const uint8_t *buf,
+                                          size_t len,
+                                          const struct tsocket_address *dst);
+   ssize_t tsocket_sendto_recv(struct tevent_req *req, int *perrno);
+
+As only one async tsocket_sendto() call should happen at a time,
+there's a 'tevent_queue' is used to serialize the sendto requests.
+
+   struct tevent_req *tsocket_sendto_queue_send(TALLOC_CTX *mem_ctx,
+                                                struct tsocket_context *sock,
+                                                struct tevent_queue *queue,
+                                                const uint8_t *buf,
+                                                size_t len,
+                                                struct tsocket_address *dst);
+   ssize_t tsocket_sendto_queue_recv(struct tevent_req *req, int *perrno);
+
+Ther's an async helper for tsocket_connect(), which should be used
+to connect TSOCKET_TYPE_STREAM based sockets.
+The caller virtually sends its desire to connect to the destination
+tsocket_address by calling tsocket_connect_send() and gets back a tevent_req.
+The caller sets a callback function via tevent_req_set_callback().
+The callback function is called if the tsocket is connected or an error has happened.
+The callback function needs to get the result by calling
+tsocket_connect_recv(). The return value of tsocket_connect_recv()
+matches the return value from tsocket_connect()/tsocket_get_status().
+A possible errno is delivered via the perrno parameter instead of the global
+errno variable.
+
+   struct tevent_req *tsocket_connect_send(struct tsocket_context *sock,
+                                           TALLOC_CTX *mem_ctx,
+                                           const struct tsocket_address *dst);
+   int tsocket_connect_recv(struct tevent_req *req, int *perrno);
+
+To send an 'iovec' there's a wrapper for tsocket_writev().
+The caller calls tsocket_writev_send() instead of tsocket_writev()
+which returns a tevent_req allocated on the given TALLOC_CTX.
+The caller attaches a callback function to the returned tevent_req via
+tevent_req_set_callback(). The callback function is called when the whole iovec
+was deliviered into the socket or an error has happened.
+The callback function needs to get the result by calling
+tsocket_writev_recv(). The return value of tsocket_writev_recv()
+matches the return value from tsocket_writev(). A possible errno is delivered
+via the perrno parameter instead of the global errno variable.
+Normal callers should not use this function directly, they should use
+tsocket_writev_queue_send/recv() instead.
+
+   struct tevent_req *tsocket_writev_send(struct tsocket_context *sock,
+                                          TALLOC_CTX *mem_ctx,
+                                          const struct iovec *vector,
+                                          size_t count);
+   int tsocket_writev_recv(struct tevent_req *req, int *perrno);
+
+As only one async tsocket_writev() call should happen at a time,
+there's a 'tevent_queue' is used to serialize the writev requests.
+
+   struct tevent_req *tsocket_writev_queue_send(TALLOC_CTX *mem_ctx,
+                                                struct tsocket_context *sock,
+                                                struct tevent_queue *queue,
+                                                const struct iovec *vector,
+                                                size_t count);
+   int tsocket_writev_queue_recv(struct tevent_req *req, int *perrno);
+
+For TSOCKET_TYPE_STREAM sockets, it's typically desired to split the stream
+into PDUs. That's why the helper function for tsocket_readv() is a bit
+different compared to the other helper functions. The general rule
+is still to get a tevent_req, set a callback which gets called when the
+operation is done. The callback function needs to get the result by
+calling tsocket_readv_recv(). The 'next_iovec' callback function
+makes the difference to the other helper function.
+The tsocket_writev_send/recv() logic asks the caller via the
+next_iovec_fn for an iovec array, which will be filled completely
+with bytes from the socket, then the next_iovec_fn is called for
+the next iovec array to fill, untill the next_iovec_fn returns an empty
+iovec array. That next_iovec_fn should allocate the array as child of the
+passed mem_ctx, while the buffers the array referr to belong to the caller.
+The tsocket_writev_send/recv() engine will modify and free the given array!
+The basic idea is that the caller allocates and maintains the real buffers.
+The next_iovec_fn should report error by returning -1 and setting errno to
+the specific error code. The engine will pass the error to the caller
+via tsocket_readv_recv().
+
+typedef int (*tsocket_readv_next_iovec_t)(struct tsocket_context *sock,
+                                         void *private_data,
+                                         TALLOC_CTX *mem_ctx,
+                                         struct iovec **vector,
+                                         size_t *count);
+struct tevent_req *tsocket_readv_send(struct tsocket_context *sock,
+                                     TALLOC_CTX *mem_ctx,
+                                     tsocket_readv_next_iovec_t next_iovec_fn,
+                                     void *private_data);
+int tsocket_readv_recv(struct tevent_req *req, int *perrno);
+
+Wrapper for BSD style sockets
+=============================
+
+Support for BSD style sockets of AF_INET, AF_INET6 and AF_UNIX
+are part of the main tsocket library.
+
+To wrap an existing fd into a tsocket_context the function
+tsocket_context_bsd_wrap_existing() can be used.
+The caller needs to make sure the fd is marked as non-blocking!
+Normaly the tsocket_disconnect() function would close the fd,
+but the caller can influence this behavior based on the close_on_disconnect
+parameter. The caller should also make sure that the socket is only
+accessed via the tsocket_context wrapper after the call to
+tsocket_context_bsd_wrap_existing().
+
+   int tsocket_context_bsd_wrap_existing(TALLOC_CTX *mem_ctx,
+                                         int fd, bool close_on_disconnect,
+                                         struct tsocket_context **_sock);
+
+To create a tsocket_address for an inet address you need to use
+the tsocket_address_inet_from_strings() function. It takes the family
+as parameter which can be "ipv4", "ipv6" or "ip", where "ip" autodetects
+"ipv4" or "ipv6", based on the given address string. Depending on the
+operating system, "ipv6" may not be supported. Note: NULL as address
+is mapped to "0.0.0.0" or "::" based on the given family.
+The address parameter only accepts valid ipv4 or ipv6 address strings
+and no names! The caller need to resolve names before using this function.
+
+   int tsocket_address_inet_from_strings(TALLOC_CTX *mem_ctx,
+                                         const char *family,
+                                         const char *address,
+                                         uint16_t port,
+                                         struct tsocket_address **addr);
+
+To get the address of the inet tsocket_address as string the
+tsocket_address_inet_addr_string() function should be used.
+The caller should not try to parse the tsocket_address_string() output!
+
+   char *tsocket_address_inet_addr_string(const struct tsocket_address *addr,
+                                          TALLOC_CTX *mem_ctx);
+
+To get the port number of the inet tsocket_address the
+tsocket_address_inet_port() function should be used.
+The caller should not try to parse the tsocket_address_string() output!
+
+   uint16_t tsocket_address_inet_port(const struct tsocket_address *addr);
+
+To alter the port number of an inet tsocket_address the
+tsocket_address_inet_set_port() function can be used.
+This is usefull if the caller gets the address from
+tsocket_address_copy(), tsocket_context_remote_address() or
+tsocket_context_remote_address() instead of tsocket_address_inet_from_strings().
+
+   int tsocket_address_inet_set_port(struct tsocket_address *addr,
+                                     uint16_t port);
+
+If the caller wants to create a broadcast socket, with the SO_BROADCAST
+socket option, the broadcast option needs to be set with the
+tsocket_address_inet_set_broadcast() function before calling
+tsocket_address_create_socket().
+
+   void tsocket_address_inet_set_broadcast(struct tsocket_address *addr,
+                                           bool broadcast);
+
+To create a tsocket_address for AF_UNIX style sockets the
+tsocket_address_unix_from_path() should be used.
+NULL as path is handled like "".
+
+   int tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx,
+                                      const char *path,
+                                      struct tsocket_address **addr);
+
+To get the unix path of an existing unix tsocket_address
+the tsocket_address_unix_path() should be used.
+The caller should not try to parse the tsocket_address_string() output!
+
+   char *tsocket_address_unix_path(const struct tsocket_address *addr,
+                                   TALLOC_CTX *mem_ctx);
+
diff --git a/lib/tsocket/tsocket_helpers.c b/lib/tsocket/tsocket_helpers.c
new file mode 100644 (file)
index 0000000..b2edf43
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/network.h"
+#include "system/filesys.h"
+#include "tsocket.h"
+#include "tsocket_internal.h"
+
+int tsocket_error_from_errno(int ret,
+                            int sys_errno,
+                            bool *retry)
+{
+       *retry = false;
+
+       if (ret >= 0) {
+               return 0;
+       }
+
+       if (ret != -1) {
+               return EIO;
+       }
+
+       if (sys_errno == 0) {
+               return EIO;
+       }
+
+       if (sys_errno == EINTR) {
+               *retry = true;
+               return sys_errno;
+       }
+
+       if (sys_errno == EINPROGRESS) {
+               *retry = true;
+               return sys_errno;
+       }
+
+       if (sys_errno == EAGAIN) {
+               *retry = true;
+               return sys_errno;
+       }
+
+#ifdef EWOULDBLOCK
+       if (sys_errno == EWOULDBLOCK) {
+               *retry = true;
+               return sys_errno;
+       }
+#endif
+
+       return sys_errno;
+}
+
+int tsocket_simple_int_recv(struct tevent_req *req, int *perrno)
+{
+       enum tevent_req_state state;
+       uint64_t error;
+
+       if (!tevent_req_is_error(req, &state, &error)) {
+               return 0;
+       }
+
+       switch (state) {
+       case TEVENT_REQ_NO_MEMORY:
+               *perrno = ENOMEM;
+               return -1;
+       case TEVENT_REQ_TIMED_OUT:
+               *perrno = ETIMEDOUT;
+               return -1;
+       case TEVENT_REQ_USER_ERROR:
+               *perrno = (int)error;
+               return -1;
+       default:
+               *perrno = EIO;
+               return -1;
+       }
+
+       *perrno = EIO;
+       return -1;
+}
+
+int tsocket_common_prepare_fd(int fd, bool high_fd)
+{
+       int i;
+       int sys_errno = 0;
+       int fds[3];
+       int num_fds = 0;
+
+       int result, flags;
+
+       if (fd == -1) {
+               return -1;
+       }
+
+       /* first make a fd >= 3 */
+       if (high_fd) {
+               while (fd < 3) {
+                       fds[num_fds++] = fd;
+                       fd = dup(fd);
+                       if (fd == -1) {
+                               sys_errno = errno;
+                               break;
+                       }
+               }
+               for (i=0; i<num_fds; i++) {
+                       close(fds[i]);
+               }
+               if (fd == -1) {
+                       errno = sys_errno;
+                       return fd;
+               }
+       }
+
+       /* fd should be nonblocking. */
+
+#ifdef O_NONBLOCK
+#define FLAG_TO_SET O_NONBLOCK
+#else
+#ifdef SYSV
+#define FLAG_TO_SET O_NDELAY
+#else /* BSD */
+#define FLAG_TO_SET FNDELAY
+#endif
+#endif
+
+       if ((flags = fcntl(fd, F_GETFL)) == -1) {
+               goto fail;
+       }
+
+       flags |= FLAG_TO_SET;
+       if (fcntl(fd, F_SETFL, flags) == -1) {
+               goto fail;
+       }
+
+#undef FLAG_TO_SET
+
+       /* fd should be closed on exec() */
+#ifdef FD_CLOEXEC
+       result = flags = fcntl(fd, F_GETFD, 0);
+       if (flags >= 0) {
+               flags |= FD_CLOEXEC;
+               result = fcntl(fd, F_SETFD, flags);
+       }
+       if (result < 0) {
+               goto fail;
+       }
+#endif
+       return fd;
+
+ fail:
+       if (fd != -1) {
+               sys_errno = errno;
+               close(fd);
+               errno = sys_errno;
+       }
+       return -1;
+}
+
diff --git a/lib/tsocket/tsocket_internal.h b/lib/tsocket/tsocket_internal.h
new file mode 100644 (file)
index 0000000..e4a4908
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _TSOCKET_INTERNAL_H
+#define _TSOCKET_INTERNAL_H
+
+struct tsocket_context_ops {
+       const char *name;
+
+       /* event handling */
+       int (*set_event_context)(struct tsocket_context *sock,
+                                struct tevent_context *ev);
+       int (*set_read_handler)(struct tsocket_context *sock,
+                               tsocket_event_handler_t handler,
+                               void *private_data);
+       int (*set_write_handler)(struct tsocket_context *sock,
+                                tsocket_event_handler_t handler,
+                                void *private_data);
+
+       /* client ops */
+       int (*connect_to)(struct tsocket_context *sock,
+                         const struct tsocket_address *remote_addr);
+
+       /* server ops */
+       int (*listen_on)(struct tsocket_context *sock,
+                        int queue_size);
+       int (*accept_new)(struct tsocket_context *sock,
+                         TALLOC_CTX *mem_ctx,
+                         struct tsocket_context **new_sock,
+                         const char *location);
+
+       /* general ops */
+       ssize_t (*pending_data)(struct tsocket_context *sock);
+
+       int (*readv_data)(struct tsocket_context *sock,
+                         const struct iovec *vector, size_t count);
+       int (*writev_data)(struct tsocket_context *sock,
+                          const struct iovec *vector, size_t count);
+
+       ssize_t (*recvfrom_data)(struct tsocket_context *sock,
+                                uint8_t *data, size_t len,
+                                TALLOC_CTX *addr_ctx,
+                                struct tsocket_address **remote_addr);
+       ssize_t (*sendto_data)(struct tsocket_context *sock,
+                              const uint8_t *data, size_t len,
+                              const struct tsocket_address *remote_addr);
+
+       /* info */
+       int (*get_status)(const struct tsocket_context *sock);
+       int (*get_local_address)(const struct tsocket_context *sock,
+                               TALLOC_CTX *mem_ctx,
+                               struct tsocket_address **local_addr,
+                               const char *location);
+       int (*get_remote_address)(const struct tsocket_context *sock,
+                                 TALLOC_CTX *mem_ctx,
+                                 struct tsocket_address **remote_addr,
+                                 const char *location);
+
+       /* options */
+       int (*get_option)(const struct tsocket_context *sock,
+                         const char *option,
+                         TALLOC_CTX *mem_ctx,
+                         char **value);
+       int (*set_option)(const struct tsocket_context *sock,
+                         const char *option,
+                         bool force,
+                         const char *value);
+
+       /* close/disconnect */
+       void (*disconnect)(struct tsocket_context *sock);
+};
+
+struct tsocket_context {
+       const char *location;
+       const struct tsocket_context_ops *ops;
+
+       void *private_data;
+
+       struct {
+               struct tevent_context *ctx;
+               void *read_private;
+               tsocket_event_handler_t read_handler;
+               void *write_private;
+               tsocket_event_handler_t write_handler;
+       } event;
+};
+
+struct tsocket_context *_tsocket_context_create(TALLOC_CTX *mem_ctx,
+                                       const struct tsocket_context_ops *ops,
+                                       void *pstate,
+                                       size_t psize,
+                                       const char *type,
+                                       const char *location);
+#define tsocket_context_create(mem_ctx, ops, state, type, location) \
+       _tsocket_context_create(mem_ctx, ops, state, sizeof(type), \
+                               #type, location)
+
+struct tsocket_address_ops {
+       const char *name;
+
+       char *(*string)(const struct tsocket_address *addr,
+                       TALLOC_CTX *mem_ctx);
+
+       struct tsocket_address *(*copy)(const struct tsocket_address *addr,
+                                       TALLOC_CTX *mem_ctx,
+                                       const char *location);
+
+       int (*create_socket)(const struct tsocket_address *addr,
+                            enum tsocket_type,
+                            TALLOC_CTX *mem_ctx,
+                            struct tsocket_context **sock,
+                            const char *location);
+};
+
+struct tsocket_address {
+       const char *location;
+       const struct tsocket_address_ops *ops;
+
+       void *private_data;
+};
+
+struct tsocket_address *_tsocket_address_create(TALLOC_CTX *mem_ctx,
+                                       const struct tsocket_address_ops *ops,
+                                       void *pstate,
+                                       size_t psize,
+                                       const char *type,
+                                       const char *location);
+#define tsocket_address_create(mem_ctx, ops, state, type, location) \
+       _tsocket_address_create(mem_ctx, ops, state, sizeof(type), \
+                               #type, location)
+
+int tsocket_error_from_errno(int ret, int sys_errno, bool *retry);
+int tsocket_simple_int_recv(struct tevent_req *req, int *perrno);
+int tsocket_common_prepare_fd(int fd, bool high_fd);
+
+#endif /* _TSOCKET_H */
+
diff --git a/lib/tsocket/tsocket_readv.c b/lib/tsocket/tsocket_readv.c
new file mode 100644 (file)
index 0000000..2c8483e
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/network.h"
+#include "tsocket.h"
+#include "tsocket_internal.h"
+
+struct tsocket_readv_state {
+       /* this structs are owned by the caller */
+       struct {
+               struct tsocket_context *sock;
+               tsocket_readv_next_iovec_t next_iovec_fn;
+               void *private_data;
+       } caller;
+
+       /*
+        * Each call to the callback resets iov and count
+        * the callback allocated the iov as child of our state,
+        * that means we are allowed to modify and free it.
+        *
+        * we should call the callback every time we filled the given
+        * vector and ask for a new vector. We return if the callback
+        * ask for 0 bytes.
+        */
+       struct iovec *iov;
+       size_t count;
+
+       /*
+        * the total number of bytes we read,
+        * the return value of the _recv function
+        */
+       int total_read;
+};
+
+static int tsocket_readv_state_destructor(struct tsocket_readv_state *state)
+{
+       if (state->caller.sock) {
+               tsocket_set_readable_handler(state->caller.sock, NULL, NULL);
+       }
+       ZERO_STRUCT(state->caller);
+
+       return 0;
+}
+
+static bool tsocket_readv_ask_for_next_vector(struct tevent_req *req,
+                                             struct tsocket_readv_state *state)
+{
+       int ret;
+       int err;
+       bool dummy;
+       size_t to_read = 0;
+       size_t i;
+
+       talloc_free(state->iov);
+       state->iov = NULL;
+       state->count = 0;
+
+       ret = state->caller.next_iovec_fn(state->caller.sock,
+                                         state->caller.private_data,
+                                         state, &state->iov, &state->count);
+       err = tsocket_error_from_errno(ret, errno, &dummy);
+       if (tevent_req_error(req, err)) {
+               return false;
+       }
+
+       for (i=0; i < state->count; i++) {
+               size_t tmp = to_read;
+               tmp += state->iov[i].iov_len;
+
+               if (tmp < to_read) {
+                       tevent_req_error(req, EMSGSIZE);
+                       return false;
+               }
+
+               to_read = tmp;
+       }
+
+       if (to_read == 0) {
+               tevent_req_done(req);
+               return false;
+       }
+
+       if (state->total_read + to_read < state->total_read) {
+               tevent_req_error(req, EMSGSIZE);
+               return false;
+       }
+
+       return true;
+}
+
+static void tsocket_readv_handler(struct tsocket_context *sock,
+                                 void *private_data);
+
+struct tevent_req *tsocket_readv_send(struct tsocket_context *sock,
+                                     TALLOC_CTX *mem_ctx,
+                                     tsocket_readv_next_iovec_t next_iovec_fn,
+                                     void *private_data)
+{
+       struct tevent_req *req;
+       struct tsocket_readv_state *state;
+       int ret;
+       int err;
+       bool dummy;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct tsocket_readv_state);
+       if (!req) {
+               return NULL;
+       }
+
+       state->caller.sock              = sock;
+       state->caller.next_iovec_fn     = next_iovec_fn;
+       state->caller.private_data      = private_data;
+
+       state->iov              = NULL;
+       state->count            = 0;
+       state->total_read       = 0;
+
+       if (!tsocket_readv_ask_for_next_vector(req, state)) {
+               goto post;
+       }
+
+       talloc_set_destructor(state, tsocket_readv_state_destructor);
+
+       ret = tsocket_set_readable_handler(sock,
+                                          tsocket_readv_handler,
+                                          req);
+       err = tsocket_error_from_errno(ret, errno, &dummy);
+       if (tevent_req_error(req, err)) {
+               goto post;
+       }
+
+       return req;
+
+ post:
+       return tevent_req_post(req, sock->event.ctx);
+}
+
+static void tsocket_readv_handler(struct tsocket_context *sock,
+                                 void *private_data)
+{
+       struct tevent_req *req = talloc_get_type(private_data,
+                                struct tevent_req);
+       struct tsocket_readv_state *state = tevent_req_data(req,
+                                           struct tsocket_readv_state);
+       ssize_t ret;
+       int err;
+       bool retry;
+
+       ret = tsocket_readv(state->caller.sock,
+                           state->iov,
+                           state->count);
+       err = tsocket_error_from_errno(ret, errno, &retry);
+       if (retry) {
+               /* retry later */
+               return;
+       }
+       if (tevent_req_error(req, err)) {
+               return;
+       }
+
+       state->total_read += ret;
+
+       while (ret > 0) {
+               if (ret < state->iov[0].iov_len) {
+                       uint8_t *base;
+                       base = (uint8_t *)state->iov[0].iov_base;
+                       base += ret;
+                       state->iov[0].iov_base = base;
+                       state->iov[0].iov_len -= ret;
+                       break;
+               }
+               ret -= state->iov[0].iov_len;
+               state->iov += 1;
+               state->count -= 1;
+       }
+
+       if (state->count) {
+               /* we have more to read */
+               return;
+       }
+
+       /* ask the callback for a new vector we should fill */
+       tsocket_readv_ask_for_next_vector(req, state);
+}
+
+int tsocket_readv_recv(struct tevent_req *req, int *perrno)
+{
+       struct tsocket_readv_state *state = tevent_req_data(req,
+                                           struct tsocket_readv_state);
+       int ret;
+
+       ret = tsocket_simple_int_recv(req, perrno);
+       if (ret == 0) {
+               ret = state->total_read;
+       }
+
+       tevent_req_received(req);
+       return ret;
+}
+
diff --git a/lib/tsocket/tsocket_recvfrom.c b/lib/tsocket/tsocket_recvfrom.c
new file mode 100644 (file)
index 0000000..467738c
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/network.h"
+#include "tsocket.h"
+#include "tsocket_internal.h"
+
+struct tsocket_recvfrom_state {
+       /* this structs are owned by the caller */
+       struct {
+               struct tsocket_context *sock;
+       } caller;
+
+       uint8_t *buf;
+       size_t len;
+       struct tsocket_address *src;
+};
+
+static int tsocket_recvfrom_state_destructor(struct tsocket_recvfrom_state *state)
+{
+       if (state->caller.sock) {
+               tsocket_set_readable_handler(state->caller.sock, NULL, NULL);
+       }
+       ZERO_STRUCT(state->caller);
+
+       return 0;
+}
+
+static void tsocket_recvfrom_handler(struct tsocket_context *sock,
+                                    void *private_data);
+
+struct tevent_req *tsocket_recvfrom_send(struct tsocket_context *sock,
+                                        TALLOC_CTX *mem_ctx)
+{
+       struct tevent_req *req;
+       struct tsocket_recvfrom_state *state;
+       int ret;
+       int err;
+       bool dummy;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct tsocket_recvfrom_state);
+       if (!req) {
+               return NULL;
+       }
+
+       state->caller.sock      = sock;
+       state->buf              = NULL;
+       state->len              = 0;
+       state->src              = NULL;
+
+       talloc_set_destructor(state, tsocket_recvfrom_state_destructor);
+
+       ret = tsocket_set_readable_handler(sock,
+                                          tsocket_recvfrom_handler,
+                                          req);
+       err = tsocket_error_from_errno(ret, errno, &dummy);
+       if (tevent_req_error(req, err)) {
+               goto post;
+       }
+
+       return req;
+
+ post:
+       return tevent_req_post(req, sock->event.ctx);
+}
+
+static void tsocket_recvfrom_handler(struct tsocket_context *sock,
+                                    void *private_data)
+{
+       struct tevent_req *req = talloc_get_type(private_data,
+                                struct tevent_req);
+       struct tsocket_recvfrom_state *state = tevent_req_data(req,
+                                              struct tsocket_recvfrom_state);
+       ssize_t ret;
+       int err;
+       bool retry;
+
+       ret = tsocket_pending(state->caller.sock);
+       if (ret == 0) {
+               /* retry later */
+               return;
+       }
+       err = tsocket_error_from_errno(ret, errno, &retry);
+       if (retry) {
+               /* retry later */
+               return;
+       }
+       if (tevent_req_error(req, err)) {
+               return;
+       }
+
+       state->buf = talloc_array(state, uint8_t, ret);
+       if (tevent_req_nomem(state->buf, req)) {
+               return;
+       }
+       state->len = ret;
+
+       ret = tsocket_recvfrom(state->caller.sock,
+                              state->buf,
+                              state->len,
+                              state,
+                              &state->src);
+       err = tsocket_error_from_errno(ret, errno, &retry);
+       if (retry) {
+               /* retry later */
+               return;
+       }
+       if (tevent_req_error(req, err)) {
+               return;
+       }
+
+       if (ret != state->len) {
+               tevent_req_error(req, EIO);
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+ssize_t tsocket_recvfrom_recv(struct tevent_req *req,
+                             int *perrno,
+                             TALLOC_CTX *mem_ctx,
+                             uint8_t **buf,
+                             struct tsocket_address **src)
+{
+       struct tsocket_recvfrom_state *state = tevent_req_data(req,
+                                              struct tsocket_recvfrom_state);
+       ssize_t ret;
+
+       ret = tsocket_simple_int_recv(req, perrno);
+       if (ret == 0) {
+               *buf = talloc_move(mem_ctx, &state->buf);
+               ret = state->len;
+               if (src) {
+                       *src = talloc_move(mem_ctx, &state->src);
+               }
+       }
+
+       tevent_req_received(req);
+       return ret;
+}
+
diff --git a/lib/tsocket/tsocket_sendto.c b/lib/tsocket/tsocket_sendto.c
new file mode 100644 (file)
index 0000000..9c0a76b
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/network.h"
+#include "tsocket.h"
+#include "tsocket_internal.h"
+
+struct tsocket_sendto_state {
+       /* this structs are owned by the caller */
+       struct {
+               struct tsocket_context *sock;
+               const uint8_t *buf;
+               size_t len;
+               const struct tsocket_address *dst;
+       } caller;
+
+       ssize_t ret;
+};
+
+static int tsocket_sendto_state_destructor(struct tsocket_sendto_state *state)
+{
+       if (state->caller.sock) {
+               tsocket_set_writeable_handler(state->caller.sock, NULL, NULL);
+       }
+       ZERO_STRUCT(state->caller);
+
+       return 0;
+}
+
+static void tsocket_sendto_handler(struct tsocket_context *sock,
+                                  void *private_data);
+
+struct tevent_req *tsocket_sendto_send(struct tsocket_context *sock,
+                                      TALLOC_CTX *mem_ctx,
+                                      const uint8_t *buf,
+                                      size_t len,
+                                      const struct tsocket_address *dst)
+{
+       struct tevent_req *req;
+       struct tsocket_sendto_state *state;
+       int ret;
+       int err;
+       bool dummy;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct tsocket_sendto_state);
+       if (!req) {
+               return NULL;
+       }
+
+       state->caller.sock      = sock;
+       state->caller.buf       = buf;
+       state->caller.len       = len;
+       state->caller.dst       = dst;
+       state->ret              = -1;
+
+       /*
+        * this is a fast path, not waiting for the
+        * socket to become explicit writeable gains
+        * about 10%-20% performance in benchmark tests.
+        */
+       tsocket_sendto_handler(sock, req);
+       if (!tevent_req_is_in_progress(req)) {
+               goto post;
+       }
+
+       talloc_set_destructor(state, tsocket_sendto_state_destructor);
+
+       ret = tsocket_set_writeable_handler(sock,
+                                           tsocket_sendto_handler,
+                                           req);
+       err = tsocket_error_from_errno(ret, errno, &dummy);
+       if (tevent_req_error(req, err)) {
+               goto post;
+       }
+
+       return req;
+
+ post:
+       return tevent_req_post(req, sock->event.ctx);
+}
+
+static void tsocket_sendto_handler(struct tsocket_context *sock,
+                                  void *private_data)
+{
+       struct tevent_req *req = talloc_get_type(private_data,
+                                struct tevent_req);
+       struct tsocket_sendto_state *state = tevent_req_data(req,
+                                            struct tsocket_sendto_state);
+       ssize_t ret;
+       int err;
+       bool retry;
+
+       ret = tsocket_sendto(state->caller.sock,
+                            state->caller.buf,
+                            state->caller.len,
+                            state->caller.dst);
+       err = tsocket_error_from_errno(ret, errno, &retry);
+       if (retry) {
+               /* retry later */
+               return;
+       }
+       if (tevent_req_error(req, err)) {
+               return;
+       }
+
+       state->ret = ret;
+
+       tevent_req_done(req);
+}
+
+ssize_t tsocket_sendto_recv(struct tevent_req *req, int *perrno)
+{
+       struct tsocket_sendto_state *state = tevent_req_data(req,
+                                            struct tsocket_sendto_state);
+       ssize_t ret;
+
+       ret = tsocket_simple_int_recv(req, perrno);
+       if (ret == 0) {
+               ret = state->ret;
+       }
+
+       tevent_req_received(req);
+       return ret;
+}
+
+struct tsocket_sendto_queue_state {
+       /* this structs are owned by the caller */
+       struct {
+               struct tsocket_context *sock;
+               const uint8_t *buf;
+               size_t len;
+               const struct tsocket_address *dst;
+       } caller;
+       ssize_t ret;
+};
+
+static void tsocket_sendto_queue_trigger(struct tevent_req *req,
+                                        void *private_data);
+static void tsocket_sendto_queue_done(struct tevent_req *subreq);
+
+/**
+ * @brief Queue a dgram blob for sending through the socket
+ * @param[in] mem_ctx  The memory context for the result
+ * @param[in] sock     The socket to send the message buffer
+ * @param[in] queue    The existing dgram queue
+ * @param[in] buf      The message buffer
+ * @param[in] len      The message length
+ * @param[in] dst      The destination socket address
+ * @retval             The async request handle
+ *
+ * This function queues a blob for sending to destination through an existing
+ * dgram socket. The async callback is triggered when the whole blob is
+ * delivered to the underlying system socket.
+ *
+ * The caller needs to make sure that all non-scalar input parameters hang
+ * arround for the whole lifetime of the request.
+ */
+struct tevent_req *tsocket_sendto_queue_send(TALLOC_CTX *mem_ctx,
+                                            struct tsocket_context *sock,
+                                            struct tevent_queue *queue,
+                                            const uint8_t *buf,
+                                            size_t len,
+                                            struct tsocket_address *dst)
+{
+       struct tevent_req *req;
+       struct tsocket_sendto_queue_state *state;
+       bool ok;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct tsocket_sendto_queue_state);
+       if (!req) {
+               return NULL;
+       }
+
+       state->caller.sock      = sock;
+       state->caller.buf       = buf;
+       state->caller.len       = len;
+       state->caller.dst       = dst;
+       state->ret              = -1;
+
+       ok = tevent_queue_add(queue,
+                             sock->event.ctx,
+                             req,
+                             tsocket_sendto_queue_trigger,
+                             NULL);
+       if (!ok) {
+               tevent_req_nomem(NULL, req);
+               goto post;
+       }
+
+       return req;
+
+ post:
+       return tevent_req_post(req, sock->event.ctx);
+}
+
+static void tsocket_sendto_queue_trigger(struct tevent_req *req,
+                                        void *private_data)
+{
+       struct tsocket_sendto_queue_state *state = tevent_req_data(req,
+                                       struct tsocket_sendto_queue_state);
+       struct tevent_req *subreq;
+
+       subreq = tsocket_sendto_send(state->caller.sock,
+                                    state,
+                                    state->caller.buf,
+                                    state->caller.len,
+                                    state->caller.dst);
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq, tsocket_sendto_queue_done ,req);
+}
+
+static void tsocket_sendto_queue_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(subreq,
+                                struct tevent_req);
+       struct tsocket_sendto_queue_state *state = tevent_req_data(req,
+                                       struct tsocket_sendto_queue_state);
+       ssize_t ret;
+       int sys_errno;
+
+       ret = tsocket_sendto_recv(subreq, &sys_errno);
+       talloc_free(subreq);
+       if (ret == -1) {
+               tevent_req_error(req, sys_errno);
+               return;
+       }
+       state->ret = ret;
+
+       tevent_req_done(req);
+}
+
+ssize_t tsocket_sendto_queue_recv(struct tevent_req *req, int *perrno)
+{
+       struct tsocket_sendto_queue_state *state = tevent_req_data(req,
+                                       struct tsocket_sendto_queue_state);
+       ssize_t ret;
+
+       ret = tsocket_simple_int_recv(req, perrno);
+       if (ret == 0) {
+               ret = state->ret;
+       }
+
+       tevent_req_received(req);
+       return ret;
+}
+
diff --git a/lib/tsocket/tsocket_writev.c b/lib/tsocket/tsocket_writev.c
new file mode 100644 (file)
index 0000000..8c5cd40
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/network.h"
+#include "tsocket.h"
+#include "tsocket_internal.h"
+
+struct tsocket_writev_state {
+       /* this structs are owned by the caller */
+       struct {
+               struct tsocket_context *sock;
+               const struct iovec *vector;
+               size_t count;
+       } caller;
+
+       struct iovec *iov;
+       size_t count;
+       int total_written;
+};
+
+static int tsocket_writev_state_destructor(struct tsocket_writev_state *state)
+{
+       if (state->caller.sock) {
+               tsocket_set_writeable_handler(state->caller.sock, NULL, NULL);
+       }
+       ZERO_STRUCT(state->caller);
+
+       return 0;
+}
+
+static void tsocket_writev_handler(struct tsocket_context *sock,
+                                  void *private_data);
+
+struct tevent_req *tsocket_writev_send(struct tsocket_context *sock,
+                                      TALLOC_CTX *mem_ctx,
+                                      const struct iovec *vector,
+                                      size_t count)
+{
+       struct tevent_req *req;
+       struct tsocket_writev_state *state;
+       int ret;
+       int err;
+       bool dummy;
+       int to_write = 0;
+       size_t i;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct tsocket_writev_state);
+       if (!req) {
+               return NULL;
+       }
+
+       state->caller.sock      = sock;
+       state->caller.vector    = vector;
+       state->caller.count     = count;
+
+       state->iov              = NULL;
+       state->count            = count;
+       state->total_written    = 0;
+
+       state->iov = talloc_array(state, struct iovec, count);
+       if (tevent_req_nomem(state->iov, req)) {
+               goto post;
+       }
+       memcpy(state->iov, vector, sizeof(struct iovec) * count);
+
+       for (i=0; i < count; i++) {
+               int tmp = to_write;
+
+               tmp += state->iov[i].iov_len;
+
+               if (tmp < to_write) {
+                       tevent_req_error(req, EMSGSIZE);
+                       goto post;
+               }
+
+               to_write = tmp;
+       }
+
+       if (to_write == 0) {
+               tevent_req_done(req);
+               goto post;
+       }
+
+       /*
+        * this is a fast path, not waiting for the
+        * socket to become explicit writeable gains
+        * about 10%-20% performance in benchmark tests.
+        */
+       tsocket_writev_handler(sock, req);
+       if (!tevent_req_is_in_progress(req)) {
+               goto post;
+       }
+
+       talloc_set_destructor(state, tsocket_writev_state_destructor);
+
+       ret = tsocket_set_writeable_handler(sock,
+                                           tsocket_writev_handler,
+                                           req);
+       err = tsocket_error_from_errno(ret, errno, &dummy);
+       if (tevent_req_error(req, err)) {
+               goto post;
+       }
+
+       return req;
+
+ post:
+       return tevent_req_post(req, sock->event.ctx);
+}
+
+static void tsocket_writev_handler(struct tsocket_context *sock,
+                                  void *private_data)
+{
+       struct tevent_req *req = talloc_get_type(private_data,
+                                struct tevent_req);
+       struct tsocket_writev_state *state = tevent_req_data(req,
+                                            struct tsocket_writev_state);
+       int ret;
+       int err;
+       bool retry;
+
+       ret = tsocket_writev(state->caller.sock,
+                            state->iov,
+                            state->count);
+       err = tsocket_error_from_errno(ret, errno, &retry);
+       if (retry) {
+               /* retry later */
+               return;
+       }
+       if (tevent_req_error(req, err)) {
+               return;
+       }
+
+       state->total_written += ret;
+
+       /*
+        * we have not written everything yet, so we need to truncate
+        * the already written bytes from our iov copy
+        */
+       while (ret > 0) {
+               if (ret < state->iov[0].iov_len) {
+                       uint8_t *base;
+                       base = (uint8_t *)state->iov[0].iov_base;
+                       base += ret;
+                       state->iov[0].iov_base = base;
+                       state->iov[0].iov_len -= ret;
+                       break;
+               }
+               ret -= state->iov[0].iov_len;
+               state->iov += 1;
+               state->count -= 1;
+       }
+
+       if (state->count > 0) {
+               /* more to write */
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+int tsocket_writev_recv(struct tevent_req *req, int *perrno)
+{
+       struct tsocket_writev_state *state = tevent_req_data(req,
+                                            struct tsocket_writev_state);
+       int ret;
+
+       ret = tsocket_simple_int_recv(req, perrno);
+       if (ret == 0) {
+               ret = state->total_written;
+       }
+
+       tevent_req_received(req);
+       return ret;
+}
+
+struct tsocket_writev_queue_state {
+       /* this structs are owned by the caller */
+       struct {
+               struct tsocket_context *sock;
+               const struct iovec *vector;
+               size_t count;
+       } caller;
+       int ret;
+};
+
+static void tsocket_writev_queue_trigger(struct tevent_req *req,
+                                        void *private_data);
+static void tsocket_writev_queue_done(struct tevent_req *subreq);
+
+/**
+ * @brief Queue a dgram blob for sending through the socket
+ * @param[in] mem_ctx  The memory context for the result
+ * @param[in] sock     The socket to send data through
+ * @param[in] queue    The existing send queue
+ * @param[in] vector   The iovec vector so write
+ * @param[in] count    The size of the vector
+ * @retval             The async request handle
+ *
+ * This function queues a blob for sending to destination through an existing
+ * dgram socket. The async callback is triggered when the whole blob is
+ * delivered to the underlying system socket.
+ *
+ * The caller needs to make sure that all non-scalar input parameters hang
+ * arround for the whole lifetime of the request.
+ */
+struct tevent_req *tsocket_writev_queue_send(TALLOC_CTX *mem_ctx,
+                                            struct tsocket_context *sock,
+                                            struct tevent_queue *queue,
+                                            const struct iovec *vector,
+                                            size_t count)
+{
+       struct tevent_req *req;
+       struct tsocket_writev_queue_state *state;
+       bool ok;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct tsocket_writev_queue_state);
+       if (!req) {
+               return NULL;
+       }
+
+       state->caller.sock      = sock;
+       state->caller.vector    = vector;
+       state->caller.count     = count;
+       state->ret              = -1;
+
+       ok = tevent_queue_add(queue,
+                             sock->event.ctx,
+                             req,
+                             tsocket_writev_queue_trigger,
+                             NULL);
+       if (!ok) {
+               tevent_req_nomem(NULL, req);
+               goto post;
+       }
+
+       return req;
+
+ post:
+       return tevent_req_post(req, sock->event.ctx);
+}
+
+static void tsocket_writev_queue_trigger(struct tevent_req *req,
+                                        void *private_data)
+{
+       struct tsocket_writev_queue_state *state = tevent_req_data(req,
+                                       struct tsocket_writev_queue_state);
+       struct tevent_req *subreq;
+
+       subreq = tsocket_writev_send(state->caller.sock,
+                                    state,
+                                    state->caller.vector,
+                                    state->caller.count);
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq, tsocket_writev_queue_done ,req);
+}
+
+static void tsocket_writev_queue_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(subreq,
+                                struct tevent_req);
+       struct tsocket_writev_queue_state *state = tevent_req_data(req,
+                                       struct tsocket_writev_queue_state);
+       int ret;
+       int sys_errno;
+
+       ret = tsocket_writev_recv(subreq, &sys_errno);
+       talloc_free(subreq);
+       if (ret == -1) {
+               tevent_req_error(req, sys_errno);
+               return;
+       }
+       state->ret = ret;
+
+       tevent_req_done(req);
+}
+
+int tsocket_writev_queue_recv(struct tevent_req *req, int *perrno)
+{
+       struct tsocket_writev_queue_state *state = tevent_req_data(req,
+                                       struct tsocket_writev_queue_state);
+       int ret;
+
+       ret = tsocket_simple_int_recv(req, perrno);
+       if (ret == 0) {
+               ret = state->ret;
+       }
+
+       tevent_req_received(req);
+       return ret;
+}
+
index 258730ec821ac79dea8fa48889fc111374424cb3..94d47a9f7f098b9f9f7bee3d60d1581d78d69f77 100644 (file)
@@ -169,9 +169,10 @@ static smb_iconv_t get_conv_handle(struct smb_iconv_convenience *ic,
 _PUBLIC_ ssize_t iconv_talloc(TALLOC_CTX *ctx, 
                                       smb_iconv_t cd,
                                       void const *src, size_t srclen, 
-                                      void **dest)
+                                      void *dst)
 {
        size_t i_len, o_len, destlen;
+       void **dest = (void **)dst;
        size_t retval;
        const char *inbuf = (const char *)src;
        char *outbuf, *ob;
@@ -314,9 +315,10 @@ _PUBLIC_ bool convert_string_talloc_convenience(TALLOC_CTX *ctx,
                                       struct smb_iconv_convenience *ic, 
                                       charset_t from, charset_t to, 
                                       void const *src, size_t srclen, 
-                                      void **dest, size_t *converted_size, 
+                                      void *dst, size_t *converted_size, 
                                           bool allow_badcharcnv)
 {
+       void **dest = (void **)dst;
        smb_iconv_t descriptor;
        ssize_t ret;
 
index 655bae7bcdae4cbaf7dfb74d7da9add348e2a1ea..37c5acafafa105614ad0120939c5fc8c46aa0fd1 100644 (file)
@@ -136,7 +136,7 @@ ssize_t pull_string(char *dest, const void *src, size_t dest_len, size_t src_len
 bool convert_string_talloc(TALLOC_CTX *ctx, 
                                       charset_t from, charset_t to, 
                                       void const *src, size_t srclen, 
-                                      void **dest, size_t *converted_size, 
+                                      void *dest, size_t *converted_size, 
                                           bool allow_badcharcnv);
 
 size_t convert_string(charset_t from, charset_t to,
@@ -146,7 +146,7 @@ size_t convert_string(charset_t from, charset_t to,
 ssize_t iconv_talloc(TALLOC_CTX *mem_ctx, 
                                       smb_iconv_t cd,
                                       void const *src, size_t srclen, 
-                                      void **dest);
+                                      void *dest);
 
 extern struct smb_iconv_convenience *global_iconv_convenience;
 
@@ -176,7 +176,7 @@ bool convert_string_talloc_convenience(TALLOC_CTX *ctx,
                                       struct smb_iconv_convenience *ic, 
                                       charset_t from, charset_t to, 
                                       void const *src, size_t srclen, 
-                                      void **dest, size_t *converted_size, bool allow_badcharcnv);
+                                      void *dest, size_t *converted_size, bool allow_badcharcnv);
 /* iconv */
 smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode);
 int smb_iconv_close(smb_iconv_t cd);
index 98284ce9bd5b7d85cbfa26b15d4ce156b2d8edd4..9825e4be016019360d013217a59a617658b4c218 100644 (file)
@@ -50,6 +50,7 @@
 
 static size_t ascii_pull  (void *,const char **, size_t *, char **, size_t *);
 static size_t ascii_push  (void *,const char **, size_t *, char **, size_t *);
+static size_t latin1_push (void *,const char **, size_t *, char **, size_t *);
 static size_t utf8_pull   (void *,const char **, size_t *, char **, size_t *);
 static size_t utf8_push   (void *,const char **, size_t *, char **, size_t *);
 static size_t utf16_munged_pull(void *,const char **, size_t *, char **, size_t *);
@@ -73,6 +74,8 @@ static const struct charset_functions builtin_functions[] = {
        {"UTF16_MUNGED",   utf16_munged_pull,  iconv_copy},
 
        {"ASCII", ascii_pull, ascii_push},
+       {"646", ascii_pull, ascii_push},
+       {"ISO-8859-1", ascii_pull, latin1_push},
        {"UCS2-HEX", ucs2hex_pull, ucs2hex_push}
 };
 
@@ -341,6 +344,32 @@ static size_t ascii_push(void *cd, const char **inbuf, size_t *inbytesleft,
        return ir_count;
 }
 
+static size_t latin1_push(void *cd, const char **inbuf, size_t *inbytesleft,
+                        char **outbuf, size_t *outbytesleft)
+{
+       int ir_count=0;
+
+       while (*inbytesleft >= 2 && *outbytesleft >= 1) {
+               (*outbuf)[0] = (*inbuf)[0];
+               if ((*inbuf)[1]) ir_count++;
+               (*inbytesleft)  -= 2;
+               (*outbytesleft) -= 1;
+               (*inbuf)  += 2;
+               (*outbuf) += 1;
+       }
+
+       if (*inbytesleft == 1) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       if (*inbytesleft > 1) {
+               errno = E2BIG;
+               return -1;
+       }
+       
+       return ir_count;
+}
 
 static size_t ucs2hex_pull(void *cd, const char **inbuf, size_t *inbytesleft,
                         char **outbuf, size_t *outbytesleft)
index ec88e784d088e59f271e7e3db460483e98f0b19e..ea2bfeab9f1556c30fd483dfdf99bd2d29856d9a 100644 (file)
@@ -978,7 +978,7 @@ _PUBLIC_ size_t convert_string(charset_t from, charset_t to,
 _PUBLIC_ bool convert_string_talloc(TALLOC_CTX *ctx, 
                                       charset_t from, charset_t to, 
                                       void const *src, size_t srclen, 
-                                      void **dest, size_t *converted_size, 
+                                      void *dest, size_t *converted_size, 
                                           bool allow_badcharcnv)
 {
        return convert_string_talloc_convenience(ctx, get_iconv_convenience(),
index 14bdb2a2776d91756307497ad27236ed182f5ea4..7835fed911869a5aced8c922e4e0ccf25ad3da87 100644 (file)
@@ -5,7 +5,7 @@ PUBLIC_DEPENDENCIES = \
                CHARSET EXECINFO
 
 LIBSAMBA-UTIL_OBJ_FILES = $(addprefix $(libutilsrcdir)/, \
-       xfile.o \
+               xfile.o \
                debug.o \
                fault.o \
                signal.o \
@@ -68,6 +68,13 @@ PUBLIC_DEPENDENCIES = LIBTDB
 
 UTIL_TDB_OBJ_FILES = $(libutilsrcdir)/util_tdb.o
 
+[SUBSYSTEM::UTIL_TEVENT]
+PUBLIC_DEPENDENCIES = LIBTEVENT
+
+UTIL_TEVENT_OBJ_FILES = $(addprefix $(libutilsrcdir)/, \
+                       tevent_unix.o \
+                       tevent_ntstatus.o)
+
 [SUBSYSTEM::UTIL_LDB]
 PUBLIC_DEPENDENCIES = LIBLDB
 
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 1f31f55e8b2fd1a39e3c545fe733cf4370682d04..0148bdb00d4d43a4246130b9e5993c6f67253d48 100644 (file)
@@ -541,21 +541,6 @@ void *malloc_array(size_t el_size, unsigned int count)
        return realloc_array(NULL, el_size, count, false);
 }
 
-_PUBLIC_ void *talloc_check_name_abort(const void *ptr, const char *name)
-{
-        void *result;
-
-        result = talloc_check_name(ptr, name);
-        if (result != NULL)
-                return result;
-
-        DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
-                  name, talloc_get_name(ptr)));
-        smb_panic("talloc type mismatch");
-        /* Keep the compiler happy */
-        return NULL;
-}
-
 /**
  Trim the specified elements off the front and back of a string.
 **/
index 1f6e3b193b3d0a9f9970428e19c45611e7401fca..defef127d93e4f162a8d2186a5a4ca6f40cf939b 100644 (file)
@@ -767,13 +767,6 @@ bool pm_process( const char *fileName,
                  bool (*pfunc)(const char *, const char *, void *),
                                 void *userdata);
 
-/**
- * Add-on to talloc_get_type
- */
-_PUBLIC_ void *talloc_check_name_abort(const void *ptr, const char *name);
-#define talloc_get_type_abort(ptr, type) \
-       (type *)talloc_check_name_abort(ptr, #type)
-
 bool unmap_file(void *start, size_t size);
 
 void print_asc(int level, const uint8_t *buf,int len);
diff --git a/libcli/cldap/cldap.c b/libcli/cldap/cldap.c
new file mode 100644 (file)
index 0000000..561ae80
--- /dev/null
@@ -0,0 +1,1125 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   cldap client library
+
+   Copyright (C) Andrew Tridgell 2005
+   Copyright (C) Stefan Metzmacher 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
+   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/>.
+*/
+
+/*
+  see RFC1798 for details of CLDAP
+
+  basic properties
+    - carried over UDP on port 389
+    - request and response matched by message ID
+    - request consists of only a single searchRequest element
+    - response can be in one of two forms
+       - a single searchResponse, followed by a searchResult
+       - a single searchResult
+*/
+
+#include "includes.h"
+#include <tevent.h>
+#include "../lib/util/dlinklist.h"
+#include "../libcli/ldap/ldap_message.h"
+#include "../libcli/ldap/ldap_ndr.h"
+#include "../libcli/cldap/cldap.h"
+#include "../lib/tsocket/tsocket.h"
+#include "../libcli/security/dom_sid.h"
+#include "../librpc/gen_ndr/ndr_nbt.h"
+#include "../lib/util/asn1.h"
+#include "../lib/util/tevent_ntstatus.h"
+
+#undef strcasecmp
+
+/*
+  context structure for operations on cldap packets
+*/
+struct cldap_socket {
+       /* the low level socket */
+       struct tsocket_context *sock;
+
+       /*
+        * Are we in connected mode, which means
+        * we get ICMP errors back instead of timing
+        * out requests. And we can only send requests
+        * to the connected peer.
+        */
+       bool connected;
+
+       /*
+        * we allow sync requests only, if the caller
+        * did not pass an event context to cldap_socket_init()
+        */
+       struct {
+               bool allow_poll;
+               struct tevent_context *ctx;
+       } event;
+
+       /* the queue for outgoing dgrams */
+       struct tevent_queue *send_queue;
+
+       /* do we have an async tsocket_recvfrom request pending */
+       struct tevent_req *recv_subreq;
+
+       struct {
+               /* a queue of pending search requests */
+               struct cldap_search_state *list;
+
+               /* mapping from message_id to pending request */
+               struct idr_context *idr;
+       } searches;
+
+       /* what to do with incoming request packets */
+       struct {
+               void (*handler)(struct cldap_socket *,
+                               void *private_data,
+                               struct cldap_incoming *);
+               void *private_data;
+       } incoming;
+};
+
+struct cldap_search_state {
+       struct cldap_search_state *prev, *next;
+
+       struct {
+               struct cldap_socket *cldap;
+       } caller;
+
+       int message_id;
+
+       struct {
+               uint32_t idx;
+               uint32_t delay;
+               uint32_t count;
+               struct tsocket_address *dest;
+               DATA_BLOB blob;
+       } request;
+
+       struct {
+               struct cldap_incoming *in;
+               struct asn1_data *asn1;
+       } response;
+
+       struct tevent_req *req;
+};
+
+static int cldap_socket_destructor(struct cldap_socket *c)
+{
+       tsocket_disconnect(c->sock);
+
+       while (c->searches.list) {
+               struct cldap_search_state *s = c->searches.list;
+               DLIST_REMOVE(c->searches.list, s);
+               ZERO_STRUCT(s->caller);
+       }
+
+       talloc_free(c->recv_subreq);
+       talloc_free(c->send_queue);
+       talloc_free(c->sock);
+       return 0;
+}
+
+static void cldap_recvfrom_done(struct tevent_req *subreq);
+
+static bool cldap_recvfrom_setup(struct cldap_socket *c)
+{
+       if (c->recv_subreq) {
+               return true;
+       }
+
+       if (!c->searches.list && !c->incoming.handler) {
+               return true;
+       }
+
+       c->recv_subreq = tsocket_recvfrom_send(c->sock, c);
+       if (!c->recv_subreq) {
+               return false;
+       }
+       tevent_req_set_callback(c->recv_subreq, cldap_recvfrom_done, c);
+
+       return true;
+}
+
+static void cldap_recvfrom_stop(struct cldap_socket *c)
+{
+       if (!c->recv_subreq) {
+               return;
+       }
+
+       if (c->searches.list || c->incoming.handler) {
+               return;
+       }
+
+       talloc_free(c->recv_subreq);
+       c->recv_subreq = NULL;
+}
+
+static void cldap_socket_recv_dgram(struct cldap_socket *c,
+                                   struct cldap_incoming *in);
+
+static void cldap_recvfrom_done(struct tevent_req *subreq)
+{
+       struct cldap_socket *c = tevent_req_callback_data(subreq,
+                                struct cldap_socket);
+       struct cldap_incoming *in = NULL;
+       ssize_t ret;
+
+       c->recv_subreq = NULL;
+
+       in = talloc_zero(c, struct cldap_incoming);
+       if (!in) {
+               goto nomem;
+       }
+
+       ret = tsocket_recvfrom_recv(subreq,
+                                   &in->recv_errno,
+                                   in,
+                                   &in->buf,
+                                   &in->src);
+       talloc_free(subreq);
+       subreq = NULL;
+       if (ret >= 0) {
+               in->len = ret;
+       }
+       if (ret == -1 && in->recv_errno == 0) {
+               in->recv_errno = EIO;
+       }
+
+       /* this function should free or steal 'in' */
+       cldap_socket_recv_dgram(c, in);
+       in = NULL;
+
+       if (!cldap_recvfrom_setup(c)) {
+               goto nomem;
+       }
+
+       return;
+
+nomem:
+       talloc_free(subreq);
+       talloc_free(in);
+       /*TODO: call a dead socket handler */
+       return;
+}
+
+/*
+  handle recv events on a cldap socket
+*/
+static void cldap_socket_recv_dgram(struct cldap_socket *c,
+                                   struct cldap_incoming *in)
+{
+       DATA_BLOB blob;
+       struct asn1_data *asn1;
+       void *p;
+       struct cldap_search_state *search;
+       NTSTATUS status;
+
+       if (in->recv_errno != 0) {
+               goto error;
+       }
+
+       blob = data_blob_const(in->buf, in->len);
+
+       asn1 = asn1_init(in);
+       if (!asn1) {
+               goto nomem;
+       }
+
+       if (!asn1_load(asn1, blob)) {
+               goto nomem;
+       }
+
+       in->ldap_msg = talloc(in, struct ldap_message);
+       if (in->ldap_msg == NULL) {
+               goto nomem;
+       }
+
+       /* this initial decode is used to find the message id */
+       status = ldap_decode(asn1, NULL, in->ldap_msg);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto nterror;
+       }
+
+       /* find the pending request */
+       p = idr_find(c->searches.idr, in->ldap_msg->messageid);
+       if (p == NULL) {
+               if (!c->incoming.handler) {
+                       goto done;
+               }
+
+               /* this function should free or steal 'in' */
+               c->incoming.handler(c, c->incoming.private_data, in);
+               return;
+       }
+
+       search = talloc_get_type(p, struct cldap_search_state);
+       search->response.in = talloc_move(search, &in);
+       search->response.asn1 = asn1;
+       search->response.asn1->ofs = 0;
+
+       tevent_req_done(search->req);
+       goto done;
+
+nomem:
+       in->recv_errno = ENOMEM;
+error:
+       status = map_nt_error_from_unix(in->recv_errno);
+nterror:
+       /* in connected mode the first pending search gets the error */
+       if (!c->connected) {
+               /* otherwise we just ignore the error */
+               goto done;
+       }
+       if (!c->searches.list) {
+               goto done;
+       }
+       tevent_req_nterror(c->searches.list->req, status);
+done:
+       talloc_free(in);
+}
+
+/*
+  initialise a cldap_sock
+*/
+NTSTATUS cldap_socket_init(TALLOC_CTX *mem_ctx,
+                          struct tevent_context *ev,
+                          const struct tsocket_address *local_addr,
+                          const struct tsocket_address *remote_addr,
+                          struct cldap_socket **_cldap)
+{
+       struct cldap_socket *c = NULL;
+       struct tsocket_address *any = NULL;
+       NTSTATUS status;
+       int ret;
+
+       c = talloc_zero(mem_ctx, struct cldap_socket);
+       if (!c) {
+               goto nomem;
+       }
+
+       if (!ev) {
+               ev = tevent_context_init(c);
+               if (!ev) {
+                       goto nomem;
+               }
+               c->event.allow_poll = true;
+       }
+       c->event.ctx = ev;
+
+       if (!local_addr) {
+               ret = tsocket_address_inet_from_strings(c, "ipv4",
+                                                       NULL, 0,
+                                                       &any);
+               if (ret != 0) {
+                       status = map_nt_error_from_unix(errno);
+                       goto nterror;
+               }
+               local_addr = any;
+       }
+
+       c->searches.idr = idr_init(c);
+       if (!c->searches.idr) {
+               goto nomem;
+       }
+
+       ret = tsocket_address_create_socket(local_addr,
+                                           TSOCKET_TYPE_DGRAM,
+                                           c, &c->sock);
+       if (ret != 0) {
+               status = map_nt_error_from_unix(errno);
+               goto nterror;
+       }
+       talloc_free(any);
+
+       tsocket_set_event_context(c->sock, c->event.ctx);
+
+       if (remote_addr) {
+               ret = tsocket_connect(c->sock, remote_addr);
+               if (ret != 0) {
+                       status = map_nt_error_from_unix(errno);
+                       goto nterror;
+               }
+               c->connected = true;
+       }
+
+       c->send_queue = tevent_queue_create(c, "cldap_send_queue");
+       if (!c->send_queue) {
+               goto nomem;
+       }
+
+       talloc_set_destructor(c, cldap_socket_destructor);
+
+       *_cldap = c;
+       return NT_STATUS_OK;
+
+nomem:
+       status = NT_STATUS_NO_MEMORY;
+nterror:
+       talloc_free(c);
+       return status;
+}
+
+/*
+  setup a handler for incoming requests
+*/
+NTSTATUS cldap_set_incoming_handler(struct cldap_socket *c,
+                                   void (*handler)(struct cldap_socket *,
+                                                   void *private_data,
+                                                   struct cldap_incoming *),
+                                   void *private_data)
+{
+       if (c->connected) {
+               return NT_STATUS_PIPE_CONNECTED;
+       }
+
+       /* if sync requests are allowed, we don't allow an incoming handler */
+       if (c->event.allow_poll) {
+               return NT_STATUS_INVALID_PIPE_STATE;
+       }
+
+       c->incoming.handler = handler;
+       c->incoming.private_data = private_data;
+
+       if (!cldap_recvfrom_setup(c)) {
+               ZERO_STRUCT(c->incoming);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       return NT_STATUS_OK;
+}
+
+struct cldap_reply_state {
+       struct tsocket_address *dest;
+       DATA_BLOB blob;
+};
+
+static void cldap_reply_state_destroy(struct tevent_req *req);
+
+/*
+  queue a cldap reply for send
+*/
+NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io)
+{
+       struct cldap_reply_state *state = NULL;
+       struct ldap_message *msg;
+       DATA_BLOB blob1, blob2;
+       NTSTATUS status;
+       struct tevent_req *req;
+
+       if (cldap->connected) {
+               return NT_STATUS_PIPE_CONNECTED;
+       }
+
+       if (!io->dest) {
+               return NT_STATUS_INVALID_ADDRESS;
+       }
+
+       state = talloc(cldap, struct cldap_reply_state);
+       NT_STATUS_HAVE_NO_MEMORY(state);
+
+       state->dest = tsocket_address_copy(io->dest, state);
+       if (!state->dest) {
+               goto nomem;
+       }
+
+       msg = talloc(state, struct ldap_message);
+       if (!msg) {
+               goto nomem;
+       }
+
+       msg->messageid       = io->messageid;
+       msg->controls        = NULL;
+
+       if (io->response) {
+               msg->type = LDAP_TAG_SearchResultEntry;
+               msg->r.SearchResultEntry = *io->response;
+
+               if (!ldap_encode(msg, NULL, &blob1, state)) {
+                       status = NT_STATUS_INVALID_PARAMETER;
+                       goto failed;
+               }
+       } else {
+               blob1 = data_blob(NULL, 0);
+       }
+
+       msg->type = LDAP_TAG_SearchResultDone;
+       msg->r.SearchResultDone = *io->result;
+
+       if (!ldap_encode(msg, NULL, &blob2, state)) {
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto failed;
+       }
+       talloc_free(msg);
+
+       state->blob = data_blob_talloc(state, NULL, blob1.length + blob2.length);
+       if (!state->blob.data) {
+               goto nomem;
+       }
+
+       memcpy(state->blob.data, blob1.data, blob1.length);
+       memcpy(state->blob.data+blob1.length, blob2.data, blob2.length);
+       data_blob_free(&blob1);
+       data_blob_free(&blob2);
+
+       req = tsocket_sendto_queue_send(state,
+                                       cldap->sock,
+                                       cldap->send_queue,
+                                       state->blob.data,
+                                       state->blob.length,
+                                       state->dest);
+       if (!req) {
+               goto nomem;
+       }
+       /* the callback will just free the state, as we don't need a result */
+       tevent_req_set_callback(req, cldap_reply_state_destroy, state);
+
+       return NT_STATUS_OK;
+
+nomem:
+       status = NT_STATUS_NO_MEMORY;
+failed:
+       talloc_free(state);
+       return status;
+}
+
+static void cldap_reply_state_destroy(struct tevent_req *req)
+{
+       struct cldap_reply_state *state = tevent_req_callback_data(req,
+                                         struct cldap_reply_state);
+
+       /* we don't want to know the result here, we just free the state */
+       talloc_free(req);
+       talloc_free(state);
+}
+
+static int cldap_search_state_destructor(struct cldap_search_state *s)
+{
+       if (s->caller.cldap) {
+               DLIST_REMOVE(s->caller.cldap->searches.list, s);
+               cldap_recvfrom_stop(s->caller.cldap);
+               ZERO_STRUCT(s->caller);
+       }
+
+       return 0;
+}
+
+static void cldap_search_state_queue_done(struct tevent_req *subreq);
+static void cldap_search_state_wakeup_done(struct tevent_req *subreq);
+
+/*
+  queue a cldap reply for send
+*/
+struct tevent_req *cldap_search_send(TALLOC_CTX *mem_ctx,
+                                   struct cldap_socket *cldap,
+                                   const struct cldap_search *io)
+{
+       struct tevent_req *req, *subreq;
+       struct cldap_search_state *state = NULL;
+       struct ldap_message *msg;
+       struct ldap_SearchRequest *search;
+       struct timeval now;
+       struct timeval end;
+       uint32_t i;
+       int ret;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct cldap_search_state);
+       if (!req) {
+               return NULL;
+       }
+       state->req = req;
+       state->caller.cldap = cldap;
+
+       if (io->in.dest_address) {
+               if (cldap->connected) {
+                       tevent_req_nterror(req, NT_STATUS_PIPE_CONNECTED);
+                       goto post;
+               }
+               ret = tsocket_address_inet_from_strings(state,
+                                                       "ipv4",
+                                                       io->in.dest_address,
+                                                       io->in.dest_port,
+                                                       &state->request.dest);
+               if (ret != 0) {
+                       tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       goto post;
+               }
+       } else {
+               if (!cldap->connected) {
+                       tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
+                       goto post;
+               }
+               state->request.dest = NULL;
+       }
+
+       state->message_id = idr_get_new_random(cldap->searches.idr,
+                                              state, UINT16_MAX);
+       if (state->message_id == -1) {
+               tevent_req_nterror(req, NT_STATUS_INSUFFICIENT_RESOURCES);
+               goto post;
+       }
+
+       msg = talloc(state, struct ldap_message);
+       if (tevent_req_nomem(msg, req)) {
+               goto post;
+       }
+
+       msg->messageid  = state->message_id;
+       msg->type       = LDAP_TAG_SearchRequest;
+       msg->controls   = NULL;
+       search = &msg->r.SearchRequest;
+
+       search->basedn          = "";
+       search->scope           = LDAP_SEARCH_SCOPE_BASE;
+       search->deref           = LDAP_DEREFERENCE_NEVER;
+       search->timelimit       = 0;
+       search->sizelimit       = 0;
+       search->attributesonly  = false;
+       search->num_attributes  = str_list_length(io->in.attributes);
+       search->attributes      = io->in.attributes;
+       search->tree            = ldb_parse_tree(msg, io->in.filter);
+       if (tevent_req_nomem(search->tree, req)) {
+               goto post;
+       }
+
+       if (!ldap_encode(msg, NULL, &state->request.blob, state)) {
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               goto post;
+       }
+       talloc_free(msg);
+
+       state->request.idx = 0;
+       state->request.delay = 10*1000*1000;
+       state->request.count = 3;
+       if (io->in.timeout > 0) {
+               state->request.delay = io->in.timeout * 1000 * 1000;
+               state->request.count = io->in.retries + 1;
+       }
+
+       now = tevent_timeval_current();
+       end = now;
+       for (i = 0; i < state->request.count; i++) {
+               end = tevent_timeval_add(&end, 0, state->request.delay);
+       }
+
+       if (!tevent_req_set_endtime(req, state->caller.cldap->event.ctx, end)) {
+               tevent_req_nomem(NULL, req);
+               goto post;
+       }
+
+       subreq = tsocket_sendto_queue_send(state,
+                                          state->caller.cldap->sock,
+                                          state->caller.cldap->send_queue,
+                                          state->request.blob.data,
+                                          state->request.blob.length,
+                                          state->request.dest);
+       if (tevent_req_nomem(subreq, req)) {
+               goto post;
+       }
+       tevent_req_set_callback(subreq, cldap_search_state_queue_done, req);
+
+       DLIST_ADD_END(cldap->searches.list, state, struct cldap_search_state *);
+       talloc_set_destructor(state, cldap_search_state_destructor);
+
+       return req;
+
+ post:
+       return tevent_req_post(req, cldap->event.ctx);
+}
+
+static void cldap_search_state_queue_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(subreq,
+                                struct tevent_req);
+       struct cldap_search_state *state = tevent_req_data(req,
+                                          struct cldap_search_state);
+       ssize_t ret;
+       int sys_errno = 0;
+       struct timeval next;
+
+       ret = tsocket_sendto_queue_recv(subreq, &sys_errno);
+       talloc_free(subreq);
+       if (ret == -1) {
+               NTSTATUS status;
+               status = map_nt_error_from_unix(sys_errno);
+               DLIST_REMOVE(state->caller.cldap->searches.list, state);
+               ZERO_STRUCT(state->caller.cldap);
+               tevent_req_nterror(req, status);
+               return;
+       }
+
+       state->request.idx++;
+
+       /* wait for incoming traffic */
+       if (!cldap_recvfrom_setup(state->caller.cldap)) {
+               tevent_req_nomem(NULL, req);
+               return;
+       }
+
+       if (state->request.idx > state->request.count) {
+               /* we just wait for the response or a timeout */
+               return;
+       }
+
+       next = tevent_timeval_current_ofs(0, state->request.delay);
+       subreq = tevent_wakeup_send(state,
+                                   state->caller.cldap->event.ctx,
+                                   next);
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq, cldap_search_state_wakeup_done, req);
+}
+
+static void cldap_search_state_wakeup_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(subreq,
+                                struct tevent_req);
+       struct cldap_search_state *state = tevent_req_data(req,
+                                          struct cldap_search_state);
+       bool ok;
+
+       ok = tevent_wakeup_recv(subreq);
+       talloc_free(subreq);
+       if (!ok) {
+               tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+               return;
+       }
+
+       subreq = tsocket_sendto_queue_send(state,
+                                          state->caller.cldap->sock,
+                                          state->caller.cldap->send_queue,
+                                          state->request.blob.data,
+                                          state->request.blob.length,
+                                          state->request.dest);
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq, cldap_search_state_queue_done, req);
+}
+
+/*
+  receive a cldap reply
+*/
+NTSTATUS cldap_search_recv(struct tevent_req *req,
+                          TALLOC_CTX *mem_ctx,
+                          struct cldap_search *io)
+{
+       struct cldap_search_state *state = tevent_req_data(req,
+                                          struct cldap_search_state);
+       struct ldap_message *ldap_msg;
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               goto failed;
+       }
+
+       ldap_msg = talloc(mem_ctx, struct ldap_message);
+       if (!ldap_msg) {
+               goto nomem;
+       }
+
+       status = ldap_decode(state->response.asn1, NULL, ldap_msg);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto failed;
+       }
+
+       ZERO_STRUCT(io->out);
+
+       /* the first possible form has a search result in first place */
+       if (ldap_msg->type == LDAP_TAG_SearchResultEntry) {
+               io->out.response = talloc(mem_ctx, struct ldap_SearchResEntry);
+               if (!io->out.response) {
+                       goto nomem;
+               }
+               *io->out.response = ldap_msg->r.SearchResultEntry;
+
+               /* decode the 2nd part */
+               status = ldap_decode(state->response.asn1, NULL, ldap_msg);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto failed;
+               }
+       }
+
+       if (ldap_msg->type != LDAP_TAG_SearchResultDone) {
+               status = NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+               goto failed;
+       }
+
+       io->out.result = talloc(mem_ctx, struct ldap_Result);
+       if (!io->out.result) {
+               goto nomem;
+       }
+       *io->out.result = ldap_msg->r.SearchResultDone;
+
+       if (io->out.result->resultcode != LDAP_SUCCESS) {
+               status = NT_STATUS_LDAP(io->out.result->resultcode);
+               goto failed;
+       }
+
+       tevent_req_received(req);
+       return NT_STATUS_OK;
+
+nomem:
+       status = NT_STATUS_NO_MEMORY;
+failed:
+       tevent_req_received(req);
+       return status;
+}
+
+
+/*
+  synchronous cldap search
+*/
+NTSTATUS cldap_search(struct cldap_socket *cldap,
+                     TALLOC_CTX *mem_ctx,
+                     struct cldap_search *io)
+{
+       struct tevent_req *req;
+       NTSTATUS status;
+
+       if (!cldap->event.allow_poll) {
+               return NT_STATUS_INVALID_PIPE_STATE;
+       }
+
+       if (cldap->searches.list) {
+               return NT_STATUS_PIPE_BUSY;
+       }
+
+       req = cldap_search_send(mem_ctx, cldap, io);
+       NT_STATUS_HAVE_NO_MEMORY(req);
+
+       if (!tevent_req_poll(req, cldap->event.ctx)) {
+               talloc_free(req);
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       status = cldap_search_recv(req, mem_ctx, io);
+       talloc_free(req);
+
+       return status;
+}
+
+struct cldap_netlogon_state {
+       struct cldap_search search;
+};
+
+static void cldap_netlogon_state_done(struct tevent_req *subreq);
+/*
+  queue a cldap netlogon for send
+*/
+struct tevent_req *cldap_netlogon_send(TALLOC_CTX *mem_ctx,
+                                     struct cldap_socket *cldap,
+                                     const struct cldap_netlogon *io)
+{
+       struct tevent_req *req, *subreq;
+       struct cldap_netlogon_state *state;
+       char *filter;
+       static const char * const attr[] = { "NetLogon", NULL };
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct cldap_netlogon_state);
+       if (!req) {
+               return NULL;
+       }
+
+       filter = talloc_asprintf(state, "(&(NtVer=%s)", 
+                                ldap_encode_ndr_uint32(state, io->in.version));
+       if (tevent_req_nomem(filter, req)) {
+               goto post;
+       }
+       if (io->in.user) {
+               filter = talloc_asprintf_append_buffer(filter, "(User=%s)", io->in.user);
+               if (tevent_req_nomem(filter, req)) {
+                       goto post;
+               }
+       }
+       if (io->in.host) {
+               filter = talloc_asprintf_append_buffer(filter, "(Host=%s)", io->in.host);
+               if (tevent_req_nomem(filter, req)) {
+                       goto post;
+               }
+       }
+       if (io->in.realm) {
+               filter = talloc_asprintf_append_buffer(filter, "(DnsDomain=%s)", io->in.realm);
+               if (tevent_req_nomem(filter, req)) {
+                       goto post;
+               }
+       }
+       if (io->in.acct_control != -1) {
+               filter = talloc_asprintf_append_buffer(filter, "(AAC=%s)", 
+                                               ldap_encode_ndr_uint32(state, io->in.acct_control));
+               if (tevent_req_nomem(filter, req)) {
+                       goto post;
+               }
+       }
+       if (io->in.domain_sid) {
+               struct dom_sid *sid = dom_sid_parse_talloc(state, io->in.domain_sid);
+               if (tevent_req_nomem(sid, req)) {
+                       goto post;
+               }
+               filter = talloc_asprintf_append_buffer(filter, "(domainSid=%s)",
+                                               ldap_encode_ndr_dom_sid(state, sid));
+               if (tevent_req_nomem(filter, req)) {
+                       goto post;
+               }
+       }
+       if (io->in.domain_guid) {
+               struct GUID guid;
+               NTSTATUS status;
+               status = GUID_from_string(io->in.domain_guid, &guid);
+               if (tevent_req_nterror(req, status)) {
+                       goto post;
+               }
+               filter = talloc_asprintf_append_buffer(filter, "(DomainGuid=%s)",
+                                               ldap_encode_ndr_GUID(state, &guid));
+               if (tevent_req_nomem(filter, req)) {
+                       goto post;
+               }
+       }
+       filter = talloc_asprintf_append_buffer(filter, ")");
+       if (tevent_req_nomem(filter, req)) {
+               goto post;
+       }
+
+       if (io->in.dest_address) {
+               state->search.in.dest_address = talloc_strdup(state,
+                                               io->in.dest_address);
+               if (tevent_req_nomem(state->search.in.dest_address, req)) {
+                       goto post;
+               }
+               state->search.in.dest_port = io->in.dest_port;
+       } else {
+               state->search.in.dest_address   = NULL;
+               state->search.in.dest_port      = 0;
+       }
+       state->search.in.filter         = filter;
+       state->search.in.attributes     = attr;
+       state->search.in.timeout        = 2;
+       state->search.in.retries        = 2;
+
+       subreq = cldap_search_send(state, cldap, &state->search);
+       if (tevent_req_nomem(subreq, req)) {
+               goto post;
+       }
+       tevent_req_set_callback(subreq, cldap_netlogon_state_done, req);
+
+       return req;
+post:
+       return tevent_req_post(req, cldap->event.ctx);
+}
+
+static void cldap_netlogon_state_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(subreq,
+                                struct tevent_req);
+       struct cldap_netlogon_state *state = tevent_req_data(req,
+                                            struct cldap_netlogon_state);
+       NTSTATUS status;
+
+       status = cldap_search_recv(subreq, state, &state->search);
+       talloc_free(subreq);
+
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+/*
+  receive a cldap netlogon reply
+*/
+NTSTATUS cldap_netlogon_recv(struct tevent_req *req,
+                            struct smb_iconv_convenience *iconv_convenience,
+                            TALLOC_CTX *mem_ctx,
+                            struct cldap_netlogon *io)
+{
+       struct cldap_netlogon_state *state = tevent_req_data(req,
+                                            struct cldap_netlogon_state);
+       NTSTATUS status;
+       DATA_BLOB *data;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               goto failed;
+       }
+
+       if (state->search.out.response == NULL) {
+               status = NT_STATUS_NOT_FOUND;
+               goto failed;
+       }
+
+       if (state->search.out.response->num_attributes != 1 ||
+           strcasecmp(state->search.out.response->attributes[0].name, "netlogon") != 0 ||
+           state->search.out.response->attributes[0].num_values != 1 ||
+           state->search.out.response->attributes[0].values->length < 2) {
+               status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
+               goto failed;
+       }
+       data = state->search.out.response->attributes[0].values;
+
+       status = pull_netlogon_samlogon_response(data, mem_ctx,
+                                                iconv_convenience,
+                                                &io->out.netlogon);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto failed;
+       }
+
+       if (io->in.map_response) {
+               map_netlogon_samlogon_response(&io->out.netlogon);
+       }
+
+       status =  NT_STATUS_OK;
+failed:
+       tevent_req_received(req);
+       return status;
+}
+
+/*
+  sync cldap netlogon search
+*/
+NTSTATUS cldap_netlogon(struct cldap_socket *cldap,
+                       struct smb_iconv_convenience *iconv_convenience,
+                       TALLOC_CTX *mem_ctx,
+                       struct cldap_netlogon *io)
+{
+       struct tevent_req *req;
+       NTSTATUS status;
+
+       if (!cldap->event.allow_poll) {
+               return NT_STATUS_INVALID_PIPE_STATE;
+       }
+
+       if (cldap->searches.list) {
+               return NT_STATUS_PIPE_BUSY;
+       }
+
+       req = cldap_netlogon_send(mem_ctx, cldap, io);
+       NT_STATUS_HAVE_NO_MEMORY(req);
+
+       if (!tevent_req_poll(req, cldap->event.ctx)) {
+               talloc_free(req);
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       status = cldap_netlogon_recv(req, iconv_convenience, mem_ctx, io);
+       talloc_free(req);
+
+       return status;
+}
+
+
+/*
+  send an empty reply (used on any error, so the client doesn't keep waiting
+  or send the bad request again)
+*/
+NTSTATUS cldap_empty_reply(struct cldap_socket *cldap,
+                          uint32_t message_id,
+                          struct tsocket_address *dest)
+{
+       NTSTATUS status;
+       struct cldap_reply reply;
+       struct ldap_Result result;
+
+       reply.messageid    = message_id;
+       reply.dest         = dest;
+       reply.response     = NULL;
+       reply.result       = &result;
+
+       ZERO_STRUCT(result);
+
+       status = cldap_reply_send(cldap, &reply);
+
+       return status;
+}
+
+/*
+  send an error reply (used on any error, so the client doesn't keep waiting
+  or send the bad request again)
+*/
+NTSTATUS cldap_error_reply(struct cldap_socket *cldap,
+                          uint32_t message_id,
+                          struct tsocket_address *dest,
+                          int resultcode,
+                          const char *errormessage)
+{
+       NTSTATUS status;
+       struct cldap_reply reply;
+       struct ldap_Result result;
+
+       reply.messageid    = message_id;
+       reply.dest         = dest;
+       reply.response     = NULL;
+       reply.result       = &result;
+
+       ZERO_STRUCT(result);
+       result.resultcode       = resultcode;
+       result.errormessage     = errormessage;
+
+       status = cldap_reply_send(cldap, &reply);
+
+       return status;
+}
+
+
+/*
+  send a netlogon reply 
+*/
+NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap,
+                             struct smb_iconv_convenience *iconv_convenience,
+                             uint32_t message_id,
+                             struct tsocket_address *dest,
+                             uint32_t version,
+                             struct netlogon_samlogon_response *netlogon)
+{
+       NTSTATUS status;
+       struct cldap_reply reply;
+       struct ldap_SearchResEntry response;
+       struct ldap_Result result;
+       TALLOC_CTX *tmp_ctx = talloc_new(cldap);
+       DATA_BLOB blob;
+
+       status = push_netlogon_samlogon_response(&blob, tmp_ctx,
+                                                iconv_convenience,
+                                                netlogon);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(tmp_ctx);
+               return status;
+       }
+       reply.messageid    = message_id;
+       reply.dest         = dest;
+       reply.response     = &response;
+       reply.result       = &result;
+
+       ZERO_STRUCT(result);
+
+       response.dn = "";
+       response.num_attributes = 1;
+       response.attributes = talloc(tmp_ctx, struct ldb_message_element);
+       NT_STATUS_HAVE_NO_MEMORY(response.attributes);
+       response.attributes->name = "netlogon";
+       response.attributes->num_values = 1;
+       response.attributes->values = &blob;
+
+       status = cldap_reply_send(cldap, &reply);
+
+       talloc_free(tmp_ctx);
+
+       return status;
+}
+
diff --git a/libcli/cldap/cldap.h b/libcli/cldap/cldap.h
new file mode 100644 (file)
index 0000000..111fa2c
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   a async CLDAP library
+
+   Copyright (C) Andrew Tridgell 2005
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "../libcli/netlogon.h"
+
+struct ldap_message;
+struct tsocket_address;
+struct cldap_socket;
+
+struct cldap_incoming {
+       int recv_errno;
+       uint8_t *buf;
+       size_t len;
+       struct tsocket_address *src;
+       struct ldap_message *ldap_msg;
+};
+
+/*
+ a general cldap search request
+*/
+struct cldap_search {
+       struct {
+               const char *dest_address;
+               uint16_t dest_port;
+               const char *filter;
+               const char * const *attributes;
+               int timeout;
+               int retries;
+       } in;
+       struct {
+               struct ldap_SearchResEntry *response;
+               struct ldap_Result         *result;
+       } out;
+};
+
+NTSTATUS cldap_socket_init(TALLOC_CTX *mem_ctx,
+                          struct tevent_context *ev,
+                          const struct tsocket_address *local_addr,
+                          const struct tsocket_address *remote_addr,
+                          struct cldap_socket **_cldap);
+
+NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap,
+                                   void (*handler)(struct cldap_socket *,
+                                                   void *private_data,
+                                                   struct cldap_incoming *),
+                                   void *private_data);
+struct tevent_req *cldap_search_send(TALLOC_CTX *mem_ctx,
+                                    struct cldap_socket *cldap,
+                                    const struct cldap_search *io);
+NTSTATUS cldap_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+                          struct cldap_search *io);
+NTSTATUS cldap_search(struct cldap_socket *cldap, TALLOC_CTX *mem_ctx,
+                     struct cldap_search *io);
+
+/*
+  a general cldap reply
+*/
+struct cldap_reply {
+       uint32_t messageid;
+       struct tsocket_address *dest;
+       struct ldap_SearchResEntry *response;
+       struct ldap_Result         *result;
+};
+
+NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io);
+
+NTSTATUS cldap_empty_reply(struct cldap_socket *cldap,
+                          uint32_t message_id,
+                          struct tsocket_address *dst);
+NTSTATUS cldap_error_reply(struct cldap_socket *cldap,
+                          uint32_t message_id,
+                          struct tsocket_address *dst,
+                          int resultcode,
+                          const char *errormessage);
+
+/*
+  a netlogon cldap request  
+*/
+struct cldap_netlogon {
+       struct {
+               const char *dest_address;
+               uint16_t dest_port;
+               const char *realm;
+               const char *host;
+               const char *user;
+               const char *domain_guid;
+               const char *domain_sid;
+               int acct_control;
+               uint32_t version;
+               bool map_response;
+       } in;
+       struct {
+               struct netlogon_samlogon_response netlogon;
+       } out;
+};
+
+struct tevent_req *cldap_netlogon_send(TALLOC_CTX *mem_ctx,
+                                      struct cldap_socket *cldap,
+                                      const struct cldap_netlogon *io);
+NTSTATUS cldap_netlogon_recv(struct tevent_req *req,
+                            struct smb_iconv_convenience *iconv_convenience,
+                            TALLOC_CTX *mem_ctx,
+                            struct cldap_netlogon *io);
+NTSTATUS cldap_netlogon(struct cldap_socket *cldap,
+                       struct smb_iconv_convenience *iconv_convenience,
+                       TALLOC_CTX *mem_ctx,
+                       struct cldap_netlogon *io);
+
+NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap,
+                             struct smb_iconv_convenience *iconv_convenience,
+                             uint32_t message_id,
+                             struct tsocket_address *dst,
+                             uint32_t version,
+                             struct netlogon_samlogon_response *netlogon);
+
diff --git a/libcli/cldap/config.mk b/libcli/cldap/config.mk
new file mode 100644 (file)
index 0000000..a4a75b4
--- /dev/null
@@ -0,0 +1,7 @@
+[SUBSYSTEM::LIBCLI_CLDAP]
+PUBLIC_DEPENDENCIES = LIBCLI_LDAP
+PRIVATE_DEPENDENCIES = LIBTSOCKET LIBSAMBA-UTIL UTIL_TEVENT LIBLDB LIBCLI_NETLOGON
+
+LIBCLI_CLDAP_OBJ_FILES = ../libcli/cldap/cldap.o
+# PUBLIC_HEADERS += ../libcli/cldap/cldap.h
+
index 4e8eddcb0be5dc65171b02b39d9ea6662146d311..7d87b1cd5eb4f122a393ea75500045d793af17bc 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "includes.h"
 #include "librpc/gen_ndr/ndr_security.h"
-#include "libcli/security/security.h"
+#include "libcli/security/dom_sid.h"
 
 #define  SEC_ACE_HEADER_SIZE (2 * sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t))
 
index 45640773b009448c977487d226dddca76a56aea7..9373ef581266877ee0253235e02500fa09afcfa7 100644 (file)
@@ -21,7 +21,8 @@
  */
 
 #include "includes.h"
-#include "libcli/security/security.h"
+#include "librpc/gen_ndr/ndr_security.h"
+#include "libcli/security/secace.h"
 
 #define  SEC_ACL_HEADER_SIZE (2 * sizeof(uint16_t) + sizeof(uint32_t))
 
index 1044ab351a125f55bc2dba637a3da552eff46fb2..5104c3ee02968880e72879a84115a55f6d3a572d 100644 (file)
@@ -133,6 +133,7 @@ static const struct werror_code_struct dos_errs[] =
        { "WERR_NO_SPOOL_SPACE", WERR_NO_SPOOL_SPACE },
        { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE },
        { "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS },
+       { "WERR_DEVICE_NOT_CONNECTED", WERR_DEVICE_NOT_CONNECTED },
        { "WERR_NOT_FOUND", WERR_NOT_FOUND },
        { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE },
        { "WERR_INVALID_USER_BUFFER", WERR_INVALID_USER_BUFFER },
index 15251a44fc8e0d14721b6c07254ad6e81f153320..d92232706a61c9916309f84ad5668173bab6cda9 100644 (file)
@@ -114,6 +114,7 @@ typedef uint32_t WERROR;
 #define WERR_SERVICE_ALREADY_RUNNING W_ERROR(1056)
 #define WERR_SERVICE_DISABLED W_ERROR(1058)
 #define WERR_SERVICE_NEVER_STARTED W_ERROR(1077)
+#define WERR_DEVICE_NOT_CONNECTED W_ERROR(1167)
 #define WERR_NOT_FOUND W_ERROR(1168)
 #define WERR_INVALID_COMPUTERNAME W_ERROR(1210)
 #define WERR_INVALID_DOMAINNAME W_ERROR(1212)
index 2aa42b93bfb092a9d79aaa135877c5f9d367fe0b..1e94a2a63c45cf70ab5fdf8ab58f286a3279a42c 100644 (file)
@@ -14,7 +14,7 @@ NTSTATUS rpccli_spoolss_EnumPrinters(struct rpc_pipe_client *cli,
                                     DATA_BLOB *buffer /* [in] [unique] */,
                                     uint32_t offered /* [in]  */,
                                     uint32_t *count /* [out] [ref] */,
-                                    union spoolss_PrinterInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                    union spoolss_PrinterInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                     uint32_t *needed /* [out] [ref] */,
                                     WERROR *werror)
 {
@@ -52,9 +52,7 @@ NTSTATUS rpccli_spoolss_EnumPrinters(struct rpc_pipe_client *cli,
 
        /* Return variables */
        *count = *r.out.count;
-       if (info && r.out.info) {
-               memcpy(info, r.out.info, *count * sizeof(*info));
-       }
+       *info = *r.out.info;
        *needed = *r.out.needed;
 
        /* Return result */
@@ -231,7 +229,7 @@ NTSTATUS rpccli_spoolss_EnumJobs(struct rpc_pipe_client *cli,
                                 DATA_BLOB *buffer /* [in] [unique] */,
                                 uint32_t offered /* [in]  */,
                                 uint32_t *count /* [out] [ref] */,
-                                union spoolss_JobInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                union spoolss_JobInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                 uint32_t *needed /* [out] [ref] */,
                                 WERROR *werror)
 {
@@ -270,9 +268,7 @@ NTSTATUS rpccli_spoolss_EnumJobs(struct rpc_pipe_client *cli,
 
        /* Return variables */
        *count = *r.out.count;
-       if (info && r.out.info) {
-               memcpy(info, r.out.info, *count * sizeof(*info));
-       }
+       *info = *r.out.info;
        *needed = *r.out.needed;
 
        /* Return result */
@@ -526,7 +522,7 @@ NTSTATUS rpccli_spoolss_EnumPrinterDrivers(struct rpc_pipe_client *cli,
                                           DATA_BLOB *buffer /* [in] [unique] */,
                                           uint32_t offered /* [in]  */,
                                           uint32_t *count /* [out] [ref] */,
-                                          union spoolss_DriverInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                          union spoolss_DriverInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                           uint32_t *needed /* [out] [ref] */,
                                           WERROR *werror)
 {
@@ -564,9 +560,7 @@ NTSTATUS rpccli_spoolss_EnumPrinterDrivers(struct rpc_pipe_client *cli,
 
        /* Return variables */
        *count = *r.out.count;
-       if (info && r.out.info) {
-               memcpy(info, r.out.info, *count * sizeof(*info));
-       }
+       *info = *r.out.info;
        *needed = *r.out.needed;
 
        /* Return result */
@@ -779,7 +773,7 @@ NTSTATUS rpccli_spoolss_EnumPrintProcessors(struct rpc_pipe_client *cli,
                                            DATA_BLOB *buffer /* [in] [unique] */,
                                            uint32_t offered /* [in]  */,
                                            uint32_t *count /* [out] [ref] */,
-                                           union spoolss_PrintProcessorInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                           union spoolss_PrintProcessorInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                            uint32_t *needed /* [out] [ref] */,
                                            WERROR *werror)
 {
@@ -817,9 +811,7 @@ NTSTATUS rpccli_spoolss_EnumPrintProcessors(struct rpc_pipe_client *cli,
 
        /* Return variables */
        *count = *r.out.count;
-       if (info && r.out.info) {
-               memcpy(info, r.out.info, *count * sizeof(*info));
-       }
+       *info = *r.out.info;
        *needed = *r.out.needed;
 
        /* Return result */
@@ -1310,8 +1302,8 @@ NTSTATUS rpccli_spoolss_GetPrinterData(struct rpc_pipe_client *cli,
                                       struct policy_handle *handle /* [in] [ref] */,
                                       const char *value_name /* [in] [charset(UTF16)] */,
                                       uint32_t offered /* [in]  */,
-                                      enum spoolss_PrinterDataType *type /* [out] [ref] */,
-                                      union spoolss_PrinterData data /* [out] [subcontext_size(offered),subcontext(4),switch_is(*type)] */,
+                                      enum winreg_Type *type /* [out] [ref] */,
+                                      union spoolss_PrinterData *data /* [out] [subcontext_size(offered),ref,subcontext(4),switch_is(*type)] */,
                                       uint32_t *needed /* [out] [ref] */,
                                       WERROR *werror)
 {
@@ -1347,7 +1339,7 @@ NTSTATUS rpccli_spoolss_GetPrinterData(struct rpc_pipe_client *cli,
 
        /* Return variables */
        *type = *r.out.type;
-       return NT_STATUS_NOT_SUPPORTED;
+       *data = *r.out.data;
        *needed = *r.out.needed;
 
        /* Return result */
@@ -1362,7 +1354,7 @@ NTSTATUS rpccli_spoolss_SetPrinterData(struct rpc_pipe_client *cli,
                                       TALLOC_CTX *mem_ctx,
                                       struct policy_handle *handle /* [in] [ref] */,
                                       const char *value_name /* [in] [charset(UTF16)] */,
-                                      enum spoolss_PrinterDataType type /* [in]  */,
+                                      enum winreg_Type type /* [in]  */,
                                       union spoolss_PrinterData data /* [in] [subcontext(4),switch_is(type)] */,
                                       uint32_t _offered /* [in] [value(ndr_size_spoolss_PrinterData(&data,type,ndr->iconv_convenience,flags))] */,
                                       WERROR *werror)
@@ -1699,7 +1691,7 @@ NTSTATUS rpccli_spoolss_EnumForms(struct rpc_pipe_client *cli,
                                  DATA_BLOB *buffer /* [in] [unique] */,
                                  uint32_t offered /* [in]  */,
                                  uint32_t *count /* [out] [ref] */,
-                                 union spoolss_FormInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                 union spoolss_FormInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                  uint32_t *needed /* [out] [ref] */,
                                  WERROR *werror)
 {
@@ -1736,9 +1728,7 @@ NTSTATUS rpccli_spoolss_EnumForms(struct rpc_pipe_client *cli,
 
        /* Return variables */
        *count = *r.out.count;
-       if (info && r.out.info) {
-               memcpy(info, r.out.info, *count * sizeof(*info));
-       }
+       *info = *r.out.info;
        *needed = *r.out.needed;
 
        /* Return result */
@@ -1756,7 +1746,7 @@ NTSTATUS rpccli_spoolss_EnumPorts(struct rpc_pipe_client *cli,
                                  DATA_BLOB *buffer /* [in] [unique] */,
                                  uint32_t offered /* [in]  */,
                                  uint32_t *count /* [out] [ref] */,
-                                 union spoolss_PortInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                 union spoolss_PortInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                  uint32_t *needed /* [out] [ref] */,
                                  WERROR *werror)
 {
@@ -1793,9 +1783,7 @@ NTSTATUS rpccli_spoolss_EnumPorts(struct rpc_pipe_client *cli,
 
        /* Return variables */
        *count = *r.out.count;
-       if (info && r.out.info) {
-               memcpy(info, r.out.info, *count * sizeof(*info));
-       }
+       *info = *r.out.info;
        *needed = *r.out.needed;
 
        /* Return result */
@@ -1813,7 +1801,7 @@ NTSTATUS rpccli_spoolss_EnumMonitors(struct rpc_pipe_client *cli,
                                     DATA_BLOB *buffer /* [in] [unique] */,
                                     uint32_t offered /* [in]  */,
                                     uint32_t *count /* [out] [ref] */,
-                                    union spoolss_MonitorInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                    union spoolss_MonitorInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                     uint32_t *needed /* [out] [ref] */,
                                     WERROR *werror)
 {
@@ -1850,9 +1838,7 @@ NTSTATUS rpccli_spoolss_EnumMonitors(struct rpc_pipe_client *cli,
 
        /* Return variables */
        *count = *r.out.count;
-       if (info && r.out.info) {
-               memcpy(info, r.out.info, *count * sizeof(*info));
-       }
+       *info = *r.out.info;
        *needed = *r.out.needed;
 
        /* Return result */
@@ -2445,12 +2431,25 @@ NTSTATUS rpccli_spoolss_DeletePrintProvidor(struct rpc_pipe_client *cli,
 
 NTSTATUS rpccli_spoolss_EnumPrintProcDataTypes(struct rpc_pipe_client *cli,
                                               TALLOC_CTX *mem_ctx,
+                                              const char *servername /* [in] [unique,charset(UTF16)] */,
+                                              const char *print_processor_name /* [in] [unique,charset(UTF16)] */,
+                                              uint32_t level /* [in]  */,
+                                              DATA_BLOB *buffer /* [in] [unique] */,
+                                              uint32_t offered /* [in]  */,
+                                              uint32_t *count /* [out] [ref] */,
+                                              union spoolss_PrintProcDataTypesInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
+                                              uint32_t *needed /* [out] [ref] */,
                                               WERROR *werror)
 {
        struct spoolss_EnumPrintProcDataTypes r;
        NTSTATUS status;
 
        /* In parameters */
+       r.in.servername = servername;
+       r.in.print_processor_name = print_processor_name;
+       r.in.level = level;
+       r.in.buffer = buffer;
+       r.in.offered = offered;
 
        if (DEBUGLEVEL >= 10) {
                NDR_PRINT_IN_DEBUG(spoolss_EnumPrintProcDataTypes, &r);
@@ -2475,6 +2474,9 @@ NTSTATUS rpccli_spoolss_EnumPrintProcDataTypes(struct rpc_pipe_client *cli,
        }
 
        /* Return variables */
+       *count = *r.out.count;
+       *info = *r.out.info;
+       *needed = *r.out.needed;
 
        /* Return result */
        if (werror) {
@@ -3424,8 +3426,8 @@ NTSTATUS rpccli_spoolss_EnumPrinterData(struct rpc_pipe_client *cli,
                                        const char *value_name /* [out] [charset(UTF16),size_is(value_offered/2)] */,
                                        uint32_t value_offered /* [in]  */,
                                        uint32_t *value_needed /* [out] [ref] */,
-                                       uint32_t *printerdata_type /* [out] [ref] */,
-                                       DATA_BLOB *buffer /* [out] [ref] */,
+                                       enum winreg_Type *type /* [out] [ref] */,
+                                       uint8_t *data /* [out] [ref,flag(LIBNDR_PRINT_ARRAY_HEX),size_is(data_offered)] */,
                                        uint32_t data_offered /* [in]  */,
                                        uint32_t *data_needed /* [out] [ref] */,
                                        WERROR *werror)
@@ -3464,8 +3466,8 @@ NTSTATUS rpccli_spoolss_EnumPrinterData(struct rpc_pipe_client *cli,
        /* Return variables */
        memcpy(CONST_DISCARD(char *, value_name), r.out.value_name, r.in.value_offered / 2 * sizeof(*value_name));
        *value_needed = *r.out.value_needed;
-       *printerdata_type = *r.out.printerdata_type;
-       *buffer = *r.out.buffer;
+       *type = *r.out.type;
+       memcpy(data, r.out.data, r.in.data_offered * sizeof(*data));
        *data_needed = *r.out.data_needed;
 
        /* Return result */
@@ -3649,7 +3651,7 @@ NTSTATUS rpccli_spoolss_SetPrinterDataEx(struct rpc_pipe_client *cli,
                                         struct policy_handle *handle /* [in] [ref] */,
                                         const char *key_name /* [in] [charset(UTF16)] */,
                                         const char *value_name /* [in] [charset(UTF16)] */,
-                                        uint32_t type /* [in]  */,
+                                        enum winreg_Type type /* [in]  */,
                                         uint8_t *buffer /* [in] [ref,size_is(offered)] */,
                                         uint32_t offered /* [in]  */,
                                         WERROR *werror)
@@ -3702,7 +3704,7 @@ NTSTATUS rpccli_spoolss_GetPrinterDataEx(struct rpc_pipe_client *cli,
                                         struct policy_handle *handle /* [in] [ref] */,
                                         const char *key_name /* [in] [charset(UTF16)] */,
                                         const char *value_name /* [in] [charset(UTF16)] */,
-                                        uint32_t *type /* [out] [ref] */,
+                                        enum winreg_Type *type /* [out] [ref] */,
                                         uint8_t *buffer /* [out] [ref,size_is(offered)] */,
                                         uint32_t offered /* [in]  */,
                                         uint32_t *needed /* [out] [ref] */,
@@ -3756,10 +3758,10 @@ NTSTATUS rpccli_spoolss_EnumPrinterDataEx(struct rpc_pipe_client *cli,
                                          TALLOC_CTX *mem_ctx,
                                          struct policy_handle *handle /* [in] [ref] */,
                                          const char *key_name /* [in] [charset(UTF16)] */,
-                                         uint8_t *buffer /* [out] [ref,size_is(offered)] */,
                                          uint32_t offered /* [in]  */,
-                                         uint32_t *needed /* [out] [ref] */,
                                          uint32_t *count /* [out] [ref] */,
+                                         struct spoolss_PrinterEnumValues **info /* [out] [ref,size_is(,*count)] */,
+                                         uint32_t *needed /* [out] [ref] */,
                                          WERROR *werror)
 {
        struct spoolss_EnumPrinterDataEx r;
@@ -3793,9 +3795,9 @@ NTSTATUS rpccli_spoolss_EnumPrinterDataEx(struct rpc_pipe_client *cli,
        }
 
        /* Return variables */
-       memcpy(buffer, r.out.buffer, r.in.offered * sizeof(*buffer));
-       *needed = *r.out.needed;
        *count = *r.out.count;
+       *info = *r.out.info;
+       *needed = *r.out.needed;
 
        /* Return result */
        if (werror) {
@@ -3809,8 +3811,8 @@ NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli,
                                       TALLOC_CTX *mem_ctx,
                                       struct policy_handle *handle /* [in] [ref] */,
                                       const char *key_name /* [in] [charset(UTF16)] */,
-                                      uint16_t *key_buffer /* [out] [ref,size_is(key_buffer_size/2)] */,
-                                      uint32_t key_buffer_size /* [in]  */,
+                                      const char ** *key_buffer /* [out] [subcontext_size(offered),ref,subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */,
+                                      uint32_t offered /* [in]  */,
                                       uint32_t *needed /* [out] [ref] */,
                                       WERROR *werror)
 {
@@ -3820,7 +3822,7 @@ NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli,
        /* In parameters */
        r.in.handle = handle;
        r.in.key_name = key_name;
-       r.in.key_buffer_size = key_buffer_size;
+       r.in.offered = offered;
 
        if (DEBUGLEVEL >= 10) {
                NDR_PRINT_IN_DEBUG(spoolss_EnumPrinterKey, &r);
@@ -3845,7 +3847,7 @@ NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli,
        }
 
        /* Return variables */
-       memcpy(key_buffer, r.out.key_buffer, r.in.key_buffer_size / 2 * sizeof(*key_buffer));
+       *key_buffer = *r.out.key_buffer;
        *needed = *r.out.needed;
 
        /* Return result */
index 83b2e28729ec4292cf39ba2fbb7ffa059d64b233..eb86e8c6a08d50a0366b3f4e09cb2ec78d75b27f 100644 (file)
@@ -9,7 +9,7 @@ NTSTATUS rpccli_spoolss_EnumPrinters(struct rpc_pipe_client *cli,
                                     DATA_BLOB *buffer /* [in] [unique] */,
                                     uint32_t offered /* [in]  */,
                                     uint32_t *count /* [out] [ref] */,
-                                    union spoolss_PrinterInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                    union spoolss_PrinterInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                     uint32_t *needed /* [out] [ref] */,
                                     WERROR *werror);
 NTSTATUS rpccli_spoolss_OpenPrinter(struct rpc_pipe_client *cli,
@@ -46,7 +46,7 @@ NTSTATUS rpccli_spoolss_EnumJobs(struct rpc_pipe_client *cli,
                                 DATA_BLOB *buffer /* [in] [unique] */,
                                 uint32_t offered /* [in]  */,
                                 uint32_t *count /* [out] [ref] */,
-                                union spoolss_JobInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                union spoolss_JobInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                 uint32_t *needed /* [out] [ref] */,
                                 WERROR *werror);
 NTSTATUS rpccli_spoolss_AddPrinter(struct rpc_pipe_client *cli,
@@ -86,7 +86,7 @@ NTSTATUS rpccli_spoolss_EnumPrinterDrivers(struct rpc_pipe_client *cli,
                                           DATA_BLOB *buffer /* [in] [unique] */,
                                           uint32_t offered /* [in]  */,
                                           uint32_t *count /* [out] [ref] */,
-                                          union spoolss_DriverInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                          union spoolss_DriverInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                           uint32_t *needed /* [out] [ref] */,
                                           WERROR *werror);
 NTSTATUS rpccli_spoolss_GetPrinterDriver(struct rpc_pipe_client *cli,
@@ -123,7 +123,7 @@ NTSTATUS rpccli_spoolss_EnumPrintProcessors(struct rpc_pipe_client *cli,
                                            DATA_BLOB *buffer /* [in] [unique] */,
                                            uint32_t offered /* [in]  */,
                                            uint32_t *count /* [out] [ref] */,
-                                           union spoolss_PrintProcessorInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                           union spoolss_PrintProcessorInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                            uint32_t *needed /* [out] [ref] */,
                                            WERROR *werror);
 NTSTATUS rpccli_spoolss_GetPrintProcessorDirectory(struct rpc_pipe_client *cli,
@@ -191,15 +191,15 @@ NTSTATUS rpccli_spoolss_GetPrinterData(struct rpc_pipe_client *cli,
                                       struct policy_handle *handle /* [in] [ref] */,
                                       const char *value_name /* [in] [charset(UTF16)] */,
                                       uint32_t offered /* [in]  */,
-                                      enum spoolss_PrinterDataType *type /* [out] [ref] */,
-                                      union spoolss_PrinterData data /* [out] [subcontext_size(offered),subcontext(4),switch_is(*type)] */,
+                                      enum winreg_Type *type /* [out] [ref] */,
+                                      union spoolss_PrinterData *data /* [out] [subcontext_size(offered),ref,subcontext(4),switch_is(*type)] */,
                                       uint32_t *needed /* [out] [ref] */,
                                       WERROR *werror);
 NTSTATUS rpccli_spoolss_SetPrinterData(struct rpc_pipe_client *cli,
                                       TALLOC_CTX *mem_ctx,
                                       struct policy_handle *handle /* [in] [ref] */,
                                       const char *value_name /* [in] [charset(UTF16)] */,
-                                      enum spoolss_PrinterDataType type /* [in]  */,
+                                      enum winreg_Type type /* [in]  */,
                                       union spoolss_PrinterData data /* [in] [subcontext(4),switch_is(type)] */,
                                       uint32_t _offered /* [in] [value(ndr_size_spoolss_PrinterData(&data,type,ndr->iconv_convenience,flags))] */,
                                       WERROR *werror);
@@ -245,7 +245,7 @@ NTSTATUS rpccli_spoolss_EnumForms(struct rpc_pipe_client *cli,
                                  DATA_BLOB *buffer /* [in] [unique] */,
                                  uint32_t offered /* [in]  */,
                                  uint32_t *count /* [out] [ref] */,
-                                 union spoolss_FormInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                 union spoolss_FormInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                  uint32_t *needed /* [out] [ref] */,
                                  WERROR *werror);
 NTSTATUS rpccli_spoolss_EnumPorts(struct rpc_pipe_client *cli,
@@ -255,7 +255,7 @@ NTSTATUS rpccli_spoolss_EnumPorts(struct rpc_pipe_client *cli,
                                  DATA_BLOB *buffer /* [in] [unique] */,
                                  uint32_t offered /* [in]  */,
                                  uint32_t *count /* [out] [ref] */,
-                                 union spoolss_PortInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                 union spoolss_PortInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                  uint32_t *needed /* [out] [ref] */,
                                  WERROR *werror);
 NTSTATUS rpccli_spoolss_EnumMonitors(struct rpc_pipe_client *cli,
@@ -265,7 +265,7 @@ NTSTATUS rpccli_spoolss_EnumMonitors(struct rpc_pipe_client *cli,
                                     DATA_BLOB *buffer /* [in] [unique] */,
                                     uint32_t offered /* [in]  */,
                                     uint32_t *count /* [out] [ref] */,
-                                    union spoolss_MonitorInfo *info /* [out] [unique,switch_is(level),size_is(*count)] */,
+                                    union spoolss_MonitorInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
                                     uint32_t *needed /* [out] [ref] */,
                                     WERROR *werror);
 NTSTATUS rpccli_spoolss_AddPort(struct rpc_pipe_client *cli,
@@ -315,6 +315,14 @@ NTSTATUS rpccli_spoolss_DeletePrintProvidor(struct rpc_pipe_client *cli,
                                            WERROR *werror);
 NTSTATUS rpccli_spoolss_EnumPrintProcDataTypes(struct rpc_pipe_client *cli,
                                               TALLOC_CTX *mem_ctx,
+                                              const char *servername /* [in] [unique,charset(UTF16)] */,
+                                              const char *print_processor_name /* [in] [unique,charset(UTF16)] */,
+                                              uint32_t level /* [in]  */,
+                                              DATA_BLOB *buffer /* [in] [unique] */,
+                                              uint32_t offered /* [in]  */,
+                                              uint32_t *count /* [out] [ref] */,
+                                              union spoolss_PrintProcDataTypesInfo **info /* [out] [ref,switch_is(level),size_is(,*count)] */,
+                                              uint32_t *needed /* [out] [ref] */,
                                               WERROR *werror);
 NTSTATUS rpccli_spoolss_ResetPrinter(struct rpc_pipe_client *cli,
                                     TALLOC_CTX *mem_ctx,
@@ -438,8 +446,8 @@ NTSTATUS rpccli_spoolss_EnumPrinterData(struct rpc_pipe_client *cli,
                                        const char *value_name /* [out] [charset(UTF16),size_is(value_offered/2)] */,
                                        uint32_t value_offered /* [in]  */,
                                        uint32_t *value_needed /* [out] [ref] */,
-                                       uint32_t *printerdata_type /* [out] [ref] */,
-                                       DATA_BLOB *buffer /* [out] [ref] */,
+                                       enum winreg_Type *type /* [out] [ref] */,
+                                       uint8_t *data /* [out] [ref,flag(LIBNDR_PRINT_ARRAY_HEX),size_is(data_offered)] */,
                                        uint32_t data_offered /* [in]  */,
                                        uint32_t *data_needed /* [out] [ref] */,
                                        WERROR *werror);
@@ -462,7 +470,7 @@ NTSTATUS rpccli_spoolss_SetPrinterDataEx(struct rpc_pipe_client *cli,
                                         struct policy_handle *handle /* [in] [ref] */,
                                         const char *key_name /* [in] [charset(UTF16)] */,
                                         const char *value_name /* [in] [charset(UTF16)] */,
-                                        uint32_t type /* [in]  */,
+                                        enum winreg_Type type /* [in]  */,
                                         uint8_t *buffer /* [in] [ref,size_is(offered)] */,
                                         uint32_t offered /* [in]  */,
                                         WERROR *werror);
@@ -471,7 +479,7 @@ NTSTATUS rpccli_spoolss_GetPrinterDataEx(struct rpc_pipe_client *cli,
                                         struct policy_handle *handle /* [in] [ref] */,
                                         const char *key_name /* [in] [charset(UTF16)] */,
                                         const char *value_name /* [in] [charset(UTF16)] */,
-                                        uint32_t *type /* [out] [ref] */,
+                                        enum winreg_Type *type /* [out] [ref] */,
                                         uint8_t *buffer /* [out] [ref,size_is(offered)] */,
                                         uint32_t offered /* [in]  */,
                                         uint32_t *needed /* [out] [ref] */,
@@ -480,17 +488,17 @@ NTSTATUS rpccli_spoolss_EnumPrinterDataEx(struct rpc_pipe_client *cli,
                                          TALLOC_CTX *mem_ctx,
                                          struct policy_handle *handle /* [in] [ref] */,
                                          const char *key_name /* [in] [charset(UTF16)] */,
-                                         uint8_t *buffer /* [out] [ref,size_is(offered)] */,
                                          uint32_t offered /* [in]  */,
-                                         uint32_t *needed /* [out] [ref] */,
                                          uint32_t *count /* [out] [ref] */,
+                                         struct spoolss_PrinterEnumValues **info /* [out] [ref,size_is(,*count)] */,
+                                         uint32_t *needed /* [out] [ref] */,
                                          WERROR *werror);
 NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli,
                                       TALLOC_CTX *mem_ctx,
                                       struct policy_handle *handle /* [in] [ref] */,
                                       const char *key_name /* [in] [charset(UTF16)] */,
-                                      uint16_t *key_buffer /* [out] [ref,size_is(key_buffer_size/2)] */,
-                                      uint32_t key_buffer_size /* [in]  */,
+                                      const char ** *key_buffer /* [out] [subcontext_size(offered),ref,subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */,
+                                      uint32_t offered /* [in]  */,
                                       uint32_t *needed /* [out] [ref] */,
                                       WERROR *werror);
 NTSTATUS rpccli_spoolss_DeletePrinterDataEx(struct rpc_pipe_client *cli,
index ee7c9933c21c529b84d1f7d5501b0658910be6c8..426ade259c72ef1354cec3f26ab90f159769b812 100644 (file)
@@ -1856,7 +1856,6 @@ _PUBLIC_ void ndr_print_package_PrimaryKerberosKey4(struct ndr_print *ndr, const
 static enum ndr_err_code ndr_push_package_PrimaryKerberosCtr4(struct ndr_push *ndr, int ndr_flags, const struct package_PrimaryKerberosCtr4 *r)
 {
        uint32_t cntr_keys_0;
-       uint32_t cntr_service_keys_0;
        uint32_t cntr_old_keys_0;
        uint32_t cntr_older_keys_0;
        if (ndr_flags & NDR_SCALARS) {
index 31220edc6223e25ec63ecff77578c5817441dd13..f5b161a9c7e7c98a186f5e34377a3a387dac3c29 100644 (file)
@@ -224,7 +224,87 @@ _PUBLIC_ void ndr_print_spoolss_MinorVersion(struct ndr_print *ndr, const char *
        ndr_print_enum(ndr, name, "ENUM", val, r);
 }
 
-static enum ndr_err_code ndr_push_spoolss_PrinterInfo0(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterInfo0 *r)
+static enum ndr_err_code ndr_push_spoolss_PrinterStatus(struct ndr_push *ndr, int ndr_flags, uint32_t r)
+{
+       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
+       return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_spoolss_PrinterStatus(struct ndr_pull *ndr, int ndr_flags, uint32_t *r)
+{
+       uint32_t v;
+       NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+       *r = v;
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_spoolss_PrinterStatus(struct ndr_print *ndr, const char *name, uint32_t r)
+{
+       ndr_print_uint32(ndr, name, r);
+       ndr->depth++;
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PAUSED", PRINTER_STATUS_PAUSED, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_ERROR", PRINTER_STATUS_ERROR, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PENDING_DELETION", PRINTER_STATUS_PENDING_DELETION, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PAPER_JAM", PRINTER_STATUS_PAPER_JAM, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PAPER_OUT", PRINTER_STATUS_PAPER_OUT, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_MANUAL_FEED", PRINTER_STATUS_MANUAL_FEED, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PAPER_PROBLEM", PRINTER_STATUS_PAPER_PROBLEM, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_OFFLINE", PRINTER_STATUS_OFFLINE, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_IO_ACTIVE", PRINTER_STATUS_IO_ACTIVE, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_BUSY", PRINTER_STATUS_BUSY, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PRINTING", PRINTER_STATUS_PRINTING, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_OUTPUT_BIN_FULL", PRINTER_STATUS_OUTPUT_BIN_FULL, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_NOT_AVAILABLE", PRINTER_STATUS_NOT_AVAILABLE, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_WAITING", PRINTER_STATUS_WAITING, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PROCESSING", PRINTER_STATUS_PROCESSING, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_INITIALIZING", PRINTER_STATUS_INITIALIZING, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_WARMING_UP", PRINTER_STATUS_WARMING_UP, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_TONER_LOW", PRINTER_STATUS_TONER_LOW, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_NO_TONER", PRINTER_STATUS_NO_TONER, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PAGE_PUNT", PRINTER_STATUS_PAGE_PUNT, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_USER_INTERVENTION", PRINTER_STATUS_USER_INTERVENTION, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_OUT_OF_MEMORY", PRINTER_STATUS_OUT_OF_MEMORY, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_DOOR_OPEN", PRINTER_STATUS_DOOR_OPEN, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_SERVER_UNKNOWN", PRINTER_STATUS_SERVER_UNKNOWN, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_POWER_SAVE", PRINTER_STATUS_POWER_SAVE, r);
+       ndr->depth--;
+}
+
+static enum ndr_err_code ndr_push_spoolss_JobStatus(struct ndr_push *ndr, int ndr_flags, uint32_t r)
+{
+       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
+       return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_spoolss_JobStatus(struct ndr_pull *ndr, int ndr_flags, uint32_t *r)
+{
+       uint32_t v;
+       NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+       *r = v;
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_spoolss_JobStatus(struct ndr_print *ndr, const char *name, uint32_t r)
+{
+       ndr_print_uint32(ndr, name, r);
+       ndr->depth++;
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_PAUSED", JOB_STATUS_PAUSED, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_ERROR", JOB_STATUS_ERROR, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_DELETING", JOB_STATUS_DELETING, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_SPOOLING", JOB_STATUS_SPOOLING, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_PRINTING", JOB_STATUS_PRINTING, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_OFFLINE", JOB_STATUS_OFFLINE, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_PAPEROUT", JOB_STATUS_PAPEROUT, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_PRINTED", JOB_STATUS_PRINTED, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_DELETED", JOB_STATUS_DELETED, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_BLOCKED_DEVQ", JOB_STATUS_BLOCKED_DEVQ, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_USER_INTERVENTION", JOB_STATUS_USER_INTERVENTION, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_RESTART", JOB_STATUS_RESTART, r);
+       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_COMPLETE", JOB_STATUS_COMPLETE, r);
+       ndr->depth--;
+}
+
+_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));
@@ -253,13 +333,13 @@ static enum ndr_err_code ndr_push_spoolss_PrinterInfo0(struct ndr_push *ndr, int
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->session_counter));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->num_error_out_of_paper));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->num_error_not_ready));
-               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->job_error));
+               NDR_CHECK(ndr_push_spoolss_JobStatus(ndr, NDR_SCALARS, r->job_error));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->number_of_processors));
                NDR_CHECK(ndr_push_spoolss_ProcessorType(ndr, NDR_SCALARS, r->processor_type));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->high_part_total_bytes));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->change_id));
                NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->last_error));
-               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->status));
+               NDR_CHECK(ndr_push_spoolss_PrinterStatus(ndr, NDR_SCALARS, r->status));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->enumerate_network_printers));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->c_setprinter));
                NDR_CHECK(ndr_push_spoolss_ProcessorArchitecture(ndr, NDR_SCALARS, r->processor_architecture));
@@ -291,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;
@@ -336,13 +416,13 @@ static enum ndr_err_code ndr_pull_spoolss_PrinterInfo0(struct ndr_pull *ndr, int
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->session_counter));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_error_out_of_paper));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_error_not_ready));
-               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->job_error));
+               NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->job_error));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->number_of_processors));
                NDR_CHECK(ndr_pull_spoolss_ProcessorType(ndr, NDR_SCALARS, &r->processor_type));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->high_part_total_bytes));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->change_id));
                NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->last_error));
-               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->status));
+               NDR_CHECK(ndr_pull_spoolss_PrinterStatus(ndr, NDR_SCALARS, &r->status));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->enumerate_network_printers));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->c_setprinter));
                NDR_CHECK(ndr_pull_spoolss_ProcessorArchitecture(ndr, NDR_SCALARS, &r->processor_architecture));
@@ -415,13 +495,13 @@ _PUBLIC_ void ndr_print_spoolss_PrinterInfo0(struct ndr_print *ndr, const char *
        ndr_print_uint32(ndr, "session_counter", r->session_counter);
        ndr_print_uint32(ndr, "num_error_out_of_paper", r->num_error_out_of_paper);
        ndr_print_uint32(ndr, "num_error_not_ready", r->num_error_not_ready);
-       ndr_print_uint32(ndr, "job_error", r->job_error);
+       ndr_print_spoolss_JobStatus(ndr, "job_error", r->job_error);
        ndr_print_uint32(ndr, "number_of_processors", r->number_of_processors);
        ndr_print_spoolss_ProcessorType(ndr, "processor_type", r->processor_type);
        ndr_print_uint32(ndr, "high_part_total_bytes", r->high_part_total_bytes);
        ndr_print_uint32(ndr, "change_id", r->change_id);
        ndr_print_WERROR(ndr, "last_error", r->last_error);
-       ndr_print_uint32(ndr, "status", r->status);
+       ndr_print_spoolss_PrinterStatus(ndr, "status", r->status);
        ndr_print_uint32(ndr, "enumerate_network_printers", r->enumerate_network_printers);
        ndr_print_uint32(ndr, "c_setprinter", r->c_setprinter);
        ndr_print_spoolss_ProcessorArchitecture(ndr, "processor_architecture", r->processor_architecture);
@@ -432,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));
@@ -678,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));
@@ -734,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;
@@ -858,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));
@@ -895,53 +985,7 @@ _PUBLIC_ void ndr_print_spoolss_PrinterAttributes(struct ndr_print *ndr, const c
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_PrinterStatus(struct ndr_push *ndr, int ndr_flags, uint32_t r)
-{
-       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
-       return NDR_ERR_SUCCESS;
-}
-
-static enum ndr_err_code ndr_pull_spoolss_PrinterStatus(struct ndr_pull *ndr, int ndr_flags, uint32_t *r)
-{
-       uint32_t v;
-       NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
-       *r = v;
-       return NDR_ERR_SUCCESS;
-}
-
-_PUBLIC_ void ndr_print_spoolss_PrinterStatus(struct ndr_print *ndr, const char *name, uint32_t r)
-{
-       ndr_print_uint32(ndr, name, r);
-       ndr->depth++;
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PAUSED", PRINTER_STATUS_PAUSED, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_ERROR", PRINTER_STATUS_ERROR, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PENDING_DELETION", PRINTER_STATUS_PENDING_DELETION, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PAPER_JAM", PRINTER_STATUS_PAPER_JAM, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PAPER_OUT", PRINTER_STATUS_PAPER_OUT, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_MANUAL_FEED", PRINTER_STATUS_MANUAL_FEED, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PAPER_PROBLEM", PRINTER_STATUS_PAPER_PROBLEM, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_OFFLINE", PRINTER_STATUS_OFFLINE, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_IO_ACTIVE", PRINTER_STATUS_IO_ACTIVE, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_BUSY", PRINTER_STATUS_BUSY, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PRINTING", PRINTER_STATUS_PRINTING, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_OUTPUT_BIN_FULL", PRINTER_STATUS_OUTPUT_BIN_FULL, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_NOT_AVAILABLE", PRINTER_STATUS_NOT_AVAILABLE, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_WAITING", PRINTER_STATUS_WAITING, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PROCESSING", PRINTER_STATUS_PROCESSING, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_INITIALIZING", PRINTER_STATUS_INITIALIZING, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_WARMING_UP", PRINTER_STATUS_WARMING_UP, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_TONER_LOW", PRINTER_STATUS_TONER_LOW, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_NO_TONER", PRINTER_STATUS_NO_TONER, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_PAGE_PUNT", PRINTER_STATUS_PAGE_PUNT, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_USER_INTERVENTION", PRINTER_STATUS_USER_INTERVENTION, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_OUT_OF_MEMORY", PRINTER_STATUS_OUT_OF_MEMORY, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_DOOR_OPEN", PRINTER_STATUS_DOOR_OPEN, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_SERVER_UNKNOWN", PRINTER_STATUS_SERVER_UNKNOWN, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_STATUS_POWER_SAVE", PRINTER_STATUS_POWER_SAVE, r);
-       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));
@@ -1144,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;
@@ -1322,6 +1366,9 @@ static enum ndr_err_code ndr_pull_spoolss_PrinterInfo2(struct ndr_pull *ndr, int
                }
                NDR_CHECK(ndr_pull_spoolss_PrinterAttributes(ndr, NDR_SCALARS, &r->attributes));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority));
+               if (r->priority > 99) {
+                       return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+               }
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->defaultpriority));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->starttime));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->untiltime));
@@ -1622,7 +1669,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));
@@ -1642,7 +1694,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;
@@ -1689,7 +1741,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));
@@ -1730,7 +1787,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;
@@ -1819,7 +1876,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));
@@ -1862,7 +1924,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;
@@ -1955,7 +2017,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));
@@ -1966,7 +2033,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));
@@ -1985,6 +2052,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));
@@ -2011,7 +2083,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));
@@ -2037,7 +2109,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;
@@ -2091,6 +2163,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) {
@@ -2456,6 +2533,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) {
@@ -2520,41 +2602,7 @@ _PUBLIC_ void ndr_print_spoolss_DevmodeContainer(struct ndr_print *ndr, const ch
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_JobStatus(struct ndr_push *ndr, int ndr_flags, uint32_t r)
-{
-       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
-       return NDR_ERR_SUCCESS;
-}
-
-static enum ndr_err_code ndr_pull_spoolss_JobStatus(struct ndr_pull *ndr, int ndr_flags, uint32_t *r)
-{
-       uint32_t v;
-       NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
-       *r = v;
-       return NDR_ERR_SUCCESS;
-}
-
-_PUBLIC_ void ndr_print_spoolss_JobStatus(struct ndr_print *ndr, const char *name, uint32_t r)
-{
-       ndr_print_uint32(ndr, name, r);
-       ndr->depth++;
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_PAUSED", JOB_STATUS_PAUSED, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_ERROR", JOB_STATUS_ERROR, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_DELETING", JOB_STATUS_DELETING, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_SPOOLING", JOB_STATUS_SPOOLING, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_PRINTING", JOB_STATUS_PRINTING, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_OFFLINE", JOB_STATUS_OFFLINE, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_PAPEROUT", JOB_STATUS_PAPEROUT, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_PRINTED", JOB_STATUS_PRINTED, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_DELETED", JOB_STATUS_DELETED, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_BLOCKED_DEVQ", JOB_STATUS_BLOCKED_DEVQ, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_USER_INTERVENTION", JOB_STATUS_USER_INTERVENTION, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_RESTART", JOB_STATUS_RESTART, r);
-       ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_COMPLETE", JOB_STATUS_COMPLETE, r);
-       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 +2709,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;
@@ -2752,6 +2800,9 @@ static enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr
                }
                NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority));
+               if (r->priority > 99) {
+                       return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+               }
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->total_pages));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->pages_printed));
@@ -2902,7 +2953,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 +3139,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;
@@ -3248,6 +3304,9 @@ static enum ndr_err_code ndr_pull_spoolss_JobInfo2(struct ndr_pull *ndr, int ndr
                }
                NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority));
+               if (r->priority > 99) {
+                       return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+               }
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->start_time));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->until_time));
@@ -3522,7 +3581,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 +3599,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 +3622,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 +3809,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;
@@ -3905,6 +3974,9 @@ static enum ndr_err_code ndr_pull_spoolss_JobInfo4(struct ndr_pull *ndr, int ndr
                }
                NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority));
+               if (r->priority > 99) {
+                       return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+               }
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->start_time));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->until_time));
@@ -4181,6 +4253,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 +4412,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) {
@@ -4449,6 +4531,9 @@ static enum ndr_err_code ndr_pull_spoolss_SetJobInfo1(struct ndr_pull *ndr, int
                }
                NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority));
+               if (r->priority > 99) {
+                       return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+               }
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->total_pages));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->pages_printed));
@@ -4595,9 +4680,9 @@ static enum ndr_err_code ndr_push_spoolss_SetJobInfo2(struct ndr_push *ndr, int
                NDR_CHECK(ndr_push_unique_ptr(ndr, r->print_processor));
                NDR_CHECK(ndr_push_unique_ptr(ndr, r->parameters));
                NDR_CHECK(ndr_push_unique_ptr(ndr, r->driver_name));
-               NDR_CHECK(ndr_push_unique_ptr(ndr, r->devmode));
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_devmode_ptr));
                NDR_CHECK(ndr_push_unique_ptr(ndr, r->text_status));
-               NDR_CHECK(ndr_push_unique_ptr(ndr, r->secdesc));
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_secdesc_ptr));
                NDR_CHECK(ndr_push_spoolss_JobStatus(ndr, NDR_SCALARS, r->status));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->priority));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->position));
@@ -4664,18 +4749,12 @@ static enum ndr_err_code ndr_push_spoolss_SetJobInfo2(struct ndr_push *ndr, int
                        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->driver_name, CH_UTF16)));
                        NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->driver_name, ndr_charset_length(r->driver_name, CH_UTF16), sizeof(uint16_t), CH_UTF16));
                }
-               if (r->devmode) {
-                       NDR_CHECK(ndr_push_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode));
-               }
                if (r->text_status) {
                        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->text_status, CH_UTF16)));
                        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
                        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->text_status, CH_UTF16)));
                        NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->text_status, ndr_charset_length(r->text_status, CH_UTF16), sizeof(uint16_t), CH_UTF16));
                }
-               if (r->secdesc) {
-                       NDR_CHECK(ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc));
-               }
        }
        return NDR_ERR_SUCCESS;
 }
@@ -4700,12 +4779,8 @@ static enum ndr_err_code ndr_pull_spoolss_SetJobInfo2(struct ndr_pull *ndr, int
        TALLOC_CTX *_mem_save_parameters_0;
        uint32_t _ptr_driver_name;
        TALLOC_CTX *_mem_save_driver_name_0;
-       uint32_t _ptr_devmode;
-       TALLOC_CTX *_mem_save_devmode_0;
        uint32_t _ptr_text_status;
        TALLOC_CTX *_mem_save_text_status_0;
-       uint32_t _ptr_secdesc;
-       TALLOC_CTX *_mem_save_secdesc_0;
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_pull_align(ndr, 4));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->job_id));
@@ -4763,26 +4838,19 @@ static enum ndr_err_code ndr_pull_spoolss_SetJobInfo2(struct ndr_pull *ndr, int
                } else {
                        r->driver_name = NULL;
                }
-               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_devmode));
-               if (_ptr_devmode) {
-                       NDR_PULL_ALLOC(ndr, r->devmode);
-               } else {
-                       r->devmode = NULL;
-               }
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_devmode_ptr));
                NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_text_status));
                if (_ptr_text_status) {
                        NDR_PULL_ALLOC(ndr, r->text_status);
                } else {
                        r->text_status = NULL;
                }
-               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_secdesc));
-               if (_ptr_secdesc) {
-                       NDR_PULL_ALLOC(ndr, r->secdesc);
-               } else {
-                       r->secdesc = NULL;
-               }
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_secdesc_ptr));
                NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority));
+               if (r->priority > 99) {
+                       return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+               }
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->start_time));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->until_time));
@@ -4901,12 +4969,6 @@ static enum ndr_err_code ndr_pull_spoolss_SetJobInfo2(struct ndr_pull *ndr, int
                        NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->driver_name, ndr_get_array_length(ndr, &r->driver_name), sizeof(uint16_t), CH_UTF16));
                        NDR_PULL_SET_MEM_CTX(ndr, _mem_save_driver_name_0, 0);
                }
-               if (r->devmode) {
-                       _mem_save_devmode_0 = NDR_PULL_GET_MEM_CTX(ndr);
-                       NDR_PULL_SET_MEM_CTX(ndr, r->devmode, 0);
-                       NDR_CHECK(ndr_pull_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode));
-                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_devmode_0, 0);
-               }
                if (r->text_status) {
                        _mem_save_text_status_0 = NDR_PULL_GET_MEM_CTX(ndr);
                        NDR_PULL_SET_MEM_CTX(ndr, r->text_status, 0);
@@ -4919,12 +4981,6 @@ static enum ndr_err_code ndr_pull_spoolss_SetJobInfo2(struct ndr_pull *ndr, int
                        NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->text_status, ndr_get_array_length(ndr, &r->text_status), sizeof(uint16_t), CH_UTF16));
                        NDR_PULL_SET_MEM_CTX(ndr, _mem_save_text_status_0, 0);
                }
-               if (r->secdesc) {
-                       _mem_save_secdesc_0 = NDR_PULL_GET_MEM_CTX(ndr);
-                       NDR_PULL_SET_MEM_CTX(ndr, r->secdesc, 0);
-                       NDR_CHECK(ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc));
-                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_secdesc_0, 0);
-               }
        }
        return NDR_ERR_SUCCESS;
 }
@@ -4988,24 +5044,14 @@ _PUBLIC_ void ndr_print_spoolss_SetJobInfo2(struct ndr_print *ndr, const char *n
                ndr_print_string(ndr, "driver_name", r->driver_name);
        }
        ndr->depth--;
-       ndr_print_ptr(ndr, "devmode", r->devmode);
-       ndr->depth++;
-       if (r->devmode) {
-               ndr_print_spoolss_DeviceMode(ndr, "devmode", r->devmode);
-       }
-       ndr->depth--;
+       ndr_print_uint32(ndr, "_devmode_ptr", r->_devmode_ptr);
        ndr_print_ptr(ndr, "text_status", r->text_status);
        ndr->depth++;
        if (r->text_status) {
                ndr_print_string(ndr, "text_status", r->text_status);
        }
        ndr->depth--;
-       ndr_print_ptr(ndr, "secdesc", r->secdesc);
-       ndr->depth++;
-       if (r->secdesc) {
-               ndr_print_security_descriptor(ndr, "secdesc", r->secdesc);
-       }
-       ndr->depth--;
+       ndr_print_uint32(ndr, "_secdesc_ptr", r->_secdesc_ptr);
        ndr_print_spoolss_JobStatus(ndr, "status", r->status);
        ndr_print_uint32(ndr, "priority", r->priority);
        ndr_print_uint32(ndr, "position", r->position);
@@ -5033,9 +5079,9 @@ static enum ndr_err_code ndr_push_spoolss_SetJobInfo4(struct ndr_push *ndr, int
                NDR_CHECK(ndr_push_unique_ptr(ndr, r->print_processor));
                NDR_CHECK(ndr_push_unique_ptr(ndr, r->parameters));
                NDR_CHECK(ndr_push_unique_ptr(ndr, r->driver_name));
-               NDR_CHECK(ndr_push_unique_ptr(ndr, r->devmode));
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_devmode_ptr));
                NDR_CHECK(ndr_push_unique_ptr(ndr, r->text_status));
-               NDR_CHECK(ndr_push_unique_ptr(ndr, r->secdesc));
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_secdesc_ptr));
                NDR_CHECK(ndr_push_spoolss_JobStatus(ndr, NDR_SCALARS, r->status));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->priority));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->position));
@@ -5103,18 +5149,12 @@ static enum ndr_err_code ndr_push_spoolss_SetJobInfo4(struct ndr_push *ndr, int
                        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->driver_name, CH_UTF16)));
                        NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->driver_name, ndr_charset_length(r->driver_name, CH_UTF16), sizeof(uint16_t), CH_UTF16));
                }
-               if (r->devmode) {
-                       NDR_CHECK(ndr_push_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode));
-               }
                if (r->text_status) {
                        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->text_status, CH_UTF16)));
                        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
                        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->text_status, CH_UTF16)));
                        NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->text_status, ndr_charset_length(r->text_status, CH_UTF16), sizeof(uint16_t), CH_UTF16));
                }
-               if (r->secdesc) {
-                       NDR_CHECK(ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc));
-               }
        }
        return NDR_ERR_SUCCESS;
 }
@@ -5139,12 +5179,8 @@ static enum ndr_err_code ndr_pull_spoolss_SetJobInfo4(struct ndr_pull *ndr, int
        TALLOC_CTX *_mem_save_parameters_0;
        uint32_t _ptr_driver_name;
        TALLOC_CTX *_mem_save_driver_name_0;
-       uint32_t _ptr_devmode;
-       TALLOC_CTX *_mem_save_devmode_0;
        uint32_t _ptr_text_status;
        TALLOC_CTX *_mem_save_text_status_0;
-       uint32_t _ptr_secdesc;
-       TALLOC_CTX *_mem_save_secdesc_0;
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_pull_align(ndr, 4));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->job_id));
@@ -5202,26 +5238,19 @@ static enum ndr_err_code ndr_pull_spoolss_SetJobInfo4(struct ndr_pull *ndr, int
                } else {
                        r->driver_name = NULL;
                }
-               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_devmode));
-               if (_ptr_devmode) {
-                       NDR_PULL_ALLOC(ndr, r->devmode);
-               } else {
-                       r->devmode = NULL;
-               }
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_devmode_ptr));
                NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_text_status));
                if (_ptr_text_status) {
                        NDR_PULL_ALLOC(ndr, r->text_status);
                } else {
                        r->text_status = NULL;
                }
-               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_secdesc));
-               if (_ptr_secdesc) {
-                       NDR_PULL_ALLOC(ndr, r->secdesc);
-               } else {
-                       r->secdesc = NULL;
-               }
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_secdesc_ptr));
                NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority));
+               if (r->priority > 99) {
+                       return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+               }
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->start_time));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->until_time));
@@ -5341,12 +5370,6 @@ static enum ndr_err_code ndr_pull_spoolss_SetJobInfo4(struct ndr_pull *ndr, int
                        NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->driver_name, ndr_get_array_length(ndr, &r->driver_name), sizeof(uint16_t), CH_UTF16));
                        NDR_PULL_SET_MEM_CTX(ndr, _mem_save_driver_name_0, 0);
                }
-               if (r->devmode) {
-                       _mem_save_devmode_0 = NDR_PULL_GET_MEM_CTX(ndr);
-                       NDR_PULL_SET_MEM_CTX(ndr, r->devmode, 0);
-                       NDR_CHECK(ndr_pull_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode));
-                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_devmode_0, 0);
-               }
                if (r->text_status) {
                        _mem_save_text_status_0 = NDR_PULL_GET_MEM_CTX(ndr);
                        NDR_PULL_SET_MEM_CTX(ndr, r->text_status, 0);
@@ -5359,12 +5382,6 @@ static enum ndr_err_code ndr_pull_spoolss_SetJobInfo4(struct ndr_pull *ndr, int
                        NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->text_status, ndr_get_array_length(ndr, &r->text_status), sizeof(uint16_t), CH_UTF16));
                        NDR_PULL_SET_MEM_CTX(ndr, _mem_save_text_status_0, 0);
                }
-               if (r->secdesc) {
-                       _mem_save_secdesc_0 = NDR_PULL_GET_MEM_CTX(ndr);
-                       NDR_PULL_SET_MEM_CTX(ndr, r->secdesc, 0);
-                       NDR_CHECK(ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc));
-                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_secdesc_0, 0);
-               }
        }
        return NDR_ERR_SUCCESS;
 }
@@ -5428,24 +5445,14 @@ _PUBLIC_ void ndr_print_spoolss_SetJobInfo4(struct ndr_print *ndr, const char *n
                ndr_print_string(ndr, "driver_name", r->driver_name);
        }
        ndr->depth--;
-       ndr_print_ptr(ndr, "devmode", r->devmode);
-       ndr->depth++;
-       if (r->devmode) {
-               ndr_print_spoolss_DeviceMode(ndr, "devmode", r->devmode);
-       }
-       ndr->depth--;
+       ndr_print_uint32(ndr, "_devmode_ptr", r->_devmode_ptr);
        ndr_print_ptr(ndr, "text_status", r->text_status);
        ndr->depth++;
        if (r->text_status) {
                ndr_print_string(ndr, "text_status", r->text_status);
        }
        ndr->depth--;
-       ndr_print_ptr(ndr, "secdesc", r->secdesc);
-       ndr->depth++;
-       if (r->secdesc) {
-               ndr_print_security_descriptor(ndr, "secdesc", r->secdesc);
-       }
-       ndr->depth--;
+       ndr_print_uint32(ndr, "_secdesc_ptr", r->_secdesc_ptr);
        ndr_print_spoolss_JobStatus(ndr, "status", r->status);
        ndr_print_uint32(ndr, "priority", r->priority);
        ndr_print_uint32(ndr, "position", r->position);
@@ -6300,6 +6307,9 @@ static enum ndr_err_code ndr_pull_spoolss_SetPrinterInfo2(struct ndr_pull *ndr,
                }
                NDR_CHECK(ndr_pull_spoolss_PrinterAttributes(ndr, NDR_SCALARS, &r->attributes));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority));
+               if (r->priority > 99) {
+                       return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+               }
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->defaultpriority));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->starttime));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->untiltime));
@@ -13694,6 +13704,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) {
@@ -13833,7 +13848,7 @@ _PUBLIC_ size_t ndr_size_spoolss_DriverDirectoryInfo(const union spoolss_DriverD
        return ndr_size_union(r, flags, level, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverDirectoryInfo, ic);
 }
 
-static enum ndr_err_code ndr_push_spoolss_PrintProcessorInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrintProcessorInfo1 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrintProcessorInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrintProcessorInfo1 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -13858,7 +13873,7 @@ static enum ndr_err_code ndr_push_spoolss_PrintProcessorInfo1(struct ndr_push *n
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PrintProcessorInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrintProcessorInfo1 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrintProcessorInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrintProcessorInfo1 *r)
 {
        uint32_t _ptr_print_processor_name;
        TALLOC_CTX *_mem_save_print_processor_name_0;
@@ -13910,6 +13925,11 @@ _PUBLIC_ void ndr_print_spoolss_PrintProcessorInfo1(struct ndr_print *ndr, const
        ndr->depth--;
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_PrintProcessorInfo1(const struct spoolss_PrintProcessorInfo1 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PrintProcessorInfo1, ic);
+}
+
 _PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrintProcessorInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_PrintProcessorInfo *r)
 {
        uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);
@@ -14534,43 +14554,15 @@ _PUBLIC_ size_t ndr_size_spoolss_OSVersionEx(const struct spoolss_OSVersionEx *r
        return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersionEx, ic);
 }
 
-static enum ndr_err_code ndr_push_spoolss_PrinterDataType(struct ndr_push *ndr, int ndr_flags, enum spoolss_PrinterDataType r)
-{
-       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
-       return NDR_ERR_SUCCESS;
-}
-
-static enum ndr_err_code ndr_pull_spoolss_PrinterDataType(struct ndr_pull *ndr, int ndr_flags, enum spoolss_PrinterDataType *r)
-{
-       uint32_t v;
-       NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
-       *r = v;
-       return NDR_ERR_SUCCESS;
-}
-
-_PUBLIC_ void ndr_print_spoolss_PrinterDataType(struct ndr_print *ndr, const char *name, enum spoolss_PrinterDataType r)
-{
-       const char *val = NULL;
-
-       switch (r) {
-               case SPOOLSS_PRINTER_DATA_TYPE_NULL: val = "SPOOLSS_PRINTER_DATA_TYPE_NULL"; break;
-               case SPOOLSS_PRINTER_DATA_TYPE_STRING: val = "SPOOLSS_PRINTER_DATA_TYPE_STRING"; break;
-               case SPOOLSS_PRINTER_DATA_TYPE_BINARY: val = "SPOOLSS_PRINTER_DATA_TYPE_BINARY"; break;
-               case SPOOLSS_PRINTER_DATA_TYPE_UINT32: val = "SPOOLSS_PRINTER_DATA_TYPE_UINT32"; break;
-               case SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY: val = "SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY"; break;
-       }
-       ndr_print_enum(ndr, name, "ENUM", val, r);
-}
-
 _PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterData(struct ndr_push *ndr, int ndr_flags, const union spoolss_PrinterData *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                int level = ndr_push_get_switch_value(ndr, r);
                switch (level) {
-                       case SPOOLSS_PRINTER_DATA_TYPE_NULL: {
+                       case REG_NONE: {
                        break; }
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_STRING: {
+                       case REG_SZ: {
                                {
                                        uint32_t _flags_save_string = ndr->flags;
                                        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
@@ -14579,7 +14571,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterData(struct ndr_push *ndr, in
                                }
                        break; }
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_BINARY: {
+                       case REG_BINARY: {
                                {
                                        uint32_t _flags_save_DATA_BLOB = ndr->flags;
                                        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
@@ -14588,11 +14580,11 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterData(struct ndr_push *ndr, in
                                }
                        break; }
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_UINT32: {
+                       case REG_DWORD: {
                                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->value));
                        break; }
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY: {
+                       case REG_MULTI_SZ: {
                                {
                                        uint32_t _flags_save_string_array = ndr->flags;
                                        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
@@ -14615,19 +14607,19 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterData(struct ndr_push *ndr, in
        if (ndr_flags & NDR_BUFFERS) {
                int level = ndr_push_get_switch_value(ndr, r);
                switch (level) {
-                       case SPOOLSS_PRINTER_DATA_TYPE_NULL:
+                       case REG_NONE:
                        break;
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_STRING:
+                       case REG_SZ:
                        break;
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_BINARY:
+                       case REG_BINARY:
                        break;
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_UINT32:
+                       case REG_DWORD:
                        break;
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY:
+                       case REG_MULTI_SZ:
                        break;
 
                        default:
@@ -14644,10 +14636,10 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterData(struct ndr_pull *ndr, in
        level = ndr_pull_get_switch_value(ndr, r);
        if (ndr_flags & NDR_SCALARS) {
                switch (level) {
-                       case SPOOLSS_PRINTER_DATA_TYPE_NULL: {
+                       case REG_NONE: {
                        break; }
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_STRING: {
+                       case REG_SZ: {
                                {
                                        uint32_t _flags_save_string = ndr->flags;
                                        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
@@ -14656,7 +14648,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterData(struct ndr_pull *ndr, in
                                }
                        break; }
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_BINARY: {
+                       case REG_BINARY: {
                                {
                                        uint32_t _flags_save_DATA_BLOB = ndr->flags;
                                        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
@@ -14665,11 +14657,11 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterData(struct ndr_pull *ndr, in
                                }
                        break; }
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_UINT32: {
+                       case REG_DWORD: {
                                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->value));
                        break; }
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY: {
+                       case REG_MULTI_SZ: {
                                {
                                        uint32_t _flags_save_string_array = ndr->flags;
                                        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
@@ -14691,19 +14683,19 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterData(struct ndr_pull *ndr, in
        }
        if (ndr_flags & NDR_BUFFERS) {
                switch (level) {
-                       case SPOOLSS_PRINTER_DATA_TYPE_NULL:
+                       case REG_NONE:
                        break;
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_STRING:
+                       case REG_SZ:
                        break;
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_BINARY:
+                       case REG_BINARY:
                        break;
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_UINT32:
+                       case REG_DWORD:
                        break;
 
-                       case SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY:
+                       case REG_MULTI_SZ:
                        break;
 
                        default:
@@ -14720,22 +14712,22 @@ _PUBLIC_ void ndr_print_spoolss_PrinterData(struct ndr_print *ndr, const char *n
        level = ndr_print_get_switch_value(ndr, r);
        ndr_print_union(ndr, name, level, "spoolss_PrinterData");
        switch (level) {
-               case SPOOLSS_PRINTER_DATA_TYPE_NULL:
+               case REG_NONE:
                break;
 
-               case SPOOLSS_PRINTER_DATA_TYPE_STRING:
+               case REG_SZ:
                        ndr_print_string(ndr, "string", r->string);
                break;
 
-               case SPOOLSS_PRINTER_DATA_TYPE_BINARY:
+               case REG_BINARY:
                        ndr_print_DATA_BLOB(ndr, "binary", r->binary);
                break;
 
-               case SPOOLSS_PRINTER_DATA_TYPE_UINT32:
+               case REG_DWORD:
                        ndr_print_uint32(ndr, "value", r->value);
                break;
 
-               case SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY:
+               case REG_MULTI_SZ:
                        ndr_print_string_array(ndr, "string_array", r->string_array);
                break;
 
@@ -14849,7 +14841,7 @@ _PUBLIC_ void ndr_print_spoolss_FormArea(struct ndr_print *ndr, const char *name
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_FormInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_FormInfo1 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_FormInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_FormInfo1 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -14877,7 +14869,7 @@ static enum ndr_err_code ndr_push_spoolss_FormInfo1(struct ndr_push *ndr, int nd
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_FormInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_FormInfo1 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_FormInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_FormInfo1 *r)
 {
        uint32_t _ptr_form_name;
        TALLOC_CTX *_mem_save_form_name_0;
@@ -14935,6 +14927,11 @@ _PUBLIC_ void ndr_print_spoolss_FormInfo1(struct ndr_print *ndr, const char *nam
        ndr->depth--;
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_FormInfo1(const struct spoolss_FormInfo1 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_FormInfo1, ic);
+}
+
 static enum ndr_err_code ndr_push_spoolss_FormStringType(struct ndr_push *ndr, int ndr_flags, uint32_t r)
 {
        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
@@ -14959,7 +14956,7 @@ _PUBLIC_ void ndr_print_spoolss_FormStringType(struct ndr_print *ndr, const char
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_FormInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_FormInfo2 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_FormInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_FormInfo2 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -15035,7 +15032,7 @@ static enum ndr_err_code ndr_push_spoolss_FormInfo2(struct ndr_push *ndr, int nd
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_FormInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_FormInfo2 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_FormInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_FormInfo2 *r)
 {
        uint32_t _ptr_form_name;
        TALLOC_CTX *_mem_save_form_name_0;
@@ -15204,6 +15201,11 @@ _PUBLIC_ void ndr_print_spoolss_FormInfo2(struct ndr_print *ndr, const char *nam
        ndr->depth--;
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_FormInfo2(const struct spoolss_FormInfo2 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_FormInfo2, ic);
+}
+
 _PUBLIC_ enum ndr_err_code ndr_push_spoolss_FormInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_FormInfo *r)
 {
        uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);
@@ -15696,7 +15698,7 @@ _PUBLIC_ void ndr_print_spoolss_AddFormInfo(struct ndr_print *ndr, const char *n
        }
 }
 
-static enum ndr_err_code ndr_push_spoolss_PortInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfo1 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PortInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfo1 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -15721,7 +15723,7 @@ static enum ndr_err_code ndr_push_spoolss_PortInfo1(struct ndr_push *ndr, int nd
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PortInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfo1 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PortInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfo1 *r)
 {
        uint32_t _ptr_port_name;
        TALLOC_CTX *_mem_save_port_name_0;
@@ -15773,6 +15775,11 @@ _PUBLIC_ void ndr_print_spoolss_PortInfo1(struct ndr_print *ndr, const char *nam
        ndr->depth--;
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_PortInfo1(const struct spoolss_PortInfo1 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PortInfo1, ic);
+}
+
 static enum ndr_err_code ndr_push_spoolss_PortType(struct ndr_push *ndr, int ndr_flags, uint32_t r)
 {
        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
@@ -15798,7 +15805,7 @@ _PUBLIC_ void ndr_print_spoolss_PortType(struct ndr_print *ndr, const char *name
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_PortInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfo2 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PortInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfo2 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -15855,7 +15862,7 @@ static enum ndr_err_code ndr_push_spoolss_PortInfo2(struct ndr_push *ndr, int nd
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PortInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfo2 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PortInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfo2 *r)
 {
        uint32_t _ptr_port_name;
        TALLOC_CTX *_mem_save_port_name_0;
@@ -15981,6 +15988,11 @@ _PUBLIC_ void ndr_print_spoolss_PortInfo2(struct ndr_print *ndr, const char *nam
        ndr->depth--;
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_PortInfo2(const struct spoolss_PortInfo2 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PortInfo2, ic);
+}
+
 static enum ndr_err_code ndr_push_spoolss_PortStatus(struct ndr_push *ndr, int ndr_flags, enum spoolss_PortStatus r)
 {
        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
@@ -16043,7 +16055,7 @@ _PUBLIC_ void ndr_print_spoolss_PortSeverity(struct ndr_print *ndr, const char *
        ndr_print_enum(ndr, name, "ENUM", val, r);
 }
 
-static enum ndr_err_code ndr_push_spoolss_PortInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfo3 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PortInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfo3 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -16070,7 +16082,7 @@ static enum ndr_err_code ndr_push_spoolss_PortInfo3(struct ndr_push *ndr, int nd
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PortInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfo3 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PortInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfo3 *r)
 {
        uint32_t _ptr_status_string;
        TALLOC_CTX *_mem_save_status_string_0;
@@ -16126,7 +16138,12 @@ _PUBLIC_ void ndr_print_spoolss_PortInfo3(struct ndr_print *ndr, const char *nam
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_PortInfoFF(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfoFF *r)
+_PUBLIC_ size_t ndr_size_spoolss_PortInfo3(const struct spoolss_PortInfo3 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PortInfo3, ic);
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PortInfoFF(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfoFF *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -16152,7 +16169,7 @@ static enum ndr_err_code ndr_push_spoolss_PortInfoFF(struct ndr_push *ndr, int n
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_PortInfoFF(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfoFF *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PortInfoFF(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfoFF *r)
 {
        uint32_t _ptr_port_name;
        TALLOC_CTX *_mem_save_port_name_0;
@@ -16206,6 +16223,11 @@ _PUBLIC_ void ndr_print_spoolss_PortInfoFF(struct ndr_print *ndr, const char *na
        ndr->depth--;
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_PortInfoFF(const struct spoolss_PortInfoFF *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PortInfoFF, ic);
+}
+
 _PUBLIC_ enum ndr_err_code ndr_push_spoolss_PortInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_PortInfo *r)
 {
        uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);
@@ -16362,7 +16384,7 @@ _PUBLIC_ void ndr_print_spoolss_PortInfo(struct ndr_print *ndr, const char *name
        }
 }
 
-static enum ndr_err_code ndr_push_spoolss_MonitorInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_MonitorInfo1 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_MonitorInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_MonitorInfo1 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -16387,7 +16409,7 @@ static enum ndr_err_code ndr_push_spoolss_MonitorInfo1(struct ndr_push *ndr, int
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_MonitorInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_MonitorInfo1 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_MonitorInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_MonitorInfo1 *r)
 {
        uint32_t _ptr_monitor_name;
        TALLOC_CTX *_mem_save_monitor_name_0;
@@ -16439,7 +16461,12 @@ _PUBLIC_ void ndr_print_spoolss_MonitorInfo1(struct ndr_print *ndr, const char *
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_MonitorInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_MonitorInfo2 *r)
+_PUBLIC_ size_t ndr_size_spoolss_MonitorInfo1(const struct spoolss_MonitorInfo1 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorInfo1, ic);
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_MonitorInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_MonitorInfo2 *r)
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
@@ -16494,7 +16521,7 @@ static enum ndr_err_code ndr_push_spoolss_MonitorInfo2(struct ndr_push *ndr, int
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_MonitorInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_MonitorInfo2 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_MonitorInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_MonitorInfo2 *r)
 {
        uint32_t _ptr_monitor_name;
        TALLOC_CTX *_mem_save_monitor_name_0;
@@ -16616,6 +16643,11 @@ _PUBLIC_ void ndr_print_spoolss_MonitorInfo2(struct ndr_print *ndr, const char *
        ndr->depth--;
 }
 
+_PUBLIC_ size_t ndr_size_spoolss_MonitorInfo2(const struct spoolss_MonitorInfo2 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorInfo2, ic);
+}
+
 _PUBLIC_ enum ndr_err_code ndr_push_spoolss_MonitorInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_MonitorInfo *r)
 {
        uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);
@@ -16724,6 +16756,172 @@ _PUBLIC_ void ndr_print_spoolss_MonitorInfo(struct ndr_print *ndr, const char *n
        }
 }
 
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrintProcDataTypesInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrintProcDataTypesInfo1 *r)
+{
+       if (ndr_flags & NDR_SCALARS) {
+               NDR_CHECK(ndr_push_align(ndr, 4));
+               {
+                       uint32_t _flags_save_string = ndr->flags;
+                       ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+                       NDR_CHECK(ndr_push_relative_ptr1(ndr, r->name_array));
+                       ndr->flags = _flags_save_string;
+               }
+       }
+       if (ndr_flags & NDR_BUFFERS) {
+               {
+                       uint32_t _flags_save_string = ndr->flags;
+                       ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+                       if (r->name_array) {
+                               NDR_CHECK(ndr_push_relative_ptr2(ndr, r->name_array));
+                               NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->name_array));
+                       }
+                       ndr->flags = _flags_save_string;
+               }
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrintProcDataTypesInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrintProcDataTypesInfo1 *r)
+{
+       uint32_t _ptr_name_array;
+       TALLOC_CTX *_mem_save_name_array_0;
+       if (ndr_flags & NDR_SCALARS) {
+               NDR_CHECK(ndr_pull_align(ndr, 4));
+               {
+                       uint32_t _flags_save_string = ndr->flags;
+                       ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+                       NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_name_array));
+                       if (_ptr_name_array) {
+                               NDR_PULL_ALLOC(ndr, r->name_array);
+                               NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->name_array, _ptr_name_array));
+                       } else {
+                               r->name_array = NULL;
+                       }
+                       ndr->flags = _flags_save_string;
+               }
+       }
+       if (ndr_flags & NDR_BUFFERS) {
+               {
+                       uint32_t _flags_save_string = ndr->flags;
+                       ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+                       if (r->name_array) {
+                               uint32_t _relative_save_offset;
+                               _relative_save_offset = ndr->offset;
+                               NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->name_array));
+                               _mem_save_name_array_0 = NDR_PULL_GET_MEM_CTX(ndr);
+                               NDR_PULL_SET_MEM_CTX(ndr, r->name_array, 0);
+                               NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->name_array));
+                               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_array_0, 0);
+                               ndr->offset = _relative_save_offset;
+                       }
+                       ndr->flags = _flags_save_string;
+               }
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_spoolss_PrintProcDataTypesInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_PrintProcDataTypesInfo1 *r)
+{
+       ndr_print_struct(ndr, name, "spoolss_PrintProcDataTypesInfo1");
+       ndr->depth++;
+       ndr_print_ptr(ndr, "name_array", r->name_array);
+       ndr->depth++;
+       if (r->name_array) {
+               ndr_print_string(ndr, "name_array", r->name_array);
+       }
+       ndr->depth--;
+       ndr->depth--;
+}
+
+_PUBLIC_ size_t ndr_size_spoolss_PrintProcDataTypesInfo1(const struct spoolss_PrintProcDataTypesInfo1 *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PrintProcDataTypesInfo1, ic);
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrintProcDataTypesInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_PrintProcDataTypesInfo *r)
+{
+       uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);
+       if (ndr_flags & NDR_SCALARS) {
+               int level = ndr_push_get_switch_value(ndr, r);
+               switch (level) {
+                       case 1: {
+                               NDR_CHECK(ndr_push_align(ndr, 4));
+                               NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset));
+                               NDR_CHECK(ndr_push_spoolss_PrintProcDataTypesInfo1(ndr, NDR_SCALARS, &r->info1));
+                       break; }
+
+                       default: {
+                       break; }
+
+               }
+       }
+       if (ndr_flags & NDR_BUFFERS) {
+               int level = ndr_push_get_switch_value(ndr, r);
+               NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, r));
+               switch (level) {
+                       case 1:
+                               NDR_CHECK(ndr_push_spoolss_PrintProcDataTypesInfo1(ndr, NDR_BUFFERS, &r->info1));
+                       break;
+
+                       default:
+                       break;
+
+               }
+       }
+       ndr_push_restore_relative_base_offset(ndr, _save_relative_base_offset);
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrintProcDataTypesInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_PrintProcDataTypesInfo *r)
+{
+       uint32_t _save_relative_base_offset = ndr_pull_get_relative_base_offset(ndr);
+       int level;
+       level = ndr_pull_get_switch_value(ndr, r);
+       if (ndr_flags & NDR_SCALARS) {
+               switch (level) {
+                       case 1: {
+                               NDR_CHECK(ndr_pull_align(ndr, 4));
+                               NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset));
+                               NDR_CHECK(ndr_pull_spoolss_PrintProcDataTypesInfo1(ndr, NDR_SCALARS, &r->info1));
+                       break; }
+
+                       default: {
+                       break; }
+
+               }
+       }
+       if (ndr_flags & NDR_BUFFERS) {
+               NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, r));
+               switch (level) {
+                       case 1:
+                               NDR_CHECK(ndr_pull_spoolss_PrintProcDataTypesInfo1(ndr, NDR_BUFFERS, &r->info1));
+                       break;
+
+                       default:
+                       break;
+
+               }
+       }
+       ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_spoolss_PrintProcDataTypesInfo(struct ndr_print *ndr, const char *name, const union spoolss_PrintProcDataTypesInfo *r)
+{
+       int level;
+       level = ndr_print_get_switch_value(ndr, r);
+       ndr_print_union(ndr, name, level, "spoolss_PrintProcDataTypesInfo");
+       switch (level) {
+               case 1:
+                       ndr_print_spoolss_PrintProcDataTypesInfo1(ndr, "info1", &r->info1);
+               break;
+
+               default:
+               break;
+
+       }
+}
+
 static enum ndr_err_code ndr_push_spoolss_PrinterChangeFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r)
 {
        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
@@ -16766,13 +16964,13 @@ _PUBLIC_ void ndr_print_spoolss_PrinterChangeFlags(struct ndr_print *ndr, const
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_Field(struct ndr_push *ndr, int ndr_flags, enum spoolss_Field r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_JobNotifyField(struct ndr_push *ndr, int ndr_flags, enum spoolss_JobNotifyField r)
 {
        NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r));
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_Field(struct ndr_pull *ndr, int ndr_flags, enum spoolss_Field *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_JobNotifyField(struct ndr_pull *ndr, int ndr_flags, enum spoolss_JobNotifyField *r)
 {
        uint16_t v;
        NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &v));
@@ -16780,48 +16978,46 @@ static enum ndr_err_code ndr_pull_spoolss_Field(struct ndr_pull *ndr, int ndr_fl
        return NDR_ERR_SUCCESS;
 }
 
-_PUBLIC_ void ndr_print_spoolss_Field(struct ndr_print *ndr, const char *name, enum spoolss_Field r)
+_PUBLIC_ void ndr_print_spoolss_JobNotifyField(struct ndr_print *ndr, const char *name, enum spoolss_JobNotifyField r)
 {
        const char *val = NULL;
 
        switch (r) {
-               case SPOOLSS_FIELD_SERVER_NAME: val = "SPOOLSS_FIELD_SERVER_NAME"; break;
-               case SPOOLSS_FIELD_PRINTER_NAME: val = "SPOOLSS_FIELD_PRINTER_NAME"; break;
-               case SPOOLSS_FIELD_SHARE_NAME: val = "SPOOLSS_FIELD_SHARE_NAME"; break;
-               case SPOOLSS_FIELD_PORT_NAME: val = "SPOOLSS_FIELD_PORT_NAME"; break;
-               case SPOOLSS_FIELD_DRIVER_NAME: val = "SPOOLSS_FIELD_DRIVER_NAME"; break;
-               case SPOOLSS_FIELD_COMMENT: val = "SPOOLSS_FIELD_COMMENT"; break;
-               case SPOOLSS_FIELD_LOCATION: val = "SPOOLSS_FIELD_LOCATION"; break;
-               case SPOOLSS_FIELD_DEVMODE: val = "SPOOLSS_FIELD_DEVMODE"; break;
-               case SPOOLSS_FIELD_SEPFILE: val = "SPOOLSS_FIELD_SEPFILE"; break;
-               case SPOOLSS_FIELD_PRINT_PROCESSOR: val = "SPOOLSS_FIELD_PRINT_PROCESSOR"; break;
-               case SPOOLSS_FIELD_PARAMETERS: val = "SPOOLSS_FIELD_PARAMETERS"; break;
-               case SPOOLSS_FIELD_DATATYPE: val = "SPOOLSS_FIELD_DATATYPE"; break;
-               case SPOOLSS_FIELD_SECURITY_DESCRIPTOR: val = "SPOOLSS_FIELD_SECURITY_DESCRIPTOR"; break;
-               case SPOOLSS_FIELD_ATTRIBUTES: val = "SPOOLSS_FIELD_ATTRIBUTES"; break;
-               case SPOOLSS_FIELD_PRIORITY: val = "SPOOLSS_FIELD_PRIORITY"; break;
-               case SPOOLSS_FIELD_DEFAULT_PRIORITY: val = "SPOOLSS_FIELD_DEFAULT_PRIORITY"; break;
-               case SPOOLSS_FIELD_START_TIME: val = "SPOOLSS_FIELD_START_TIME"; break;
-               case SPOOLSS_FIELD_UNTIL_TIME: val = "SPOOLSS_FIELD_UNTIL_TIME"; break;
-               case SPOOLSS_FIELD_STATUS: val = "SPOOLSS_FIELD_STATUS"; break;
-               case SPOOLSS_FIELD_STATUS_STRING: val = "SPOOLSS_FIELD_STATUS_STRING"; break;
-               case SPOOLSS_FIELD_CJOBS: val = "SPOOLSS_FIELD_CJOBS"; break;
-               case SPOOLSS_FIELD_AVERAGE_PPM: val = "SPOOLSS_FIELD_AVERAGE_PPM"; break;
-               case SPOOLSS_FIELD_TOTAL_PAGES: val = "SPOOLSS_FIELD_TOTAL_PAGES"; break;
-               case SPOOLSS_FIELD_PAGES_PRINTED: val = "SPOOLSS_FIELD_PAGES_PRINTED"; break;
-               case SPOOLSS_FIELD_TOTAL_BYTES: val = "SPOOLSS_FIELD_TOTAL_BYTES"; break;
-               case SPOOLSS_FIELD_BYTES_PRINTED: val = "SPOOLSS_FIELD_BYTES_PRINTED"; break;
+               case JOB_NOTIFY_FIELD_PRINTER_NAME: val = "JOB_NOTIFY_FIELD_PRINTER_NAME"; break;
+               case JOB_NOTIFY_FIELD_MACHINE_NAME: val = "JOB_NOTIFY_FIELD_MACHINE_NAME"; break;
+               case JOB_NOTIFY_FIELD_PORT_NAME: val = "JOB_NOTIFY_FIELD_PORT_NAME"; break;
+               case JOB_NOTIFY_FIELD_USER_NAME: val = "JOB_NOTIFY_FIELD_USER_NAME"; break;
+               case JOB_NOTIFY_FIELD_NOTIFY_NAME: val = "JOB_NOTIFY_FIELD_NOTIFY_NAME"; break;
+               case JOB_NOTIFY_FIELD_DATATYPE: val = "JOB_NOTIFY_FIELD_DATATYPE"; break;
+               case JOB_NOTIFY_FIELD_PRINT_PROCESSOR: val = "JOB_NOTIFY_FIELD_PRINT_PROCESSOR"; break;
+               case JOB_NOTIFY_FIELD_PARAMETERS: val = "JOB_NOTIFY_FIELD_PARAMETERS"; break;
+               case JOB_NOTIFY_FIELD_DRIVER_NAME: val = "JOB_NOTIFY_FIELD_DRIVER_NAME"; break;
+               case JOB_NOTIFY_FIELD_DEVMODE: val = "JOB_NOTIFY_FIELD_DEVMODE"; break;
+               case JOB_NOTIFY_FIELD_STATUS: val = "JOB_NOTIFY_FIELD_STATUS"; break;
+               case JOB_NOTIFY_FIELD_STATUS_STRING: val = "JOB_NOTIFY_FIELD_STATUS_STRING"; break;
+               case JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR: val = "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR"; break;
+               case JOB_NOTIFY_FIELD_DOCUMENT: val = "JOB_NOTIFY_FIELD_DOCUMENT"; break;
+               case JOB_NOTIFY_FIELD_PRIORITY: val = "JOB_NOTIFY_FIELD_PRIORITY"; break;
+               case JOB_NOTIFY_FIELD_POSITION: val = "JOB_NOTIFY_FIELD_POSITION"; break;
+               case JOB_NOTIFY_FIELD_SUBMITTED: val = "JOB_NOTIFY_FIELD_SUBMITTED"; break;
+               case JOB_NOTIFY_FIELD_START_TIME: val = "JOB_NOTIFY_FIELD_START_TIME"; break;
+               case JOB_NOTIFY_FIELD_UNTIL_TIME: val = "JOB_NOTIFY_FIELD_UNTIL_TIME"; break;
+               case JOB_NOTIFY_FIELD_TIME: val = "JOB_NOTIFY_FIELD_TIME"; break;
+               case JOB_NOTIFY_FIELD_TOTAL_PAGES: val = "JOB_NOTIFY_FIELD_TOTAL_PAGES"; break;
+               case JOB_NOTIFY_FIELD_PAGES_PRINTED: val = "JOB_NOTIFY_FIELD_PAGES_PRINTED"; break;
+               case JOB_NOTIFY_FIELD_TOTAL_BYTES: val = "JOB_NOTIFY_FIELD_TOTAL_BYTES"; break;
+               case JOB_NOTIFY_FIELD_BYTES_PRINTED: val = "JOB_NOTIFY_FIELD_BYTES_PRINTED"; break;
        }
        ndr_print_enum(ndr, name, "ENUM", val, r);
 }
 
-static enum ndr_err_code ndr_push_spoolss_NotifyType(struct ndr_push *ndr, int ndr_flags, enum spoolss_NotifyType r)
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrintNotifyField(struct ndr_push *ndr, int ndr_flags, enum spoolss_PrintNotifyField r)
 {
        NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r));
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_NotifyType(struct ndr_pull *ndr, int ndr_flags, enum spoolss_NotifyType *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrintNotifyField(struct ndr_pull *ndr, int ndr_flags, enum spoolss_PrintNotifyField *r)
 {
        uint16_t v;
        NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &v));
@@ -16829,22 +17025,145 @@ static enum ndr_err_code ndr_pull_spoolss_NotifyType(struct ndr_pull *ndr, int n
        return NDR_ERR_SUCCESS;
 }
 
-_PUBLIC_ void ndr_print_spoolss_NotifyType(struct ndr_print *ndr, const char *name, enum spoolss_NotifyType r)
+_PUBLIC_ void ndr_print_spoolss_PrintNotifyField(struct ndr_print *ndr, const char *name, enum spoolss_PrintNotifyField r)
 {
        const char *val = NULL;
 
        switch (r) {
-               case SPOOLSS_NOTIFY_PRINTER: val = "SPOOLSS_NOTIFY_PRINTER"; break;
-               case SPOOLSS_NOTIFY_JOB: val = "SPOOLSS_NOTIFY_JOB"; break;
+               case PRINTER_NOTIFY_FIELD_SERVER_NAME: val = "PRINTER_NOTIFY_FIELD_SERVER_NAME"; break;
+               case PRINTER_NOTIFY_FIELD_PRINTER_NAME: val = "PRINTER_NOTIFY_FIELD_PRINTER_NAME"; break;
+               case PRINTER_NOTIFY_FIELD_SHARE_NAME: val = "PRINTER_NOTIFY_FIELD_SHARE_NAME"; break;
+               case PRINTER_NOTIFY_FIELD_PORT_NAME: val = "PRINTER_NOTIFY_FIELD_PORT_NAME"; break;
+               case PRINTER_NOTIFY_FIELD_DRIVER_NAME: val = "PRINTER_NOTIFY_FIELD_DRIVER_NAME"; break;
+               case PRINTER_NOTIFY_FIELD_COMMENT: val = "PRINTER_NOTIFY_FIELD_COMMENT"; break;
+               case PRINTER_NOTIFY_FIELD_LOCATION: val = "PRINTER_NOTIFY_FIELD_LOCATION"; break;
+               case PRINTER_NOTIFY_FIELD_DEVMODE: val = "PRINTER_NOTIFY_FIELD_DEVMODE"; break;
+               case PRINTER_NOTIFY_FIELD_SEPFILE: val = "PRINTER_NOTIFY_FIELD_SEPFILE"; break;
+               case PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR: val = "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR"; break;
+               case PRINTER_NOTIFY_FIELD_PARAMETERS: val = "PRINTER_NOTIFY_FIELD_PARAMETERS"; break;
+               case PRINTER_NOTIFY_FIELD_DATATYPE: val = "PRINTER_NOTIFY_FIELD_DATATYPE"; break;
+               case PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR: val = "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR"; break;
+               case PRINTER_NOTIFY_FIELD_ATTRIBUTES: val = "PRINTER_NOTIFY_FIELD_ATTRIBUTES"; break;
+               case PRINTER_NOTIFY_FIELD_PRIORITY: val = "PRINTER_NOTIFY_FIELD_PRIORITY"; break;
+               case PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY: val = "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY"; break;
+               case PRINTER_NOTIFY_FIELD_START_TIME: val = "PRINTER_NOTIFY_FIELD_START_TIME"; break;
+               case PRINTER_NOTIFY_FIELD_UNTIL_TIME: val = "PRINTER_NOTIFY_FIELD_UNTIL_TIME"; break;
+               case PRINTER_NOTIFY_FIELD_STATUS: val = "PRINTER_NOTIFY_FIELD_STATUS"; break;
+               case PRINTER_NOTIFY_FIELD_STATUS_STRING: val = "PRINTER_NOTIFY_FIELD_STATUS_STRING"; break;
+               case PRINTER_NOTIFY_FIELD_CJOBS: val = "PRINTER_NOTIFY_FIELD_CJOBS"; break;
+               case PRINTER_NOTIFY_FIELD_AVERAGE_PPM: val = "PRINTER_NOTIFY_FIELD_AVERAGE_PPM"; break;
+               case PRINTER_NOTIFY_FIELD_TOTAL_PAGES: val = "PRINTER_NOTIFY_FIELD_TOTAL_PAGES"; break;
+               case PRINTER_NOTIFY_FIELD_PAGES_PRINTED: val = "PRINTER_NOTIFY_FIELD_PAGES_PRINTED"; break;
+               case PRINTER_NOTIFY_FIELD_TOTAL_BYTES: val = "PRINTER_NOTIFY_FIELD_TOTAL_BYTES"; break;
+               case PRINTER_NOTIFY_FIELD_BYTES_PRINTED: val = "PRINTER_NOTIFY_FIELD_BYTES_PRINTED"; break;
+               case PRINTER_NOTIFY_FIELD_OBJECT_GUID: val = "PRINTER_NOTIFY_FIELD_OBJECT_GUID"; break;
+               case PRINTER_NOTIFY_FIELD_FRIENDLY_NAME: val = "PRINTER_NOTIFY_FIELD_FRIENDLY_NAME"; break;
        }
        ndr_print_enum(ndr, name, "ENUM", val, r);
 }
 
-static enum ndr_err_code ndr_push_spoolss_NotifyOptionType(struct ndr_push *ndr, int ndr_flags, const struct spoolss_NotifyOptionType *r)
+static enum ndr_err_code ndr_push_spoolss_NotifyType(struct ndr_push *ndr, int ndr_flags, enum spoolss_NotifyType r)
 {
-       uint32_t cntr_fields_1;
-       if (ndr_flags & NDR_SCALARS) {
-               NDR_CHECK(ndr_push_align(ndr, 4));
+       NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r));
+       return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_spoolss_NotifyType(struct ndr_pull *ndr, int ndr_flags, enum spoolss_NotifyType *r)
+{
+       uint16_t v;
+       NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &v));
+       *r = v;
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_spoolss_NotifyType(struct ndr_print *ndr, const char *name, enum spoolss_NotifyType r)
+{
+       const char *val = NULL;
+
+       switch (r) {
+               case PRINTER_NOTIFY_TYPE: val = "PRINTER_NOTIFY_TYPE"; break;
+               case JOB_NOTIFY_TYPE: val = "JOB_NOTIFY_TYPE"; break;
+       }
+       ndr_print_enum(ndr, name, "ENUM", val, r);
+}
+
+static enum ndr_err_code ndr_push_spoolss_Field(struct ndr_push *ndr, int ndr_flags, const union spoolss_Field *r)
+{
+       if (ndr_flags & NDR_SCALARS) {
+               int level = ndr_push_get_switch_value(ndr, r);
+               switch (level) {
+                       case PRINTER_NOTIFY_TYPE: {
+                               NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->field));
+                       break; }
+
+                       case JOB_NOTIFY_TYPE: {
+                               NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->field));
+                       break; }
+
+                       default: {
+                               NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->field));
+                       break; }
+
+               }
+       }
+       if (ndr_flags & NDR_BUFFERS) {
+               int level = ndr_push_get_switch_value(ndr, r);
+               switch (level) {
+                       case PRINTER_NOTIFY_TYPE:
+                       break;
+
+                       case JOB_NOTIFY_TYPE:
+                       break;
+
+                       default:
+                       break;
+
+               }
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_spoolss_Field(struct ndr_pull *ndr, int ndr_flags, union spoolss_Field *r)
+{
+       int level;
+       level = ndr_pull_get_switch_value(ndr, r);
+       if (ndr_flags & NDR_SCALARS) {
+               switch (level) {
+                       case PRINTER_NOTIFY_TYPE: {
+                               NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->field));
+                       break; }
+
+                       case JOB_NOTIFY_TYPE: {
+                               NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->field));
+                       break; }
+
+                       default: {
+                               NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->field));
+                       break; }
+
+               }
+       }
+       if (ndr_flags & NDR_BUFFERS) {
+               switch (level) {
+                       case PRINTER_NOTIFY_TYPE:
+                       break;
+
+                       case JOB_NOTIFY_TYPE:
+                       break;
+
+                       default:
+                       break;
+
+               }
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_push_spoolss_NotifyOptionType(struct ndr_push *ndr, int ndr_flags, const struct spoolss_NotifyOptionType *r)
+{
+       uint32_t cntr_fields_1;
+       if (ndr_flags & NDR_SCALARS) {
+               NDR_CHECK(ndr_push_align(ndr, 4));
                NDR_CHECK(ndr_push_spoolss_NotifyType(ndr, NDR_SCALARS, r->type));
                NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->u1));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->u2));
@@ -16856,7 +17175,8 @@ static enum ndr_err_code ndr_push_spoolss_NotifyOptionType(struct ndr_push *ndr,
                if (r->fields) {
                        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count));
                        for (cntr_fields_1 = 0; cntr_fields_1 < r->count; cntr_fields_1++) {
-                               NDR_CHECK(ndr_push_spoolss_Field(ndr, NDR_SCALARS, r->fields[cntr_fields_1]));
+                               NDR_CHECK(ndr_push_set_switch_value(ndr, &r->fields[cntr_fields_1], r->type));
+                               NDR_CHECK(ndr_push_spoolss_Field(ndr, NDR_SCALARS, &r->fields[cntr_fields_1]));
                        }
                }
        }
@@ -16892,6 +17212,7 @@ static enum ndr_err_code ndr_pull_spoolss_NotifyOptionType(struct ndr_pull *ndr,
                        _mem_save_fields_1 = NDR_PULL_GET_MEM_CTX(ndr);
                        NDR_PULL_SET_MEM_CTX(ndr, r->fields, 0);
                        for (cntr_fields_1 = 0; cntr_fields_1 < r->count; cntr_fields_1++) {
+                               NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->fields[cntr_fields_1], r->type));
                                NDR_CHECK(ndr_pull_spoolss_Field(ndr, NDR_SCALARS, &r->fields[cntr_fields_1]));
                        }
                        NDR_PULL_SET_MEM_CTX(ndr, _mem_save_fields_1, 0);
@@ -16922,7 +17243,8 @@ _PUBLIC_ void ndr_print_spoolss_NotifyOptionType(struct ndr_print *ndr, const ch
                for (cntr_fields_1=0;cntr_fields_1<r->count;cntr_fields_1++) {
                        char *idx_1=NULL;
                        if (asprintf(&idx_1, "[%d]", cntr_fields_1) != -1) {
-                               ndr_print_spoolss_Field(ndr, "fields", r->fields[cntr_fields_1]);
+                               ndr_print_set_switch_value(ndr, &r->fields[cntr_fields_1], r->type);
+                               ndr_print_spoolss_Field(ndr, "fields", &r->fields[cntr_fields_1]);
                                free(idx_1);
                        }
                }
@@ -17307,7 +17629,8 @@ static enum ndr_err_code ndr_push_spoolss_Notify(struct ndr_push *ndr, int ndr_f
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
                NDR_CHECK(ndr_push_spoolss_NotifyType(ndr, NDR_SCALARS, r->type));
-               NDR_CHECK(ndr_push_spoolss_Field(ndr, NDR_SCALARS, r->field));
+               NDR_CHECK(ndr_push_set_switch_value(ndr, &r->field, r->type));
+               NDR_CHECK(ndr_push_spoolss_Field(ndr, NDR_SCALARS, &r->field));
                NDR_CHECK(ndr_push_spoolss_NotifyTable(ndr, NDR_SCALARS, r->variable_type));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->job_id));
                NDR_CHECK(ndr_push_set_switch_value(ndr, &r->data, r->variable_type));
@@ -17324,6 +17647,7 @@ static enum ndr_err_code ndr_pull_spoolss_Notify(struct ndr_pull *ndr, int ndr_f
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_pull_align(ndr, 4));
                NDR_CHECK(ndr_pull_spoolss_NotifyType(ndr, NDR_SCALARS, &r->type));
+               NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->field, r->type));
                NDR_CHECK(ndr_pull_spoolss_Field(ndr, NDR_SCALARS, &r->field));
                NDR_CHECK(ndr_pull_spoolss_NotifyTable(ndr, NDR_SCALARS, &r->variable_type));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->job_id));
@@ -17341,7 +17665,8 @@ _PUBLIC_ void ndr_print_spoolss_Notify(struct ndr_print *ndr, const char *name,
        ndr_print_struct(ndr, name, "spoolss_Notify");
        ndr->depth++;
        ndr_print_spoolss_NotifyType(ndr, "type", r->type);
-       ndr_print_spoolss_Field(ndr, "field", r->field);
+       ndr_print_set_switch_value(ndr, &r->field, r->type);
+       ndr_print_spoolss_Field(ndr, "field", &r->field);
        ndr_print_spoolss_NotifyTable(ndr, "variable_type", r->variable_type);
        ndr_print_uint32(ndr, "job_id", r->job_id);
        ndr_print_set_switch_value(ndr, &r->data, r->variable_type);
@@ -18033,6 +18358,148 @@ _PUBLIC_ void ndr_print_spoolss_AccessRights(struct ndr_print *ndr, const char *
        ndr->depth--;
 }
 
+_PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrinterEnumValues(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterEnumValues *r)
+{
+       uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr);
+       if (ndr_flags & NDR_SCALARS) {
+               NDR_CHECK(ndr_push_align(ndr, 4));
+               NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset));
+               {
+                       uint32_t _flags_save_string = ndr->flags;
+                       ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+                       NDR_CHECK(ndr_push_relative_ptr1(ndr, r->value_name));
+                       ndr->flags = _flags_save_string;
+               }
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 2 * strlen_m_term(r->value_name)));
+               NDR_CHECK(ndr_push_winreg_Type(ndr, NDR_SCALARS, r->type));
+               NDR_CHECK(ndr_push_relative_ptr1(ndr, r->data));
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_spoolss_PrinterData(r->data, r->type, ndr->iconv_convenience, ndr->flags)));
+       }
+       if (ndr_flags & NDR_BUFFERS) {
+               NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, r));
+               {
+                       uint32_t _flags_save_string = ndr->flags;
+                       ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+                       if (r->value_name) {
+                               NDR_CHECK(ndr_push_relative_ptr2(ndr, r->value_name));
+                               NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->value_name));
+                       }
+                       ndr->flags = _flags_save_string;
+               }
+               if (r->data) {
+                       NDR_CHECK(ndr_push_relative_ptr2(ndr, r->data));
+                       {
+                               struct ndr_push *_ndr_data;
+                               NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_data, 0, r->data_length));
+                               NDR_CHECK(ndr_push_set_switch_value(_ndr_data, r->data, r->type));
+                               NDR_CHECK(ndr_push_spoolss_PrinterData(_ndr_data, NDR_SCALARS|NDR_BUFFERS, r->data));
+                               NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_data, 0, r->data_length));
+                       }
+               }
+       }
+       ndr_push_restore_relative_base_offset(ndr, _save_relative_base_offset);
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterEnumValues(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterEnumValues *r)
+{
+       uint32_t _save_relative_base_offset = ndr_pull_get_relative_base_offset(ndr);
+       uint32_t _ptr_value_name;
+       TALLOC_CTX *_mem_save_value_name_0;
+       uint32_t _ptr_data;
+       TALLOC_CTX *_mem_save_data_0;
+       if (ndr_flags & NDR_SCALARS) {
+               NDR_CHECK(ndr_pull_align(ndr, 4));
+               NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset));
+               {
+                       uint32_t _flags_save_string = ndr->flags;
+                       ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+                       NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_value_name));
+                       if (_ptr_value_name) {
+                               NDR_PULL_ALLOC(ndr, r->value_name);
+                               NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->value_name, _ptr_value_name));
+                       } else {
+                               r->value_name = NULL;
+                       }
+                       ndr->flags = _flags_save_string;
+               }
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->value_name_len));
+               NDR_CHECK(ndr_pull_winreg_Type(ndr, NDR_SCALARS, &r->type));
+               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data));
+               if (_ptr_data) {
+                       NDR_PULL_ALLOC(ndr, r->data);
+                       NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->data, _ptr_data));
+               } else {
+                       r->data = NULL;
+               }
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->data_length));
+       }
+       if (ndr_flags & NDR_BUFFERS) {
+               NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, r));
+               {
+                       uint32_t _flags_save_string = ndr->flags;
+                       ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+                       if (r->value_name) {
+                               uint32_t _relative_save_offset;
+                               _relative_save_offset = ndr->offset;
+                               NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->value_name));
+                               _mem_save_value_name_0 = NDR_PULL_GET_MEM_CTX(ndr);
+                               NDR_PULL_SET_MEM_CTX(ndr, r->value_name, 0);
+                               NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->value_name));
+                               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_value_name_0, 0);
+                               ndr->offset = _relative_save_offset;
+                       }
+                       ndr->flags = _flags_save_string;
+               }
+               if (r->data) {
+                       uint32_t _relative_save_offset;
+                       _relative_save_offset = ndr->offset;
+                       NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->data));
+                       _mem_save_data_0 = NDR_PULL_GET_MEM_CTX(ndr);
+                       NDR_PULL_SET_MEM_CTX(ndr, r->data, 0);
+                       {
+                               struct ndr_pull *_ndr_data;
+                               NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_data, 0, r->data_length));
+                               NDR_CHECK(ndr_pull_set_switch_value(_ndr_data, r->data, r->type));
+                               NDR_CHECK(ndr_pull_spoolss_PrinterData(_ndr_data, NDR_SCALARS|NDR_BUFFERS, r->data));
+                               NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_data, 0, r->data_length));
+                       }
+                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_0, 0);
+                       ndr->offset = _relative_save_offset;
+               }
+       }
+       ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_spoolss_PrinterEnumValues(struct ndr_print *ndr, const char *name, const struct spoolss_PrinterEnumValues *r)
+{
+       ndr_print_struct(ndr, name, "spoolss_PrinterEnumValues");
+       ndr->depth++;
+       ndr_print_ptr(ndr, "value_name", r->value_name);
+       ndr->depth++;
+       if (r->value_name) {
+               ndr_print_string(ndr, "value_name", r->value_name);
+       }
+       ndr->depth--;
+       ndr_print_uint32(ndr, "value_name_len", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2 * strlen_m_term(r->value_name):r->value_name_len);
+       ndr_print_winreg_Type(ndr, "type", r->type);
+       ndr_print_ptr(ndr, "data", r->data);
+       ndr->depth++;
+       if (r->data) {
+               ndr_print_set_switch_value(ndr, r->data, r->type);
+               ndr_print_spoolss_PrinterData(ndr, "data", r->data);
+       }
+       ndr->depth--;
+       ndr_print_uint32(ndr, "data_length", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?ndr_size_spoolss_PrinterData(r->data, r->type, ndr->iconv_convenience, ndr->flags):r->data_length);
+       ndr->depth--;
+}
+
+_PUBLIC_ size_t ndr_size_spoolss_PrinterEnumValues(const struct spoolss_PrinterEnumValues *r, struct smb_iconv_convenience *ic, int flags)
+{
+       return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterEnumValues, ic);
+}
+
 _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DeleteDriverFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r)
 {
        NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
@@ -18458,7 +18925,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull___spoolss_EnumPrinters(struct ndr_pull *ndr,
 
 _PUBLIC_ void ndr_print_spoolss_EnumPrinters(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumPrinters *r)
 {
-       uint32_t cntr_info_1;
+       uint32_t cntr_info_2;
        ndr_print_struct(ndr, name, "spoolss_EnumPrinters");
        ndr->depth++;
        if (flags & NDR_SET_VALUES) {
@@ -18493,20 +18960,23 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinters(struct ndr_print *ndr, const char *
                ndr->depth--;
                ndr_print_ptr(ndr, "info", r->out.info);
                ndr->depth++;
-               if (r->out.info) {
+               ndr_print_ptr(ndr, "info", *r->out.info);
+               ndr->depth++;
+               if (*r->out.info) {
                        ndr->print(ndr, "%s: ARRAY(%d)", "info", (int)*r->out.count);
                        ndr->depth++;
-                       for (cntr_info_1=0;cntr_info_1<*r->out.count;cntr_info_1++) {
-                               char *idx_1=NULL;
-                               if (asprintf(&idx_1, "[%d]", cntr_info_1) != -1) {
-                                       ndr_print_set_switch_value(ndr, &r->out.info[cntr_info_1], r->in.level);
-                                       ndr_print_spoolss_PrinterInfo(ndr, "info", &r->out.info[cntr_info_1]);
-                                       free(idx_1);
+                       for (cntr_info_2=0;cntr_info_2<*r->out.count;cntr_info_2++) {
+                               char *idx_2=NULL;
+                               if (asprintf(&idx_2, "[%d]", cntr_info_2) != -1) {
+                                       ndr_print_set_switch_value(ndr, &(*r->out.info)[cntr_info_2], r->in.level);
+                                       ndr_print_spoolss_PrinterInfo(ndr, "info", &(*r->out.info)[cntr_info_2]);
+                                       free(idx_2);
                                }
                        }
                        ndr->depth--;
                }
                ndr->depth--;
+               ndr->depth--;
                ndr_print_ptr(ndr, "needed", r->out.needed);
                ndr->depth++;
                ndr_print_uint32(ndr, "needed", *r->out.needed);
@@ -19037,7 +19507,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull___spoolss_EnumJobs(struct ndr_pull *ndr, int
 
 _PUBLIC_ void ndr_print_spoolss_EnumJobs(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumJobs *r)
 {
-       uint32_t cntr_info_1;
+       uint32_t cntr_info_2;
        ndr_print_struct(ndr, name, "spoolss_EnumJobs");
        ndr->depth++;
        if (flags & NDR_SET_VALUES) {
@@ -19071,20 +19541,23 @@ _PUBLIC_ void ndr_print_spoolss_EnumJobs(struct ndr_print *ndr, const char *name
                ndr->depth--;
                ndr_print_ptr(ndr, "info", r->out.info);
                ndr->depth++;
-               if (r->out.info) {
+               ndr_print_ptr(ndr, "info", *r->out.info);
+               ndr->depth++;
+               if (*r->out.info) {
                        ndr->print(ndr, "%s: ARRAY(%d)", "info", (int)*r->out.count);
                        ndr->depth++;
-                       for (cntr_info_1=0;cntr_info_1<*r->out.count;cntr_info_1++) {
-                               char *idx_1=NULL;
-                               if (asprintf(&idx_1, "[%d]", cntr_info_1) != -1) {
-                                       ndr_print_set_switch_value(ndr, &r->out.info[cntr_info_1], r->in.level);
-                                       ndr_print_spoolss_JobInfo(ndr, "info", &r->out.info[cntr_info_1]);
-                                       free(idx_1);
+                       for (cntr_info_2=0;cntr_info_2<*r->out.count;cntr_info_2++) {
+                               char *idx_2=NULL;
+                               if (asprintf(&idx_2, "[%d]", cntr_info_2) != -1) {
+                                       ndr_print_set_switch_value(ndr, &(*r->out.info)[cntr_info_2], r->in.level);
+                                       ndr_print_spoolss_JobInfo(ndr, "info", &(*r->out.info)[cntr_info_2]);
+                                       free(idx_2);
                                }
                        }
                        ndr->depth--;
                }
                ndr->depth--;
+               ndr->depth--;
                ndr_print_ptr(ndr, "needed", r->out.needed);
                ndr->depth++;
                ndr_print_uint32(ndr, "needed", *r->out.needed);
@@ -19726,7 +20199,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull___spoolss_EnumPrinterDrivers(struct ndr_pull
 
 _PUBLIC_ void ndr_print_spoolss_EnumPrinterDrivers(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumPrinterDrivers *r)
 {
-       uint32_t cntr_info_1;
+       uint32_t cntr_info_2;
        ndr_print_struct(ndr, name, "spoolss_EnumPrinterDrivers");
        ndr->depth++;
        if (flags & NDR_SET_VALUES) {
@@ -19766,20 +20239,23 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterDrivers(struct ndr_print *ndr, const
                ndr->depth--;
                ndr_print_ptr(ndr, "info", r->out.info);
                ndr->depth++;
-               if (r->out.info) {
+               ndr_print_ptr(ndr, "info", *r->out.info);
+               ndr->depth++;
+               if (*r->out.info) {
                        ndr->print(ndr, "%s: ARRAY(%d)", "info", (int)*r->out.count);
                        ndr->depth++;
-                       for (cntr_info_1=0;cntr_info_1<*r->out.count;cntr_info_1++) {
-                               char *idx_1=NULL;
-                               if (asprintf(&idx_1, "[%d]", cntr_info_1) != -1) {
-                                       ndr_print_set_switch_value(ndr, &r->out.info[cntr_info_1], r->in.level);
-                                       ndr_print_spoolss_DriverInfo(ndr, "info", &r->out.info[cntr_info_1]);
-                                       free(idx_1);
+                       for (cntr_info_2=0;cntr_info_2<*r->out.count;cntr_info_2++) {
+                               char *idx_2=NULL;
+                               if (asprintf(&idx_2, "[%d]", cntr_info_2) != -1) {
+                                       ndr_print_set_switch_value(ndr, &(*r->out.info)[cntr_info_2], r->in.level);
+                                       ndr_print_spoolss_DriverInfo(ndr, "info", &(*r->out.info)[cntr_info_2]);
+                                       free(idx_2);
                                }
                        }
                        ndr->depth--;
                }
                ndr->depth--;
+               ndr->depth--;
                ndr_print_ptr(ndr, "needed", r->out.needed);
                ndr->depth++;
                ndr_print_uint32(ndr, "needed", *r->out.needed);
@@ -20424,7 +20900,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull___spoolss_EnumPrintProcessors(struct ndr_pul
 
 _PUBLIC_ void ndr_print_spoolss_EnumPrintProcessors(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumPrintProcessors *r)
 {
-       uint32_t cntr_info_1;
+       uint32_t cntr_info_2;
        ndr_print_struct(ndr, name, "spoolss_EnumPrintProcessors");
        ndr->depth++;
        if (flags & NDR_SET_VALUES) {
@@ -20464,20 +20940,23 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrintProcessors(struct ndr_print *ndr, const
                ndr->depth--;
                ndr_print_ptr(ndr, "info", r->out.info);
                ndr->depth++;
-               if (r->out.info) {
+               ndr_print_ptr(ndr, "info", *r->out.info);
+               ndr->depth++;
+               if (*r->out.info) {
                        ndr->print(ndr, "%s: ARRAY(%d)", "info", (int)*r->out.count);
                        ndr->depth++;
-                       for (cntr_info_1=0;cntr_info_1<*r->out.count;cntr_info_1++) {
-                               char *idx_1=NULL;
-                               if (asprintf(&idx_1, "[%d]", cntr_info_1) != -1) {
-                                       ndr_print_set_switch_value(ndr, &r->out.info[cntr_info_1], r->in.level);
-                                       ndr_print_spoolss_PrintProcessorInfo(ndr, "info", &r->out.info[cntr_info_1]);
-                                       free(idx_1);
+                       for (cntr_info_2=0;cntr_info_2<*r->out.count;cntr_info_2++) {
+                               char *idx_2=NULL;
+                               if (asprintf(&idx_2, "[%d]", cntr_info_2) != -1) {
+                                       ndr_print_set_switch_value(ndr, &(*r->out.info)[cntr_info_2], r->in.level);
+                                       ndr_print_spoolss_PrintProcessorInfo(ndr, "info", &(*r->out.info)[cntr_info_2]);
+                                       free(idx_2);
                                }
                        }
                        ndr->depth--;
                }
                ndr->depth--;
+               ndr->depth--;
                ndr_print_ptr(ndr, "needed", r->out.needed);
                ndr->depth++;
                ndr_print_uint32(ndr, "needed", *r->out.needed);
@@ -21396,8 +21875,11 @@ _PUBLIC_ enum ndr_err_code ndr_push__spoolss_GetPrinterData(struct ndr_push *ndr
                if (r->out.type == NULL) {
                        return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
                }
-               NDR_CHECK(ndr_push_spoolss_PrinterDataType(ndr, NDR_SCALARS, *r->out.type));
-               NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->out.data));
+               NDR_CHECK(ndr_push_winreg_Type(ndr, NDR_SCALARS, *r->out.type));
+               if (r->out.data == NULL) {
+                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+               }
+               NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, *r->out.data));
                if (r->out.needed == NULL) {
                        return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
                }
@@ -21411,6 +21893,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull__spoolss_GetPrinterData(struct ndr_pull *ndr
 {
        TALLOC_CTX *_mem_save_handle_0;
        TALLOC_CTX *_mem_save_type_0;
+       TALLOC_CTX *_mem_save_data_0;
        TALLOC_CTX *_mem_save_needed_0;
        if (flags & NDR_IN) {
                ZERO_STRUCT(r->out);
@@ -21432,6 +21915,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull__spoolss_GetPrinterData(struct ndr_pull *ndr
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.offered));
                NDR_PULL_ALLOC(ndr, r->out.type);
                ZERO_STRUCTP(r->out.type);
+               NDR_PULL_ALLOC(ndr, r->out.data);
+               ZERO_STRUCTP(r->out.data);
                NDR_PULL_ALLOC(ndr, r->out.needed);
                ZERO_STRUCTP(r->out.needed);
        }
@@ -21441,9 +21926,15 @@ _PUBLIC_ enum ndr_err_code ndr_pull__spoolss_GetPrinterData(struct ndr_pull *ndr
                }
                _mem_save_type_0 = NDR_PULL_GET_MEM_CTX(ndr);
                NDR_PULL_SET_MEM_CTX(ndr, r->out.type, LIBNDR_FLAG_REF_ALLOC);
-               NDR_CHECK(ndr_pull_spoolss_PrinterDataType(ndr, NDR_SCALARS, r->out.type));
+               NDR_CHECK(ndr_pull_winreg_Type(ndr, NDR_SCALARS, r->out.type));
                NDR_PULL_SET_MEM_CTX(ndr, _mem_save_type_0, LIBNDR_FLAG_REF_ALLOC);
-               NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->out.data));
+               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                       NDR_PULL_ALLOC(ndr, r->out.data);
+               }
+               _mem_save_data_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->out.data, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, r->out.data));
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_0, LIBNDR_FLAG_REF_ALLOC);
                if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
                        NDR_PULL_ALLOC(ndr, r->out.needed);
                }
@@ -21459,25 +21950,37 @@ _PUBLIC_ enum ndr_err_code ndr_pull__spoolss_GetPrinterData(struct ndr_pull *ndr
 _PUBLIC_ enum ndr_err_code ndr_push___spoolss_GetPrinterData(struct ndr_push *ndr, int flags, const struct __spoolss_GetPrinterData *r)
 {
        if (flags & NDR_IN) {
-               NDR_CHECK(ndr_push_spoolss_PrinterDataType(ndr, NDR_SCALARS, r->in.type));
+               NDR_CHECK(ndr_push_winreg_Type(ndr, NDR_SCALARS, r->in.type));
        }
        if (flags & NDR_OUT) {
-               NDR_CHECK(ndr_push_set_switch_value(ndr, &r->out.data, r->in.type));
-               NDR_CHECK(ndr_push_spoolss_PrinterData(ndr, NDR_SCALARS|NDR_BUFFERS, &r->out.data));
+               if (r->out.data == NULL) {
+                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+               }
+               NDR_CHECK(ndr_push_set_switch_value(ndr, r->out.data, r->in.type));
+               NDR_CHECK(ndr_push_spoolss_PrinterData(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.data));
        }
        return NDR_ERR_SUCCESS;
 }
 
 _PUBLIC_ enum ndr_err_code ndr_pull___spoolss_GetPrinterData(struct ndr_pull *ndr, int flags, struct __spoolss_GetPrinterData *r)
 {
+       TALLOC_CTX *_mem_save_data_0;
        if (flags & NDR_IN) {
                ZERO_STRUCT(r->out);
 
-               NDR_CHECK(ndr_pull_spoolss_PrinterDataType(ndr, NDR_SCALARS, &r->in.type));
+               NDR_CHECK(ndr_pull_winreg_Type(ndr, NDR_SCALARS, &r->in.type));
+               NDR_PULL_ALLOC(ndr, r->out.data);
+               ZERO_STRUCTP(r->out.data);
        }
        if (flags & NDR_OUT) {
-               NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->out.data, r->in.type));
-               NDR_CHECK(ndr_pull_spoolss_PrinterData(ndr, NDR_SCALARS|NDR_BUFFERS, &r->out.data));
+               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                       NDR_PULL_ALLOC(ndr, r->out.data);
+               }
+               _mem_save_data_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->out.data, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_set_switch_value(ndr, r->out.data, r->in.type));
+               NDR_CHECK(ndr_pull_spoolss_PrinterData(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.data));
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_0, LIBNDR_FLAG_REF_ALLOC);
        }
        return NDR_ERR_SUCCESS;
 }
@@ -21505,10 +22008,13 @@ _PUBLIC_ void ndr_print_spoolss_GetPrinterData(struct ndr_print *ndr, const char
                ndr->depth++;
                ndr_print_ptr(ndr, "type", r->out.type);
                ndr->depth++;
-               ndr_print_spoolss_PrinterDataType(ndr, "type", *r->out.type);
+               ndr_print_winreg_Type(ndr, "type", *r->out.type);
+               ndr->depth--;
+               ndr_print_ptr(ndr, "data", r->out.data);
+               ndr->depth++;
+               ndr_print_set_switch_value(ndr, r->out.data, *r->out.type);
+               ndr_print_spoolss_PrinterData(ndr, "data", r->out.data);
                ndr->depth--;
-               ndr_print_set_switch_value(ndr, &r->out.data, *r->out.type);
-               ndr_print_spoolss_PrinterData(ndr, "data", &r->out.data);
                ndr_print_ptr(ndr, "needed", r->out.needed);
                ndr->depth++;
                ndr_print_uint32(ndr, "needed", *r->out.needed);
@@ -21530,7 +22036,7 @@ _PUBLIC_ enum ndr_err_code ndr_push__spoolss_SetPrinterData(struct ndr_push *ndr
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.value_name, CH_UTF16)));
                NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.value_name, ndr_charset_length(r->in.value_name, CH_UTF16), sizeof(uint16_t), CH_UTF16));
-               NDR_CHECK(ndr_push_spoolss_PrinterDataType(ndr, NDR_SCALARS, r->in.type));
+               NDR_CHECK(ndr_push_winreg_Type(ndr, NDR_SCALARS, r->in.type));
                NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->in.data));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in._offered));
        }
@@ -21543,11 +22049,14 @@ _PUBLIC_ enum ndr_err_code ndr_push__spoolss_SetPrinterData(struct ndr_push *ndr
 _PUBLIC_ enum ndr_err_code ndr_push___spoolss_SetPrinterData(struct ndr_push *ndr, int flags, const struct __spoolss_SetPrinterData *r)
 {
        if (flags & NDR_IN) {
-               NDR_CHECK(ndr_push_spoolss_PrinterDataType(ndr, NDR_SCALARS, r->in.type));
+               NDR_CHECK(ndr_push_winreg_Type(ndr, NDR_SCALARS, r->in.type));
        }
        if (flags & NDR_OUT) {
-               NDR_CHECK(ndr_push_set_switch_value(ndr, &r->out.data, r->in.type));
-               NDR_CHECK(ndr_push_spoolss_PrinterData(ndr, NDR_SCALARS|NDR_BUFFERS, &r->out.data));
+               if (r->out.data == NULL) {
+                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+               }
+               NDR_CHECK(ndr_push_set_switch_value(ndr, r->out.data, r->in.type));
+               NDR_CHECK(ndr_push_spoolss_PrinterData(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.data));
        }
        return NDR_ERR_SUCCESS;
 }
@@ -21570,7 +22079,7 @@ static enum ndr_err_code ndr_pull_spoolss_SetPrinterData(struct ndr_pull *ndr, i
                }
                NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.value_name), sizeof(uint16_t)));
                NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.value_name, ndr_get_array_length(ndr, &r->in.value_name), sizeof(uint16_t), CH_UTF16));
-               NDR_CHECK(ndr_pull_spoolss_PrinterDataType(ndr, NDR_SCALARS, &r->in.type));
+               NDR_CHECK(ndr_pull_winreg_Type(ndr, NDR_SCALARS, &r->in.type));
                {
                        struct ndr_pull *_ndr_data;
                        NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_data, 4, -1));
@@ -21601,7 +22110,7 @@ _PUBLIC_ void ndr_print_spoolss_SetPrinterData(struct ndr_print *ndr, const char
                ndr_print_policy_handle(ndr, "handle", r->in.handle);
                ndr->depth--;
                ndr_print_string(ndr, "value_name", r->in.value_name);
-               ndr_print_spoolss_PrinterDataType(ndr, "type", r->in.type);
+               ndr_print_winreg_Type(ndr, "type", r->in.type);
                ndr_print_set_switch_value(ndr, &r->in.data, r->in.type);
                ndr_print_spoolss_PrinterData(ndr, "data", &r->in.data);
                ndr_print_uint32(ndr, "_offered", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?ndr_size_spoolss_PrinterData(&r->in.data, r->in.type, ndr->iconv_convenience, flags):r->in._offered);
@@ -22251,7 +22760,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull___spoolss_EnumForms(struct ndr_pull *ndr, in
 
 _PUBLIC_ void ndr_print_spoolss_EnumForms(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumForms *r)
 {
-       uint32_t cntr_info_1;
+       uint32_t cntr_info_2;
        ndr_print_struct(ndr, name, "spoolss_EnumForms");
        ndr->depth++;
        if (flags & NDR_SET_VALUES) {
@@ -22283,20 +22792,23 @@ _PUBLIC_ void ndr_print_spoolss_EnumForms(struct ndr_print *ndr, const char *nam
                ndr->depth--;
                ndr_print_ptr(ndr, "info", r->out.info);
                ndr->depth++;
-               if (r->out.info) {
+               ndr_print_ptr(ndr, "info", *r->out.info);
+               ndr->depth++;
+               if (*r->out.info) {
                        ndr->print(ndr, "%s: ARRAY(%d)", "info", (int)*r->out.count);
                        ndr->depth++;
-                       for (cntr_info_1=0;cntr_info_1<*r->out.count;cntr_info_1++) {
-                               char *idx_1=NULL;
-                               if (asprintf(&idx_1, "[%d]", cntr_info_1) != -1) {
-                                       ndr_print_set_switch_value(ndr, &r->out.info[cntr_info_1], r->in.level);
-                                       ndr_print_spoolss_FormInfo(ndr, "info", &r->out.info[cntr_info_1]);
-                                       free(idx_1);
+                       for (cntr_info_2=0;cntr_info_2<*r->out.count;cntr_info_2++) {
+                               char *idx_2=NULL;
+                               if (asprintf(&idx_2, "[%d]", cntr_info_2) != -1) {
+                                       ndr_print_set_switch_value(ndr, &(*r->out.info)[cntr_info_2], r->in.level);
+                                       ndr_print_spoolss_FormInfo(ndr, "info", &(*r->out.info)[cntr_info_2]);
+                                       free(idx_2);
                                }
                        }
                        ndr->depth--;
                }
                ndr->depth--;
+               ndr->depth--;
                ndr_print_ptr(ndr, "needed", r->out.needed);
                ndr->depth++;
                ndr_print_uint32(ndr, "needed", *r->out.needed);
@@ -22471,7 +22983,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull___spoolss_EnumPorts(struct ndr_pull *ndr, in
 
 _PUBLIC_ void ndr_print_spoolss_EnumPorts(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumPorts *r)
 {
-       uint32_t cntr_info_1;
+       uint32_t cntr_info_2;
        ndr_print_struct(ndr, name, "spoolss_EnumPorts");
        ndr->depth++;
        if (flags & NDR_SET_VALUES) {
@@ -22505,20 +23017,23 @@ _PUBLIC_ void ndr_print_spoolss_EnumPorts(struct ndr_print *ndr, const char *nam
                ndr->depth--;
                ndr_print_ptr(ndr, "info", r->out.info);
                ndr->depth++;
-               if (r->out.info) {
+               ndr_print_ptr(ndr, "info", *r->out.info);
+               ndr->depth++;
+               if (*r->out.info) {
                        ndr->print(ndr, "%s: ARRAY(%d)", "info", (int)*r->out.count);
                        ndr->depth++;
-                       for (cntr_info_1=0;cntr_info_1<*r->out.count;cntr_info_1++) {
-                               char *idx_1=NULL;
-                               if (asprintf(&idx_1, "[%d]", cntr_info_1) != -1) {
-                                       ndr_print_set_switch_value(ndr, &r->out.info[cntr_info_1], r->in.level);
-                                       ndr_print_spoolss_PortInfo(ndr, "info", &r->out.info[cntr_info_1]);
-                                       free(idx_1);
+                       for (cntr_info_2=0;cntr_info_2<*r->out.count;cntr_info_2++) {
+                               char *idx_2=NULL;
+                               if (asprintf(&idx_2, "[%d]", cntr_info_2) != -1) {
+                                       ndr_print_set_switch_value(ndr, &(*r->out.info)[cntr_info_2], r->in.level);
+                                       ndr_print_spoolss_PortInfo(ndr, "info", &(*r->out.info)[cntr_info_2]);
+                                       free(idx_2);
                                }
                        }
                        ndr->depth--;
                }
                ndr->depth--;
+               ndr->depth--;
                ndr_print_ptr(ndr, "needed", r->out.needed);
                ndr->depth++;
                ndr_print_uint32(ndr, "needed", *r->out.needed);
@@ -22693,7 +23208,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull___spoolss_EnumMonitors(struct ndr_pull *ndr,
 
 _PUBLIC_ void ndr_print_spoolss_EnumMonitors(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumMonitors *r)
 {
-       uint32_t cntr_info_1;
+       uint32_t cntr_info_2;
        ndr_print_struct(ndr, name, "spoolss_EnumMonitors");
        ndr->depth++;
        if (flags & NDR_SET_VALUES) {
@@ -22727,20 +23242,23 @@ _PUBLIC_ void ndr_print_spoolss_EnumMonitors(struct ndr_print *ndr, const char *
                ndr->depth--;
                ndr_print_ptr(ndr, "info", r->out.info);
                ndr->depth++;
-               if (r->out.info) {
+               ndr_print_ptr(ndr, "info", *r->out.info);
+               ndr->depth++;
+               if (*r->out.info) {
                        ndr->print(ndr, "%s: ARRAY(%d)", "info", (int)*r->out.count);
                        ndr->depth++;
-                       for (cntr_info_1=0;cntr_info_1<*r->out.count;cntr_info_1++) {
-                               char *idx_1=NULL;
-                               if (asprintf(&idx_1, "[%d]", cntr_info_1) != -1) {
-                                       ndr_print_set_switch_value(ndr, &r->out.info[cntr_info_1], r->in.level);
-                                       ndr_print_spoolss_MonitorInfo(ndr, "info", &r->out.info[cntr_info_1]);
-                                       free(idx_1);
+                       for (cntr_info_2=0;cntr_info_2<*r->out.count;cntr_info_2++) {
+                               char *idx_2=NULL;
+                               if (asprintf(&idx_2, "[%d]", cntr_info_2) != -1) {
+                                       ndr_print_set_switch_value(ndr, &(*r->out.info)[cntr_info_2], r->in.level);
+                                       ndr_print_spoolss_MonitorInfo(ndr, "info", &(*r->out.info)[cntr_info_2]);
+                                       free(idx_2);
                                }
                        }
                        ndr->depth--;
                }
                ndr->depth--;
+               ndr->depth--;
                ndr_print_ptr(ndr, "needed", r->out.needed);
                ndr->depth++;
                ndr_print_uint32(ndr, "needed", *r->out.needed);
@@ -23373,28 +23891,198 @@ _PUBLIC_ void ndr_print_spoolss_DeletePrintProvidor(struct ndr_print *ndr, const
        ndr->depth--;
 }
 
-static enum ndr_err_code ndr_push_spoolss_EnumPrintProcDataTypes(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrintProcDataTypes *r)
+_PUBLIC_ enum ndr_err_code ndr_push__spoolss_EnumPrintProcDataTypes(struct ndr_push *ndr, int flags, const struct _spoolss_EnumPrintProcDataTypes *r)
 {
        if (flags & NDR_IN) {
+               NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.servername));
+               if (r->in.servername) {
+                       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.servername, CH_UTF16)));
+                       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
+                       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.servername, CH_UTF16)));
+                       NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.servername, ndr_charset_length(r->in.servername, CH_UTF16), sizeof(uint16_t), CH_UTF16));
+               }
+               NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.print_processor_name));
+               if (r->in.print_processor_name) {
+                       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.print_processor_name, CH_UTF16)));
+                       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
+                       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.print_processor_name, CH_UTF16)));
+                       NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.print_processor_name, ndr_charset_length(r->in.print_processor_name, CH_UTF16), sizeof(uint16_t), CH_UTF16));
+               }
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.level));
+               NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.buffer));
+               if (r->in.buffer) {
+                       NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, *r->in.buffer));
+               }
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.offered));
        }
        if (flags & NDR_OUT) {
+               NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.info));
+               if (r->out.info) {
+                       NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, *r->out.info));
+               }
+               if (r->out.needed == NULL) {
+                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+               }
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.needed));
+               if (r->out.count == NULL) {
+                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+               }
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.count));
                NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
        }
        return NDR_ERR_SUCCESS;
 }
 
-static enum ndr_err_code ndr_pull_spoolss_EnumPrintProcDataTypes(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrintProcDataTypes *r)
+_PUBLIC_ enum ndr_err_code ndr_pull__spoolss_EnumPrintProcDataTypes(struct ndr_pull *ndr, int flags, struct _spoolss_EnumPrintProcDataTypes *r)
 {
+       uint32_t _ptr_servername;
+       uint32_t _ptr_print_processor_name;
+       uint32_t _ptr_buffer;
+       uint32_t _ptr_info;
+       TALLOC_CTX *_mem_save_servername_0;
+       TALLOC_CTX *_mem_save_print_processor_name_0;
+       TALLOC_CTX *_mem_save_buffer_0;
+       TALLOC_CTX *_mem_save_info_0;
+       TALLOC_CTX *_mem_save_needed_0;
+       TALLOC_CTX *_mem_save_count_0;
        if (flags & NDR_IN) {
-       }
-       if (flags & NDR_OUT) {
-               NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
-       }
+               ZERO_STRUCT(r->out);
+
+               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_servername));
+               if (_ptr_servername) {
+                       NDR_PULL_ALLOC(ndr, r->in.servername);
+               } else {
+                       r->in.servername = NULL;
+               }
+               if (r->in.servername) {
+                       _mem_save_servername_0 = NDR_PULL_GET_MEM_CTX(ndr);
+                       NDR_PULL_SET_MEM_CTX(ndr, r->in.servername, 0);
+                       NDR_CHECK(ndr_pull_array_size(ndr, &r->in.servername));
+                       NDR_CHECK(ndr_pull_array_length(ndr, &r->in.servername));
+                       if (ndr_get_array_length(ndr, &r->in.servername) > ndr_get_array_size(ndr, &r->in.servername)) {
+                               return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->in.servername), ndr_get_array_length(ndr, &r->in.servername));
+                       }
+                       NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.servername), sizeof(uint16_t)));
+                       NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.servername, ndr_get_array_length(ndr, &r->in.servername), sizeof(uint16_t), CH_UTF16));
+                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_servername_0, 0);
+               }
+               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_print_processor_name));
+               if (_ptr_print_processor_name) {
+                       NDR_PULL_ALLOC(ndr, r->in.print_processor_name);
+               } else {
+                       r->in.print_processor_name = NULL;
+               }
+               if (r->in.print_processor_name) {
+                       _mem_save_print_processor_name_0 = NDR_PULL_GET_MEM_CTX(ndr);
+                       NDR_PULL_SET_MEM_CTX(ndr, r->in.print_processor_name, 0);
+                       NDR_CHECK(ndr_pull_array_size(ndr, &r->in.print_processor_name));
+                       NDR_CHECK(ndr_pull_array_length(ndr, &r->in.print_processor_name));
+                       if (ndr_get_array_length(ndr, &r->in.print_processor_name) > ndr_get_array_size(ndr, &r->in.print_processor_name)) {
+                               return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->in.print_processor_name), ndr_get_array_length(ndr, &r->in.print_processor_name));
+                       }
+                       NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.print_processor_name), sizeof(uint16_t)));
+                       NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.print_processor_name, ndr_get_array_length(ndr, &r->in.print_processor_name), sizeof(uint16_t), CH_UTF16));
+                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_print_processor_name_0, 0);
+               }
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.level));
+               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_buffer));
+               if (_ptr_buffer) {
+                       NDR_PULL_ALLOC(ndr, r->in.buffer);
+               } else {
+                       r->in.buffer = NULL;
+               }
+               if (r->in.buffer) {
+                       _mem_save_buffer_0 = NDR_PULL_GET_MEM_CTX(ndr);
+                       NDR_PULL_SET_MEM_CTX(ndr, r->in.buffer, 0);
+                       NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, r->in.buffer));
+                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_buffer_0, 0);
+               }
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.offered));
+               NDR_PULL_ALLOC(ndr, r->out.needed);
+               ZERO_STRUCTP(r->out.needed);
+               NDR_PULL_ALLOC(ndr, r->out.count);
+               ZERO_STRUCTP(r->out.count);
+       }
+       if (flags & NDR_OUT) {
+               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info));
+               if (_ptr_info) {
+                       NDR_PULL_ALLOC(ndr, r->out.info);
+               } else {
+                       r->out.info = NULL;
+               }
+               if (r->out.info) {
+                       _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr);
+                       NDR_PULL_SET_MEM_CTX(ndr, r->out.info, 0);
+                       NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, r->out.info));
+                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0);
+               }
+               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                       NDR_PULL_ALLOC(ndr, r->out.needed);
+               }
+               _mem_save_needed_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->out.needed, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.needed));
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_needed_0, LIBNDR_FLAG_REF_ALLOC);
+               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                       NDR_PULL_ALLOC(ndr, r->out.count);
+               }
+               _mem_save_count_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->out.count, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.count));
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_count_0, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push___spoolss_EnumPrintProcDataTypes(struct ndr_push *ndr, int flags, const struct __spoolss_EnumPrintProcDataTypes *r)
+{
+       uint32_t cntr_info_0;
+       if (flags & NDR_IN) {
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.level));
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.count));
+       }
+       if (flags & NDR_OUT) {
+               for (cntr_info_0 = 0; cntr_info_0 < r->in.count; cntr_info_0++) {
+                       NDR_CHECK(ndr_push_set_switch_value(ndr, &r->out.info[cntr_info_0], r->in.level));
+                       NDR_CHECK(ndr_push_spoolss_PrintProcDataTypesInfo(ndr, NDR_SCALARS, &r->out.info[cntr_info_0]));
+               }
+               for (cntr_info_0 = 0; cntr_info_0 < r->in.count; cntr_info_0++) {
+                       NDR_CHECK(ndr_push_spoolss_PrintProcDataTypesInfo(ndr, NDR_BUFFERS, &r->out.info[cntr_info_0]));
+               }
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull___spoolss_EnumPrintProcDataTypes(struct ndr_pull *ndr, int flags, struct __spoolss_EnumPrintProcDataTypes *r)
+{
+       uint32_t cntr_info_0;
+       TALLOC_CTX *_mem_save_info_0;
+       if (flags & NDR_IN) {
+               ZERO_STRUCT(r->out);
+
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.level));
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.count));
+       }
+       if (flags & NDR_OUT) {
+               NDR_PULL_ALLOC_N(ndr, r->out.info, r->in.count);
+               _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->out.info, 0);
+               for (cntr_info_0 = 0; cntr_info_0 < r->in.count; cntr_info_0++) {
+                       NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->out.info[cntr_info_0], r->in.level));
+                       NDR_CHECK(ndr_pull_spoolss_PrintProcDataTypesInfo(ndr, NDR_SCALARS, &r->out.info[cntr_info_0]));
+               }
+               for (cntr_info_0 = 0; cntr_info_0 < r->in.count; cntr_info_0++) {
+                       NDR_CHECK(ndr_pull_spoolss_PrintProcDataTypesInfo(ndr, NDR_BUFFERS, &r->out.info[cntr_info_0]));
+               }
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0);
+       }
        return NDR_ERR_SUCCESS;
 }
 
 _PUBLIC_ void ndr_print_spoolss_EnumPrintProcDataTypes(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumPrintProcDataTypes *r)
 {
+       uint32_t cntr_info_2;
        ndr_print_struct(ndr, name, "spoolss_EnumPrintProcDataTypes");
        ndr->depth++;
        if (flags & NDR_SET_VALUES) {
@@ -23403,11 +24091,58 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrintProcDataTypes(struct ndr_print *ndr, co
        if (flags & NDR_IN) {
                ndr_print_struct(ndr, "in", "spoolss_EnumPrintProcDataTypes");
                ndr->depth++;
+               ndr_print_ptr(ndr, "servername", r->in.servername);
+               ndr->depth++;
+               if (r->in.servername) {
+                       ndr_print_string(ndr, "servername", r->in.servername);
+               }
+               ndr->depth--;
+               ndr_print_ptr(ndr, "print_processor_name", r->in.print_processor_name);
+               ndr->depth++;
+               if (r->in.print_processor_name) {
+                       ndr_print_string(ndr, "print_processor_name", r->in.print_processor_name);
+               }
+               ndr->depth--;
+               ndr_print_uint32(ndr, "level", r->in.level);
+               ndr_print_ptr(ndr, "buffer", r->in.buffer);
+               ndr->depth++;
+               if (r->in.buffer) {
+                       ndr_print_DATA_BLOB(ndr, "buffer", *r->in.buffer);
+               }
+               ndr->depth--;
+               ndr_print_uint32(ndr, "offered", r->in.offered);
                ndr->depth--;
        }
        if (flags & NDR_OUT) {
                ndr_print_struct(ndr, "out", "spoolss_EnumPrintProcDataTypes");
                ndr->depth++;
+               ndr_print_ptr(ndr, "count", r->out.count);
+               ndr->depth++;
+               ndr_print_uint32(ndr, "count", *r->out.count);
+               ndr->depth--;
+               ndr_print_ptr(ndr, "info", r->out.info);
+               ndr->depth++;
+               ndr_print_ptr(ndr, "info", *r->out.info);
+               ndr->depth++;
+               if (*r->out.info) {
+                       ndr->print(ndr, "%s: ARRAY(%d)", "info", (int)*r->out.count);
+                       ndr->depth++;
+                       for (cntr_info_2=0;cntr_info_2<*r->out.count;cntr_info_2++) {
+                               char *idx_2=NULL;
+                               if (asprintf(&idx_2, "[%d]", cntr_info_2) != -1) {
+                                       ndr_print_set_switch_value(ndr, &(*r->out.info)[cntr_info_2], r->in.level);
+                                       ndr_print_spoolss_PrintProcDataTypesInfo(ndr, "info", &(*r->out.info)[cntr_info_2]);
+                                       free(idx_2);
+                               }
+                       }
+                       ndr->depth--;
+               }
+               ndr->depth--;
+               ndr->depth--;
+               ndr_print_ptr(ndr, "needed", r->out.needed);
+               ndr->depth++;
+               ndr_print_uint32(ndr, "needed", *r->out.needed);
+               ndr->depth--;
                ndr_print_WERROR(ndr, "result", r->out.result);
                ndr->depth--;
        }
@@ -25110,14 +25845,20 @@ static enum ndr_err_code ndr_push_spoolss_EnumPrinterData(struct ndr_push *ndr,
                        return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
                }
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.value_needed));
-               if (r->out.printerdata_type == NULL) {
+               if (r->out.type == NULL) {
                        return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
                }
-               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.printerdata_type));
-               if (r->out.buffer == NULL) {
-                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+               NDR_CHECK(ndr_push_winreg_Type(ndr, NDR_SCALARS, *r->out.type));
+               {
+                       uint32_t _flags_save_uint8 = ndr->flags;
+                       ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX);
+                       if (r->out.data == NULL) {
+                               return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+                       }
+                       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.data_offered));
+                       NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.data, r->in.data_offered));
+                       ndr->flags = _flags_save_uint8;
                }
-               NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, *r->out.buffer));
                if (r->out.data_needed == NULL) {
                        return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
                }
@@ -25131,8 +25872,7 @@ static enum ndr_err_code ndr_pull_spoolss_EnumPrinterData(struct ndr_pull *ndr,
 {
        TALLOC_CTX *_mem_save_handle_0;
        TALLOC_CTX *_mem_save_value_needed_0;
-       TALLOC_CTX *_mem_save_printerdata_type_0;
-       TALLOC_CTX *_mem_save_buffer_0;
+       TALLOC_CTX *_mem_save_type_0;
        TALLOC_CTX *_mem_save_data_needed_0;
        if (flags & NDR_IN) {
                ZERO_STRUCT(r->out);
@@ -25149,10 +25889,10 @@ static enum ndr_err_code ndr_pull_spoolss_EnumPrinterData(struct ndr_pull *ndr,
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.data_offered));
                NDR_PULL_ALLOC(ndr, r->out.value_needed);
                ZERO_STRUCTP(r->out.value_needed);
-               NDR_PULL_ALLOC(ndr, r->out.printerdata_type);
-               ZERO_STRUCTP(r->out.printerdata_type);
-               NDR_PULL_ALLOC(ndr, r->out.buffer);
-               ZERO_STRUCTP(r->out.buffer);
+               NDR_PULL_ALLOC(ndr, r->out.type);
+               ZERO_STRUCTP(r->out.type);
+               NDR_PULL_ALLOC_N(ndr, r->out.data, r->in.data_offered);
+               memset(r->out.data, 0, (r->in.data_offered) * sizeof(*r->out.data));
                NDR_PULL_ALLOC(ndr, r->out.data_needed);
                ZERO_STRUCTP(r->out.data_needed);
        }
@@ -25167,19 +25907,22 @@ static enum ndr_err_code ndr_pull_spoolss_EnumPrinterData(struct ndr_pull *ndr,
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.value_needed));
                NDR_PULL_SET_MEM_CTX(ndr, _mem_save_value_needed_0, LIBNDR_FLAG_REF_ALLOC);
                if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
-                       NDR_PULL_ALLOC(ndr, r->out.printerdata_type);
+                       NDR_PULL_ALLOC(ndr, r->out.type);
                }
-               _mem_save_printerdata_type_0 = NDR_PULL_GET_MEM_CTX(ndr);
-               NDR_PULL_SET_MEM_CTX(ndr, r->out.printerdata_type, LIBNDR_FLAG_REF_ALLOC);
-               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.printerdata_type));
-               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_printerdata_type_0, LIBNDR_FLAG_REF_ALLOC);
-               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
-                       NDR_PULL_ALLOC(ndr, r->out.buffer);
+               _mem_save_type_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->out.type, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_winreg_Type(ndr, NDR_SCALARS, r->out.type));
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_type_0, LIBNDR_FLAG_REF_ALLOC);
+               {
+                       uint32_t _flags_save_uint8 = ndr->flags;
+                       ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX);
+                       NDR_CHECK(ndr_pull_array_size(ndr, &r->out.data));
+                       if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                               NDR_PULL_ALLOC_N(ndr, r->out.data, ndr_get_array_size(ndr, &r->out.data));
+                       }
+                       NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.data, ndr_get_array_size(ndr, &r->out.data)));
+                       ndr->flags = _flags_save_uint8;
                }
-               _mem_save_buffer_0 = NDR_PULL_GET_MEM_CTX(ndr);
-               NDR_PULL_SET_MEM_CTX(ndr, r->out.buffer, LIBNDR_FLAG_REF_ALLOC);
-               NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, r->out.buffer));
-               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_buffer_0, LIBNDR_FLAG_REF_ALLOC);
                if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
                        NDR_PULL_ALLOC(ndr, r->out.data_needed);
                }
@@ -25191,6 +25934,9 @@ static enum ndr_err_code ndr_pull_spoolss_EnumPrinterData(struct ndr_pull *ndr,
                if (r->out.value_name) {
                        NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.value_name, r->in.value_offered / 2));
                }
+               if (r->out.data) {
+                       NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.data, r->in.data_offered));
+               }
        }
        return NDR_ERR_SUCCESS;
 }
@@ -25222,13 +25968,13 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterData(struct ndr_print *ndr, const cha
                ndr->depth++;
                ndr_print_uint32(ndr, "value_needed", *r->out.value_needed);
                ndr->depth--;
-               ndr_print_ptr(ndr, "printerdata_type", r->out.printerdata_type);
+               ndr_print_ptr(ndr, "type", r->out.type);
                ndr->depth++;
-               ndr_print_uint32(ndr, "printerdata_type", *r->out.printerdata_type);
+               ndr_print_winreg_Type(ndr, "type", *r->out.type);
                ndr->depth--;
-               ndr_print_ptr(ndr, "buffer", r->out.buffer);
+               ndr_print_ptr(ndr, "data", r->out.data);
                ndr->depth++;
-               ndr_print_DATA_BLOB(ndr, "buffer", *r->out.buffer);
+               ndr_print_array_uint8(ndr, "data", r->out.data, r->in.data_offered);
                ndr->depth--;
                ndr_print_ptr(ndr, "data_needed", r->out.data_needed);
                ndr->depth++;
@@ -25447,7 +26193,7 @@ static enum ndr_err_code ndr_push_spoolss_SetPrinterDataEx(struct ndr_push *ndr,
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.value_name, CH_UTF16)));
                NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.value_name, ndr_charset_length(r->in.value_name, CH_UTF16), sizeof(uint16_t), CH_UTF16));
-               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.type));
+               NDR_CHECK(ndr_push_winreg_Type(ndr, NDR_SCALARS, r->in.type));
                if (r->in.buffer == NULL) {
                        return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
                }
@@ -25486,7 +26232,7 @@ static enum ndr_err_code ndr_pull_spoolss_SetPrinterDataEx(struct ndr_pull *ndr,
                }
                NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.value_name), sizeof(uint16_t)));
                NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.value_name, ndr_get_array_length(ndr, &r->in.value_name), sizeof(uint16_t), CH_UTF16));
-               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.type));
+               NDR_CHECK(ndr_pull_winreg_Type(ndr, NDR_SCALARS, &r->in.type));
                NDR_CHECK(ndr_pull_array_size(ndr, &r->in.buffer));
                if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
                        NDR_PULL_ALLOC_N(ndr, r->in.buffer, ndr_get_array_size(ndr, &r->in.buffer));
@@ -25519,7 +26265,7 @@ _PUBLIC_ void ndr_print_spoolss_SetPrinterDataEx(struct ndr_print *ndr, const ch
                ndr->depth--;
                ndr_print_string(ndr, "key_name", r->in.key_name);
                ndr_print_string(ndr, "value_name", r->in.value_name);
-               ndr_print_uint32(ndr, "type", r->in.type);
+               ndr_print_winreg_Type(ndr, "type", r->in.type);
                ndr_print_ptr(ndr, "buffer", r->in.buffer);
                ndr->depth++;
                ndr_print_array_uint8(ndr, "buffer", r->in.buffer, r->in.offered);
@@ -25557,7 +26303,7 @@ static enum ndr_err_code ndr_push_spoolss_GetPrinterDataEx(struct ndr_push *ndr,
                if (r->out.type == NULL) {
                        return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
                }
-               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.type));
+               NDR_CHECK(ndr_push_winreg_Type(ndr, NDR_SCALARS, *r->out.type));
                if (r->out.buffer == NULL) {
                        return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
                }
@@ -25615,7 +26361,7 @@ static enum ndr_err_code ndr_pull_spoolss_GetPrinterDataEx(struct ndr_pull *ndr,
                }
                _mem_save_type_0 = NDR_PULL_GET_MEM_CTX(ndr);
                NDR_PULL_SET_MEM_CTX(ndr, r->out.type, LIBNDR_FLAG_REF_ALLOC);
-               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.type));
+               NDR_CHECK(ndr_pull_winreg_Type(ndr, NDR_SCALARS, r->out.type));
                NDR_PULL_SET_MEM_CTX(ndr, _mem_save_type_0, LIBNDR_FLAG_REF_ALLOC);
                NDR_CHECK(ndr_pull_array_size(ndr, &r->out.buffer));
                if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
@@ -25661,7 +26407,7 @@ _PUBLIC_ void ndr_print_spoolss_GetPrinterDataEx(struct ndr_print *ndr, const ch
                ndr->depth++;
                ndr_print_ptr(ndr, "type", r->out.type);
                ndr->depth++;
-               ndr_print_uint32(ndr, "type", *r->out.type);
+               ndr_print_winreg_Type(ndr, "type", *r->out.type);
                ndr->depth--;
                ndr_print_ptr(ndr, "buffer", r->out.buffer);
                ndr->depth++;
@@ -25677,7 +26423,7 @@ _PUBLIC_ void ndr_print_spoolss_GetPrinterDataEx(struct ndr_print *ndr, const ch
        ndr->depth--;
 }
 
-_PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterDataEx(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrinterDataEx *r)
+_PUBLIC_ enum ndr_err_code ndr_push__spoolss_EnumPrinterDataEx(struct ndr_push *ndr, int flags, const struct _spoolss_EnumPrinterDataEx *r)
 {
        if (flags & NDR_IN) {
                if (r->in.handle == NULL) {
@@ -25691,11 +26437,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterDataEx(struct ndr_push *n
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.offered));
        }
        if (flags & NDR_OUT) {
-               if (r->out.buffer == NULL) {
-                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
-               }
-               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.offered));
-               NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.offered));
+               NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->out.info));
                if (r->out.needed == NULL) {
                        return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
                }
@@ -25709,7 +26451,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterDataEx(struct ndr_push *n
        return NDR_ERR_SUCCESS;
 }
 
-_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterDataEx(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinterDataEx *r)
+_PUBLIC_ enum ndr_err_code ndr_pull__spoolss_EnumPrinterDataEx(struct ndr_pull *ndr, int flags, struct _spoolss_EnumPrinterDataEx *r)
 {
        TALLOC_CTX *_mem_save_handle_0;
        TALLOC_CTX *_mem_save_needed_0;
@@ -25732,19 +26474,13 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterDataEx(struct ndr_pull *n
                NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.key_name), sizeof(uint16_t)));
                NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.key_name, ndr_get_array_length(ndr, &r->in.key_name), sizeof(uint16_t), CH_UTF16));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.offered));
-               NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.offered);
-               memset(r->out.buffer, 0, (r->in.offered) * sizeof(*r->out.buffer));
                NDR_PULL_ALLOC(ndr, r->out.needed);
                ZERO_STRUCTP(r->out.needed);
                NDR_PULL_ALLOC(ndr, r->out.count);
                ZERO_STRUCTP(r->out.count);
        }
        if (flags & NDR_OUT) {
-               NDR_CHECK(ndr_pull_array_size(ndr, &r->out.buffer));
-               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
-                       NDR_PULL_ALLOC_N(ndr, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer));
-               }
-               NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer)));
+               NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->out.info));
                if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
                        NDR_PULL_ALLOC(ndr, r->out.needed);
                }
@@ -25760,15 +26496,54 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterDataEx(struct ndr_pull *n
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.count));
                NDR_PULL_SET_MEM_CTX(ndr, _mem_save_count_0, LIBNDR_FLAG_REF_ALLOC);
                NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
-               if (r->out.buffer) {
-                       NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.buffer, r->in.offered));
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push___spoolss_EnumPrinterDataEx(struct ndr_push *ndr, int flags, const struct __spoolss_EnumPrinterDataEx *r)
+{
+       uint32_t cntr_info_0;
+       if (flags & NDR_IN) {
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.count));
+       }
+       if (flags & NDR_OUT) {
+               for (cntr_info_0 = 0; cntr_info_0 < r->in.count; cntr_info_0++) {
+                       NDR_CHECK(ndr_push_spoolss_PrinterEnumValues(ndr, NDR_SCALARS, &r->out.info[cntr_info_0]));
+               }
+               for (cntr_info_0 = 0; cntr_info_0 < r->in.count; cntr_info_0++) {
+                       NDR_CHECK(ndr_push_spoolss_PrinterEnumValues(ndr, NDR_BUFFERS, &r->out.info[cntr_info_0]));
+               }
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull___spoolss_EnumPrinterDataEx(struct ndr_pull *ndr, int flags, struct __spoolss_EnumPrinterDataEx *r)
+{
+       uint32_t cntr_info_0;
+       TALLOC_CTX *_mem_save_info_0;
+       if (flags & NDR_IN) {
+               ZERO_STRUCT(r->out);
+
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.count));
+       }
+       if (flags & NDR_OUT) {
+               NDR_PULL_ALLOC_N(ndr, r->out.info, r->in.count);
+               _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->out.info, 0);
+               for (cntr_info_0 = 0; cntr_info_0 < r->in.count; cntr_info_0++) {
+                       NDR_CHECK(ndr_pull_spoolss_PrinterEnumValues(ndr, NDR_SCALARS, &r->out.info[cntr_info_0]));
+               }
+               for (cntr_info_0 = 0; cntr_info_0 < r->in.count; cntr_info_0++) {
+                       NDR_CHECK(ndr_pull_spoolss_PrinterEnumValues(ndr, NDR_BUFFERS, &r->out.info[cntr_info_0]));
                }
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0);
        }
        return NDR_ERR_SUCCESS;
 }
 
 _PUBLIC_ void ndr_print_spoolss_EnumPrinterDataEx(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumPrinterDataEx *r)
 {
+       uint32_t cntr_info_2;
        ndr_print_struct(ndr, name, "spoolss_EnumPrinterDataEx");
        ndr->depth++;
        if (flags & NDR_SET_VALUES) {
@@ -25788,17 +26563,31 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterDataEx(struct ndr_print *ndr, const c
        if (flags & NDR_OUT) {
                ndr_print_struct(ndr, "out", "spoolss_EnumPrinterDataEx");
                ndr->depth++;
-               ndr_print_ptr(ndr, "buffer", r->out.buffer);
+               ndr_print_ptr(ndr, "count", r->out.count);
                ndr->depth++;
-               ndr_print_array_uint8(ndr, "buffer", r->out.buffer, r->in.offered);
+               ndr_print_uint32(ndr, "count", *r->out.count);
                ndr->depth--;
-               ndr_print_ptr(ndr, "needed", r->out.needed);
+               ndr_print_ptr(ndr, "info", r->out.info);
                ndr->depth++;
-               ndr_print_uint32(ndr, "needed", *r->out.needed);
+               ndr_print_ptr(ndr, "info", *r->out.info);
+               ndr->depth++;
+               if (*r->out.info) {
+                       ndr->print(ndr, "%s: ARRAY(%d)", "info", (int)*r->out.count);
+                       ndr->depth++;
+                       for (cntr_info_2=0;cntr_info_2<*r->out.count;cntr_info_2++) {
+                               char *idx_2=NULL;
+                               if (asprintf(&idx_2, "[%d]", cntr_info_2) != -1) {
+                                       ndr_print_spoolss_PrinterEnumValues(ndr, "info", &(*r->out.info)[cntr_info_2]);
+                                       free(idx_2);
+                               }
+                       }
+                       ndr->depth--;
+               }
                ndr->depth--;
-               ndr_print_ptr(ndr, "count", r->out.count);
+               ndr->depth--;
+               ndr_print_ptr(ndr, "needed", r->out.needed);
                ndr->depth++;
-               ndr_print_uint32(ndr, "count", *r->out.count);
+               ndr_print_uint32(ndr, "needed", *r->out.needed);
                ndr->depth--;
                ndr_print_WERROR(ndr, "result", r->out.result);
                ndr->depth--;
@@ -25808,7 +26597,6 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterDataEx(struct ndr_print *ndr, const c
 
 _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterKey(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrinterKey *r)
 {
-       uint32_t cntr_key_buffer_1;
        if (flags & NDR_IN) {
                if (r->in.handle == NULL) {
                        return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
@@ -25818,15 +26606,25 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterKey(struct ndr_push *ndr,
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.key_name, CH_UTF16)));
                NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.key_name, ndr_charset_length(r->in.key_name, CH_UTF16), sizeof(uint16_t), CH_UTF16));
-               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.key_buffer_size));
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.offered));
        }
        if (flags & NDR_OUT) {
-               if (r->out.key_buffer == NULL) {
-                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
-               }
-               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.key_buffer_size / 2));
-               for (cntr_key_buffer_1 = 0; cntr_key_buffer_1 < r->in.key_buffer_size / 2; cntr_key_buffer_1++) {
-                       NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->out.key_buffer[cntr_key_buffer_1]));
+               {
+                       uint32_t _flags_save_string_array = ndr->flags;
+                       ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+                       if (r->out.key_buffer == NULL) {
+                               return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+                       }
+                       NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.key_buffer));
+                       if (*r->out.key_buffer) {
+                               {
+                                       struct ndr_push *_ndr_key_buffer;
+                                       NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_key_buffer, 0, r->in.offered));
+                                       NDR_CHECK(ndr_push_string_array(_ndr_key_buffer, NDR_SCALARS, *r->out.key_buffer));
+                                       NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_key_buffer, 0, r->in.offered));
+                               }
+                       }
+                       ndr->flags = _flags_save_string_array;
                }
                if (r->out.needed == NULL) {
                        return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
@@ -25839,8 +26637,9 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterKey(struct ndr_push *ndr,
 
 _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterKey(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinterKey *r)
 {
-       uint32_t cntr_key_buffer_1;
+       uint32_t _ptr_key_buffer;
        TALLOC_CTX *_mem_save_handle_0;
+       TALLOC_CTX *_mem_save_key_buffer_0;
        TALLOC_CTX *_mem_save_key_buffer_1;
        TALLOC_CTX *_mem_save_needed_0;
        if (flags & NDR_IN) {
@@ -25860,23 +26659,41 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterKey(struct ndr_pull *ndr,
                }
                NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.key_name), sizeof(uint16_t)));
                NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.key_name, ndr_get_array_length(ndr, &r->in.key_name), sizeof(uint16_t), CH_UTF16));
-               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.key_buffer_size));
-               NDR_PULL_ALLOC_N(ndr, r->out.key_buffer, r->in.key_buffer_size / 2);
-               memset(r->out.key_buffer, 0, (r->in.key_buffer_size / 2) * sizeof(*r->out.key_buffer));
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.offered));
+               NDR_PULL_ALLOC(ndr, r->out.key_buffer);
+               ZERO_STRUCTP(r->out.key_buffer);
                NDR_PULL_ALLOC(ndr, r->out.needed);
                ZERO_STRUCTP(r->out.needed);
        }
        if (flags & NDR_OUT) {
-               NDR_CHECK(ndr_pull_array_size(ndr, &r->out.key_buffer));
-               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
-                       NDR_PULL_ALLOC_N(ndr, r->out.key_buffer, ndr_get_array_size(ndr, &r->out.key_buffer));
-               }
-               _mem_save_key_buffer_1 = NDR_PULL_GET_MEM_CTX(ndr);
-               NDR_PULL_SET_MEM_CTX(ndr, r->out.key_buffer, 0);
-               for (cntr_key_buffer_1 = 0; cntr_key_buffer_1 < r->in.key_buffer_size / 2; cntr_key_buffer_1++) {
-                       NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->out.key_buffer[cntr_key_buffer_1]));
+               {
+                       uint32_t _flags_save_string_array = ndr->flags;
+                       ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+                       if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                               NDR_PULL_ALLOC(ndr, r->out.key_buffer);
+                       }
+                       _mem_save_key_buffer_0 = NDR_PULL_GET_MEM_CTX(ndr);
+                       NDR_PULL_SET_MEM_CTX(ndr, r->out.key_buffer, LIBNDR_FLAG_REF_ALLOC);
+                       NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_key_buffer));
+                       if (_ptr_key_buffer) {
+                               NDR_PULL_ALLOC(ndr, *r->out.key_buffer);
+                       } else {
+                               *r->out.key_buffer = NULL;
+                       }
+                       if (*r->out.key_buffer) {
+                               _mem_save_key_buffer_1 = NDR_PULL_GET_MEM_CTX(ndr);
+                               NDR_PULL_SET_MEM_CTX(ndr, *r->out.key_buffer, 0);
+                               {
+                                       struct ndr_pull *_ndr_key_buffer;
+                                       NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_key_buffer, 0, r->in.offered));
+                                       NDR_CHECK(ndr_pull_string_array(_ndr_key_buffer, NDR_SCALARS, r->out.key_buffer));
+                                       NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_key_buffer, 0, r->in.offered));
+                               }
+                               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_key_buffer_1, 0);
+                       }
+                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_key_buffer_0, LIBNDR_FLAG_REF_ALLOC);
+                       ndr->flags = _flags_save_string_array;
                }
-               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_key_buffer_1, 0);
                if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
                        NDR_PULL_ALLOC(ndr, r->out.needed);
                }
@@ -25885,16 +26702,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterKey(struct ndr_pull *ndr,
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.needed));
                NDR_PULL_SET_MEM_CTX(ndr, _mem_save_needed_0, LIBNDR_FLAG_REF_ALLOC);
                NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
-               if (r->out.key_buffer) {
-                       NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.key_buffer, r->in.key_buffer_size / 2));
-               }
        }
        return NDR_ERR_SUCCESS;
 }
 
 _PUBLIC_ void ndr_print_spoolss_EnumPrinterKey(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumPrinterKey *r)
 {
-       uint32_t cntr_key_buffer_1;
        ndr_print_struct(ndr, name, "spoolss_EnumPrinterKey");
        ndr->depth++;
        if (flags & NDR_SET_VALUES) {
@@ -25908,7 +26721,7 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterKey(struct ndr_print *ndr, const char
                ndr_print_policy_handle(ndr, "handle", r->in.handle);
                ndr->depth--;
                ndr_print_string(ndr, "key_name", r->in.key_name);
-               ndr_print_uint32(ndr, "key_buffer_size", r->in.key_buffer_size);
+               ndr_print_uint32(ndr, "offered", r->in.offered);
                ndr->depth--;
        }
        if (flags & NDR_OUT) {
@@ -25916,14 +26729,10 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterKey(struct ndr_print *ndr, const char
                ndr->depth++;
                ndr_print_ptr(ndr, "key_buffer", r->out.key_buffer);
                ndr->depth++;
-               ndr->print(ndr, "%s: ARRAY(%d)", "key_buffer", (int)r->in.key_buffer_size / 2);
+               ndr_print_ptr(ndr, "key_buffer", *r->out.key_buffer);
                ndr->depth++;
-               for (cntr_key_buffer_1=0;cntr_key_buffer_1<r->in.key_buffer_size / 2;cntr_key_buffer_1++) {
-                       char *idx_1=NULL;
-                       if (asprintf(&idx_1, "[%d]", cntr_key_buffer_1) != -1) {
-                               ndr_print_uint16(ndr, "key_buffer", r->out.key_buffer[cntr_key_buffer_1]);
-                               free(idx_1);
-                       }
+               if (*r->out.key_buffer) {
+                       ndr_print_string_array(ndr, "key_buffer", *r->out.key_buffer);
                }
                ndr->depth--;
                ndr->depth--;
index 84ab8b7d0566b954aeb3b48a61a6ab5d811cf7d7..0feb4a2c5e3420a796931346584bff9ac968be28 100644 (file)
@@ -211,7 +211,12 @@ void ndr_print_spoolss_ProcessorArchitecture(struct ndr_print *ndr, const char *
 void ndr_print_spoolss_ProcessorType(struct ndr_print *ndr, const char *name, enum spoolss_ProcessorType r);
 void ndr_print_spoolss_MajorVersion(struct ndr_print *ndr, const char *name, enum spoolss_MajorVersion r);
 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);
@@ -220,29 +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);
-void ndr_print_spoolss_PrinterStatus(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);
-void ndr_print_spoolss_JobStatus(struct ndr_print *ndr, const char *name, uint32_t 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);
@@ -323,7 +362,10 @@ enum ndr_err_code ndr_push_spoolss_DriverDirectoryInfo(struct ndr_push *ndr, int
 enum ndr_err_code ndr_pull_spoolss_DriverDirectoryInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_DriverDirectoryInfo *r);
 void ndr_print_spoolss_DriverDirectoryInfo(struct ndr_print *ndr, const char *name, const union spoolss_DriverDirectoryInfo *r);
 size_t ndr_size_spoolss_DriverDirectoryInfo(const union spoolss_DriverDirectoryInfo *r, uint32_t level, struct smb_iconv_convenience *ic, int flags);
+enum ndr_err_code ndr_push_spoolss_PrintProcessorInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrintProcessorInfo1 *r);
+enum ndr_err_code ndr_pull_spoolss_PrintProcessorInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrintProcessorInfo1 *r);
 void ndr_print_spoolss_PrintProcessorInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_PrintProcessorInfo1 *r);
+size_t ndr_size_spoolss_PrintProcessorInfo1(const struct spoolss_PrintProcessorInfo1 *r, struct smb_iconv_convenience *ic, int flags);
 enum ndr_err_code ndr_push_spoolss_PrintProcessorInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_PrintProcessorInfo *r);
 enum ndr_err_code ndr_pull_spoolss_PrintProcessorInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_PrintProcessorInfo *r);
 void ndr_print_spoolss_PrintProcessorInfo(struct ndr_print *ndr, const char *name, const union spoolss_PrintProcessorInfo *r);
@@ -345,7 +387,6 @@ enum ndr_err_code ndr_push_spoolss_OSVersionEx(struct ndr_push *ndr, int ndr_fla
 enum ndr_err_code ndr_pull_spoolss_OSVersionEx(struct ndr_pull *ndr, int ndr_flags, struct spoolss_OSVersionEx *r);
 void ndr_print_spoolss_OSVersionEx(struct ndr_print *ndr, const char *name, const struct spoolss_OSVersionEx *r);
 size_t ndr_size_spoolss_OSVersionEx(const struct spoolss_OSVersionEx *r, struct smb_iconv_convenience *ic, int flags);
-void ndr_print_spoolss_PrinterDataType(struct ndr_print *ndr, const char *name, enum spoolss_PrinterDataType r);
 enum ndr_err_code ndr_push_spoolss_PrinterData(struct ndr_push *ndr, int ndr_flags, const union spoolss_PrinterData *r);
 enum ndr_err_code ndr_pull_spoolss_PrinterData(struct ndr_pull *ndr, int ndr_flags, union spoolss_PrinterData *r);
 void ndr_print_spoolss_PrinterData(struct ndr_print *ndr, const char *name, const union spoolss_PrinterData *r);
@@ -353,9 +394,15 @@ size_t ndr_size_spoolss_PrinterData(const union spoolss_PrinterData *r, uint32_t
 void ndr_print_spoolss_FormFlags(struct ndr_print *ndr, const char *name, enum spoolss_FormFlags r);
 void ndr_print_spoolss_FormSize(struct ndr_print *ndr, const char *name, const struct spoolss_FormSize *r);
 void ndr_print_spoolss_FormArea(struct ndr_print *ndr, const char *name, const struct spoolss_FormArea *r);
+enum ndr_err_code ndr_push_spoolss_FormInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_FormInfo1 *r);
+enum ndr_err_code ndr_pull_spoolss_FormInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_FormInfo1 *r);
 void ndr_print_spoolss_FormInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_FormInfo1 *r);
+size_t ndr_size_spoolss_FormInfo1(const struct spoolss_FormInfo1 *r, struct smb_iconv_convenience *ic, int flags);
 void ndr_print_spoolss_FormStringType(struct ndr_print *ndr, const char *name, uint32_t r);
+enum ndr_err_code ndr_push_spoolss_FormInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_FormInfo2 *r);
+enum ndr_err_code ndr_pull_spoolss_FormInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_FormInfo2 *r);
 void ndr_print_spoolss_FormInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_FormInfo2 *r);
+size_t ndr_size_spoolss_FormInfo2(const struct spoolss_FormInfo2 *r, struct smb_iconv_convenience *ic, int flags);
 enum ndr_err_code ndr_push_spoolss_FormInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_FormInfo *r);
 enum ndr_err_code ndr_pull_spoolss_FormInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_FormInfo *r);
 void ndr_print_spoolss_FormInfo(struct ndr_print *ndr, const char *name, const union spoolss_FormInfo *r);
@@ -363,24 +410,55 @@ size_t ndr_size_spoolss_FormInfo(const union spoolss_FormInfo *r, uint32_t level
 void ndr_print_spoolss_AddFormInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_AddFormInfo1 *r);
 void ndr_print_spoolss_AddFormInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_AddFormInfo2 *r);
 void ndr_print_spoolss_AddFormInfo(struct ndr_print *ndr, const char *name, const union spoolss_AddFormInfo *r);
+enum ndr_err_code ndr_push_spoolss_PortInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfo1 *r);
+enum ndr_err_code ndr_pull_spoolss_PortInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfo1 *r);
 void ndr_print_spoolss_PortInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_PortInfo1 *r);
+size_t ndr_size_spoolss_PortInfo1(const struct spoolss_PortInfo1 *r, struct smb_iconv_convenience *ic, int flags);
 void ndr_print_spoolss_PortType(struct ndr_print *ndr, const char *name, uint32_t r);
+enum ndr_err_code ndr_push_spoolss_PortInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfo2 *r);
+enum ndr_err_code ndr_pull_spoolss_PortInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfo2 *r);
 void ndr_print_spoolss_PortInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_PortInfo2 *r);
+size_t ndr_size_spoolss_PortInfo2(const struct spoolss_PortInfo2 *r, struct smb_iconv_convenience *ic, int flags);
 void ndr_print_spoolss_PortStatus(struct ndr_print *ndr, const char *name, enum spoolss_PortStatus r);
 void ndr_print_spoolss_PortSeverity(struct ndr_print *ndr, const char *name, enum spoolss_PortSeverity r);
+enum ndr_err_code ndr_push_spoolss_PortInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfo3 *r);
+enum ndr_err_code ndr_pull_spoolss_PortInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfo3 *r);
 void ndr_print_spoolss_PortInfo3(struct ndr_print *ndr, const char *name, const struct spoolss_PortInfo3 *r);
+size_t ndr_size_spoolss_PortInfo3(const struct spoolss_PortInfo3 *r, struct smb_iconv_convenience *ic, int flags);
+enum ndr_err_code ndr_push_spoolss_PortInfoFF(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfoFF *r);
+enum ndr_err_code ndr_pull_spoolss_PortInfoFF(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfoFF *r);
 void ndr_print_spoolss_PortInfoFF(struct ndr_print *ndr, const char *name, const struct spoolss_PortInfoFF *r);
+size_t ndr_size_spoolss_PortInfoFF(const struct spoolss_PortInfoFF *r, struct smb_iconv_convenience *ic, int flags);
 enum ndr_err_code ndr_push_spoolss_PortInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_PortInfo *r);
 enum ndr_err_code ndr_pull_spoolss_PortInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_PortInfo *r);
 void ndr_print_spoolss_PortInfo(struct ndr_print *ndr, const char *name, const union spoolss_PortInfo *r);
+enum ndr_err_code ndr_push_spoolss_MonitorInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_MonitorInfo1 *r);
+enum ndr_err_code ndr_pull_spoolss_MonitorInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_MonitorInfo1 *r);
 void ndr_print_spoolss_MonitorInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_MonitorInfo1 *r);
+size_t ndr_size_spoolss_MonitorInfo1(const struct spoolss_MonitorInfo1 *r, struct smb_iconv_convenience *ic, int flags);
+enum ndr_err_code ndr_push_spoolss_MonitorInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_MonitorInfo2 *r);
+enum ndr_err_code ndr_pull_spoolss_MonitorInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_MonitorInfo2 *r);
 void ndr_print_spoolss_MonitorInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_MonitorInfo2 *r);
+size_t ndr_size_spoolss_MonitorInfo2(const struct spoolss_MonitorInfo2 *r, struct smb_iconv_convenience *ic, int flags);
 enum ndr_err_code ndr_push_spoolss_MonitorInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_MonitorInfo *r);
 enum ndr_err_code ndr_pull_spoolss_MonitorInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_MonitorInfo *r);
 void ndr_print_spoolss_MonitorInfo(struct ndr_print *ndr, const char *name, const union spoolss_MonitorInfo *r);
+enum ndr_err_code ndr_push_spoolss_PrintProcDataTypesInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrintProcDataTypesInfo1 *r);
+enum ndr_err_code ndr_pull_spoolss_PrintProcDataTypesInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrintProcDataTypesInfo1 *r);
+void ndr_print_spoolss_PrintProcDataTypesInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_PrintProcDataTypesInfo1 *r);
+size_t ndr_size_spoolss_PrintProcDataTypesInfo1(const struct spoolss_PrintProcDataTypesInfo1 *r, struct smb_iconv_convenience *ic, int flags);
+enum ndr_err_code ndr_push_spoolss_PrintProcDataTypesInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_PrintProcDataTypesInfo *r);
+enum ndr_err_code ndr_pull_spoolss_PrintProcDataTypesInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_PrintProcDataTypesInfo *r);
+void ndr_print_spoolss_PrintProcDataTypesInfo(struct ndr_print *ndr, const char *name, const union spoolss_PrintProcDataTypesInfo *r);
 void ndr_print_spoolss_PrinterChangeFlags(struct ndr_print *ndr, const char *name, uint32_t r);
-void ndr_print_spoolss_Field(struct ndr_print *ndr, const char *name, enum spoolss_Field r);
+enum ndr_err_code ndr_push_spoolss_JobNotifyField(struct ndr_push *ndr, int ndr_flags, enum spoolss_JobNotifyField r);
+enum ndr_err_code ndr_pull_spoolss_JobNotifyField(struct ndr_pull *ndr, int ndr_flags, enum spoolss_JobNotifyField *r);
+void ndr_print_spoolss_JobNotifyField(struct ndr_print *ndr, const char *name, enum spoolss_JobNotifyField r);
+enum ndr_err_code ndr_push_spoolss_PrintNotifyField(struct ndr_push *ndr, int ndr_flags, enum spoolss_PrintNotifyField r);
+enum ndr_err_code ndr_pull_spoolss_PrintNotifyField(struct ndr_pull *ndr, int ndr_flags, enum spoolss_PrintNotifyField *r);
+void ndr_print_spoolss_PrintNotifyField(struct ndr_print *ndr, const char *name, enum spoolss_PrintNotifyField r);
 void ndr_print_spoolss_NotifyType(struct ndr_print *ndr, const char *name, enum spoolss_NotifyType r);
+void ndr_print_spoolss_Field(struct ndr_print *ndr, const char *name, const union spoolss_Field *r);
 void ndr_print_spoolss_NotifyOptionType(struct ndr_print *ndr, const char *name, const struct spoolss_NotifyOptionType *r);
 void ndr_print_spoolssNotifyOptionFlags(struct ndr_print *ndr, const char *name, uint32_t r);
 void ndr_print_spoolss_NotifyOption(struct ndr_print *ndr, const char *name, const struct spoolss_NotifyOption *r);
@@ -397,6 +475,10 @@ void ndr_print_spoolss_UserLevel3(struct ndr_print *ndr, const char *name, const
 void ndr_print_spoolss_UserLevel(struct ndr_print *ndr, const char *name, const union spoolss_UserLevel *r);
 void ndr_print_spoolss_UserLevelCtr(struct ndr_print *ndr, const char *name, const struct spoolss_UserLevelCtr *r);
 void ndr_print_spoolss_AccessRights(struct ndr_print *ndr, const char *name, uint32_t r);
+enum ndr_err_code ndr_push_spoolss_PrinterEnumValues(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PrinterEnumValues *r);
+enum ndr_err_code ndr_pull_spoolss_PrinterEnumValues(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PrinterEnumValues *r);
+void ndr_print_spoolss_PrinterEnumValues(struct ndr_print *ndr, const char *name, const struct spoolss_PrinterEnumValues *r);
+size_t ndr_size_spoolss_PrinterEnumValues(const struct spoolss_PrinterEnumValues *r, struct smb_iconv_convenience *ic, int flags);
 enum ndr_err_code ndr_push_spoolss_DeleteDriverFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r);
 enum ndr_err_code ndr_pull_spoolss_DeleteDriverFlags(struct ndr_pull *ndr, int ndr_flags, uint32_t *r);
 void ndr_print_spoolss_DeleteDriverFlags(struct ndr_print *ndr, const char *name, uint32_t r);
@@ -541,6 +623,14 @@ void ndr_print_spoolss_DeleteMonitor(struct ndr_print *ndr, const char *name, in
 void ndr_print_spoolss_DeletePrintProcessor(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_DeletePrintProcessor *r);
 void ndr_print_spoolss_AddPrintProvidor(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_AddPrintProvidor *r);
 void ndr_print_spoolss_DeletePrintProvidor(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_DeletePrintProvidor *r);
+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);
+void ndr_print__spoolss_EnumPrintProcDataTypes(struct ndr_print *ndr, const char *name, int flags, const struct _spoolss_EnumPrintProcDataTypes *r);
+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);
+void ndr_print___spoolss_EnumPrintProcDataTypes(struct ndr_print *ndr, const char *name, int flags, const struct __spoolss_EnumPrintProcDataTypes *r);
+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);
 void ndr_print_spoolss_EnumPrintProcDataTypes(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumPrintProcDataTypes *r);
 void ndr_print_spoolss_ResetPrinter(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_ResetPrinter *r);
 void ndr_print_spoolss_GetPrinterDriver2(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_GetPrinterDriver2 *r);
@@ -581,6 +671,12 @@ void ndr_print_spoolss_4b(struct ndr_print *ndr, const char *name, int flags, co
 void ndr_print_spoolss_4c(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_4c *r);
 void ndr_print_spoolss_SetPrinterDataEx(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_SetPrinterDataEx *r);
 void ndr_print_spoolss_GetPrinterDataEx(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_GetPrinterDataEx *r);
+enum ndr_err_code ndr_push__spoolss_EnumPrinterDataEx(struct ndr_push *ndr, int flags, const struct _spoolss_EnumPrinterDataEx *r);
+enum ndr_err_code ndr_pull__spoolss_EnumPrinterDataEx(struct ndr_pull *ndr, int flags, struct _spoolss_EnumPrinterDataEx *r);
+void ndr_print__spoolss_EnumPrinterDataEx(struct ndr_print *ndr, const char *name, int flags, const struct _spoolss_EnumPrinterDataEx *r);
+enum ndr_err_code ndr_push___spoolss_EnumPrinterDataEx(struct ndr_push *ndr, int flags, const struct __spoolss_EnumPrinterDataEx *r);
+enum ndr_err_code ndr_pull___spoolss_EnumPrinterDataEx(struct ndr_pull *ndr, int flags, struct __spoolss_EnumPrinterDataEx *r);
+void ndr_print___spoolss_EnumPrinterDataEx(struct ndr_print *ndr, const char *name, int flags, const struct __spoolss_EnumPrinterDataEx *r);
 enum ndr_err_code ndr_push_spoolss_EnumPrinterDataEx(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrinterDataEx *r);
 enum ndr_err_code ndr_pull_spoolss_EnumPrinterDataEx(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinterDataEx *r);
 void ndr_print_spoolss_EnumPrinterDataEx(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumPrinterDataEx *r);
index b66e4ab2a85e4c8abc33f2507b793d44aa67778b..8340b34e454240ee554655f1e391670a7fdc2eec 100644 (file)
 #ifndef _HEADER_spoolss
 #define _HEADER_spoolss
 
-#define PRINTER_ENUM_ICONMASK  ( (PRINTER_ENUM_ICON1|PRINTER_ENUM_ICON2|PRINTER_ENUM_ICON3|PRINTER_ENUM_ICON4|PRINTER_ENUM_ICON5|PRINTER_ENUM_ICON6|PRINTER_ENUM_ICON7|PRINTER_ENUM_ICON8) )
+#define PRINTER_STATUS_OK      ( 0x00000000 )
 #define JOB_STATUS_QUEUED      ( 0x0000 )
+#define PRINTER_ENUM_ICONMASK  ( (PRINTER_ENUM_ICON1|PRINTER_ENUM_ICON2|PRINTER_ENUM_ICON3|PRINTER_ENUM_ICON4|PRINTER_ENUM_ICON5|PRINTER_ENUM_ICON6|PRINTER_ENUM_ICON7|PRINTER_ENUM_ICON8) )
 #define SPOOLSS_ARCHITECTURE_NT_X86    ( "Windows NT x86" )
 #define SPOOLSS_DEFAULT_SERVER_PATH    ( "C:\\WINDOWS\\system32\\spool" )
+#define SPL_LOCAL_PORT ( "Local Port" )
+#define SPL_TCPIP_PORT ( "Standard TCP/IP Port" )
+#define SPL_XCV_MONITOR_LOCALMON       ( ",XcvMonitor Local Port" )
+#define SPL_XCV_MONITOR_TCPMON ( ",XcvMonitor Standard TCP/IP Port" )
 #define PRINTER_CHANGE_PRINTER ( 0x000000FF )
 #define PRINTER_CHANGE_JOB     ( 0x0000FF00 )
 #define PRINTER_CHANGE_FORM    ( (PRINTER_CHANGE_ADD_FORM|PRINTER_CHANGE_SET_FORM|PRINTER_CHANGE_DELETE_FORM) )
@@ -120,6 +125,48 @@ enum spoolss_MinorVersion
 #endif
 ;
 
+/* bitmap spoolss_PrinterStatus */
+#define PRINTER_STATUS_PAUSED ( 0x00000001 )
+#define PRINTER_STATUS_ERROR ( 0x00000002 )
+#define PRINTER_STATUS_PENDING_DELETION ( 0x00000004 )
+#define PRINTER_STATUS_PAPER_JAM ( 0x00000008 )
+#define PRINTER_STATUS_PAPER_OUT ( 0x00000010 )
+#define PRINTER_STATUS_MANUAL_FEED ( 0x00000020 )
+#define PRINTER_STATUS_PAPER_PROBLEM ( 0x00000040 )
+#define PRINTER_STATUS_OFFLINE ( 0x00000080 )
+#define PRINTER_STATUS_IO_ACTIVE ( 0x00000100 )
+#define PRINTER_STATUS_BUSY ( 0x00000200 )
+#define PRINTER_STATUS_PRINTING ( 0x00000400 )
+#define PRINTER_STATUS_OUTPUT_BIN_FULL ( 0x00000800 )
+#define PRINTER_STATUS_NOT_AVAILABLE ( 0x00001000 )
+#define PRINTER_STATUS_WAITING ( 0x00002000 )
+#define PRINTER_STATUS_PROCESSING ( 0x00004000 )
+#define PRINTER_STATUS_INITIALIZING ( 0x00008000 )
+#define PRINTER_STATUS_WARMING_UP ( 0x00010000 )
+#define PRINTER_STATUS_TONER_LOW ( 0x00020000 )
+#define PRINTER_STATUS_NO_TONER ( 0x00040000 )
+#define PRINTER_STATUS_PAGE_PUNT ( 0x00080000 )
+#define PRINTER_STATUS_USER_INTERVENTION ( 0x00100000 )
+#define PRINTER_STATUS_OUT_OF_MEMORY ( 0x00200000 )
+#define PRINTER_STATUS_DOOR_OPEN ( 0x00400000 )
+#define PRINTER_STATUS_SERVER_UNKNOWN ( 0x00800000 )
+#define PRINTER_STATUS_POWER_SAVE ( 0x01000000 )
+
+/* bitmap spoolss_JobStatus */
+#define JOB_STATUS_PAUSED ( 0x00000001 )
+#define JOB_STATUS_ERROR ( 0x00000002 )
+#define JOB_STATUS_DELETING ( 0x00000004 )
+#define JOB_STATUS_SPOOLING ( 0x00000008 )
+#define JOB_STATUS_PRINTING ( 0x00000010 )
+#define JOB_STATUS_OFFLINE ( 0x00000020 )
+#define JOB_STATUS_PAPEROUT ( 0x00000040 )
+#define JOB_STATUS_PRINTED ( 0x00000080 )
+#define JOB_STATUS_DELETED ( 0x00000100 )
+#define JOB_STATUS_BLOCKED_DEVQ ( 0x00000200 )
+#define JOB_STATUS_USER_INTERVENTION ( 0x00000400 )
+#define JOB_STATUS_RESTART ( 0x00000800 )
+#define JOB_STATUS_COMPLETE ( 0x00001000 )
+
 struct spoolss_PrinterInfo0 {
        const char * printername;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        const char * servername;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
@@ -150,7 +197,7 @@ struct spoolss_PrinterInfo0 {
        uint32_t ref_ic;
        uint32_t reserved2;
        uint32_t reserved3;
-};
+}/* [gensize,public] */;
 
 /* bitmap spoolss_DeviceModeFields */
 #define DEVMODE_ORIENTATION ( 0x00000001 )
@@ -246,7 +293,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 )
@@ -266,33 +313,6 @@ struct spoolss_PrinterInfo1 {
 #define PRINTER_ATTRIBUTE_FAX ( 0x00004000 )
 #define PRINTER_ATTRIBUTE_TS ( 0x00008000 )
 
-/* bitmap spoolss_PrinterStatus */
-#define PRINTER_STATUS_PAUSED ( 0x00000001 )
-#define PRINTER_STATUS_ERROR ( 0x00000002 )
-#define PRINTER_STATUS_PENDING_DELETION ( 0x00000004 )
-#define PRINTER_STATUS_PAPER_JAM ( 0x00000008 )
-#define PRINTER_STATUS_PAPER_OUT ( 0x00000010 )
-#define PRINTER_STATUS_MANUAL_FEED ( 0x00000020 )
-#define PRINTER_STATUS_PAPER_PROBLEM ( 0x00000040 )
-#define PRINTER_STATUS_OFFLINE ( 0x00000080 )
-#define PRINTER_STATUS_IO_ACTIVE ( 0x00000100 )
-#define PRINTER_STATUS_BUSY ( 0x00000200 )
-#define PRINTER_STATUS_PRINTING ( 0x00000400 )
-#define PRINTER_STATUS_OUTPUT_BIN_FULL ( 0x00000800 )
-#define PRINTER_STATUS_NOT_AVAILABLE ( 0x00001000 )
-#define PRINTER_STATUS_WAITING ( 0x00002000 )
-#define PRINTER_STATUS_PROCESSING ( 0x00004000 )
-#define PRINTER_STATUS_INITIALIZING ( 0x00008000 )
-#define PRINTER_STATUS_WARMING_UP ( 0x00010000 )
-#define PRINTER_STATUS_TONER_LOW ( 0x00020000 )
-#define PRINTER_STATUS_NO_TONER ( 0x00040000 )
-#define PRINTER_STATUS_PAGE_PUNT ( 0x00080000 )
-#define PRINTER_STATUS_USER_INTERVENTION ( 0x00100000 )
-#define PRINTER_STATUS_OUT_OF_MEMORY ( 0x00200000 )
-#define PRINTER_STATUS_DOOR_OPEN ( 0x00400000 )
-#define PRINTER_STATUS_SERVER_UNKNOWN ( 0x00800000 )
-#define PRINTER_STATUS_POWER_SAVE ( 0x01000000 )
-
 struct spoolss_PrinterInfo2 {
        const char * servername;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        const char * printername;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
@@ -308,24 +328,24 @@ struct spoolss_PrinterInfo2 {
        const char * parameters;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        struct security_descriptor *secdesc;/* [relative,subcontext(0)] */
        uint32_t attributes;
-       uint32_t priority;
+       uint32_t priority;/* [range(0,99)] */
        uint32_t defaultpriority;
        uint32_t starttime;
        uint32_t untiltime;
        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)] */
@@ -333,11 +353,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 )
@@ -349,7 +369,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)] */
@@ -366,28 +386,13 @@ 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))] */
        struct spoolss_DeviceMode *devmode;/* [unique,subcontext_size(_ndr_size),subcontext(4)] */
 };
 
-/* bitmap spoolss_JobStatus */
-#define JOB_STATUS_PAUSED ( 0x00000001 )
-#define JOB_STATUS_ERROR ( 0x00000002 )
-#define JOB_STATUS_DELETING ( 0x00000004 )
-#define JOB_STATUS_SPOOLING ( 0x00000008 )
-#define JOB_STATUS_PRINTING ( 0x00000010 )
-#define JOB_STATUS_OFFLINE ( 0x00000020 )
-#define JOB_STATUS_PAPEROUT ( 0x00000040 )
-#define JOB_STATUS_PRINTED ( 0x00000080 )
-#define JOB_STATUS_DELETED ( 0x00000100 )
-#define JOB_STATUS_BLOCKED_DEVQ ( 0x00000200 )
-#define JOB_STATUS_USER_INTERVENTION ( 0x00000400 )
-#define JOB_STATUS_RESTART ( 0x00000800 )
-#define JOB_STATUS_COMPLETE ( 0x00001000 )
-
 struct spoolss_JobInfo1 {
        uint32_t job_id;
        const char * printer_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
@@ -397,12 +402,12 @@ struct spoolss_JobInfo1 {
        const char * data_type;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        const char * text_status;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        uint32_t status;
-       uint32_t priority;
+       uint32_t priority;/* [range(0,99)] */
        uint32_t position;
        uint32_t total_pages;
        uint32_t pages_printed;
        struct spoolss_Time submitted;
-};
+}/* [gensize,public] */;
 
 struct spoolss_JobInfo2 {
        uint32_t job_id;
@@ -419,7 +424,7 @@ struct spoolss_JobInfo2 {
        const char * text_status;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        struct security_descriptor *secdesc;/* [relative] */
        uint32_t status;
-       uint32_t priority;
+       uint32_t priority;/* [range(0,99)] */
        uint32_t position;
        uint32_t start_time;
        uint32_t until_time;
@@ -428,13 +433,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;
@@ -451,7 +456,7 @@ struct spoolss_JobInfo4 {
        const char * text_status;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        struct security_descriptor *secdesc;/* [relative] */
        uint32_t status;
-       uint32_t priority;
+       uint32_t priority;/* [range(0,99)] */
        uint32_t position;
        uint32_t start_time;
        uint32_t until_time;
@@ -461,14 +466,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;
@@ -479,7 +484,7 @@ struct spoolss_SetJobInfo1 {
        const char *data_type;/* [unique,charset(UTF16)] */
        const char *text_status;/* [unique,charset(UTF16)] */
        uint32_t status;
-       uint32_t priority;
+       uint32_t priority;/* [range(0,99)] */
        uint32_t position;
        uint32_t total_pages;
        uint32_t pages_printed;
@@ -497,11 +502,11 @@ struct spoolss_SetJobInfo2 {
        const char *print_processor;/* [unique,charset(UTF16)] */
        const char *parameters;/* [unique,charset(UTF16)] */
        const char *driver_name;/* [unique,charset(UTF16)] */
-       struct spoolss_DeviceMode *devmode;/* [unique] */
+       uint32_t _devmode_ptr;
        const char *text_status;/* [unique,charset(UTF16)] */
-       struct security_descriptor *secdesc;/* [unique] */
+       uint32_t _secdesc_ptr;
        uint32_t status;
-       uint32_t priority;
+       uint32_t priority;/* [range(0,99)] */
        uint32_t position;
        uint32_t start_time;
        uint32_t until_time;
@@ -523,11 +528,11 @@ struct spoolss_SetJobInfo4 {
        const char *print_processor;/* [unique,charset(UTF16)] */
        const char *parameters;/* [unique,charset(UTF16)] */
        const char *driver_name;/* [unique,charset(UTF16)] */
-       struct spoolss_DeviceMode *devmode;/* [unique] */
+       uint32_t _devmode_ptr;
        const char *text_status;/* [unique,charset(UTF16)] */
-       struct security_descriptor *secdesc;/* [unique] */
+       uint32_t _secdesc_ptr;
        uint32_t status;
-       uint32_t priority;
+       uint32_t priority;/* [range(0,99)] */
        uint32_t position;
        uint32_t start_time;
        uint32_t until_time;
@@ -651,7 +656,7 @@ struct spoolss_SetPrinterInfo2 {
        const char *parameters;/* [unique,charset(UTF16)] */
        struct security_descriptor *secdesc;/* [unique,subcontext(0)] */
        uint32_t attributes;
-       uint32_t priority;
+       uint32_t priority;/* [range(0,99)] */
        uint32_t defaultpriority;
        uint32_t starttime;
        uint32_t untiltime;
@@ -1001,7 +1006,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)] */
@@ -1013,7 +1018,7 @@ union spoolss_DriverDirectoryInfo {
 
 struct spoolss_PrintProcessorInfo1 {
        const char * print_processor_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
-};
+}/* [gensize,public] */;
 
 union spoolss_PrintProcessorInfo {
        struct spoolss_PrintProcessorInfo1 info1;/* [case] */
@@ -1057,30 +1062,11 @@ struct spoolss_OSVersionEx {
        uint32_t unknown3;
 }/* [gensize,public] */;
 
-enum spoolss_PrinterDataType
-#ifndef USE_UINT_ENUMS
- {
-       SPOOLSS_PRINTER_DATA_TYPE_NULL=0,
-       SPOOLSS_PRINTER_DATA_TYPE_STRING=1,
-       SPOOLSS_PRINTER_DATA_TYPE_BINARY=3,
-       SPOOLSS_PRINTER_DATA_TYPE_UINT32=4,
-       SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY=7
-}
-#else
- { __donnot_use_enum_spoolss_PrinterDataType=0x7FFFFFFF}
-#define SPOOLSS_PRINTER_DATA_TYPE_NULL ( 0 )
-#define SPOOLSS_PRINTER_DATA_TYPE_STRING ( 1 )
-#define SPOOLSS_PRINTER_DATA_TYPE_BINARY ( 3 )
-#define SPOOLSS_PRINTER_DATA_TYPE_UINT32 ( 4 )
-#define SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY ( 7 )
-#endif
-;
-
 union spoolss_PrinterData {
-       const char * string;/* [flag(LIBNDR_FLAG_STR_NULLTERM),case(SPOOLSS_PRINTER_DATA_TYPE_STRING)] */
-       DATA_BLOB binary;/* [flag(LIBNDR_FLAG_REMAINING),case(SPOOLSS_PRINTER_DATA_TYPE_BINARY)] */
-       uint32_t value;/* [case(SPOOLSS_PRINTER_DATA_TYPE_UINT32)] */
-       const char ** string_array;/* [flag(LIBNDR_FLAG_STR_NULLTERM),case(SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY)] */
+       const char * string;/* [flag(LIBNDR_FLAG_STR_NULLTERM),case(REG_SZ)] */
+       DATA_BLOB binary;/* [flag(LIBNDR_FLAG_REMAINING),case(REG_BINARY)] */
+       uint32_t value;/* [case(REG_DWORD)] */
+       const char ** string_array;/* [flag(LIBNDR_FLAG_STR_NULLTERM),case(REG_MULTI_SZ)] */
        DATA_BLOB data;/* [flag(LIBNDR_FLAG_REMAINING),default] */
 }/* [gensize,public,nodiscriminant] */;
 
@@ -1116,7 +1102,7 @@ struct spoolss_FormInfo1 {
        const char * form_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        struct spoolss_FormSize size;
        struct spoolss_FormArea area;
-};
+}/* [gensize,public] */;
 
 /* bitmap spoolss_FormStringType */
 #define SPOOLSS_FORM_STRING_TYPE_NONE ( 0x00000001 )
@@ -1134,7 +1120,7 @@ struct spoolss_FormInfo2 {
        uint32_t ressource_id;
        const char * display_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        uint32_t lang_id;
-};
+}/* [gensize,public] */;
 
 union spoolss_FormInfo {
        struct spoolss_FormInfo1 info1;/* [case] */
@@ -1168,7 +1154,7 @@ union spoolss_AddFormInfo {
 
 struct spoolss_PortInfo1 {
        const char * port_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
-};
+}/* [gensize,public] */;
 
 /* bitmap spoolss_PortType */
 #define SPOOLSS_PORT_TYPE_WRITE ( 0x00000001 )
@@ -1182,7 +1168,7 @@ struct spoolss_PortInfo2 {
        const char * description;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        uint32_t port_type;
        uint32_t reserved;
-};
+}/* [gensize,public] */;
 
 enum spoolss_PortStatus
 #ifndef USE_UINT_ENUMS
@@ -1238,12 +1224,12 @@ struct spoolss_PortInfo3 {
        enum spoolss_PortStatus status;
        const char * status_string;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        enum spoolss_PortSeverity severity;
-};
+}/* [gensize,public] */;
 
 struct spoolss_PortInfoFF {
        const char * port_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        DATA_BLOB monitor_data;
-};
+}/* [gensize,public] */;
 
 union spoolss_PortInfo {
        struct spoolss_PortInfo1 info1;/* [case] */
@@ -1254,19 +1240,27 @@ union spoolss_PortInfo {
 
 struct spoolss_MonitorInfo1 {
        const char * monitor_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
-};
+}/* [gensize,public] */;
 
 struct spoolss_MonitorInfo2 {
        const char * monitor_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        const char * environment;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
        const char * dll_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
-};
+}/* [gensize,public] */;
 
 union spoolss_MonitorInfo {
        struct spoolss_MonitorInfo1 info1;/* [case] */
        struct spoolss_MonitorInfo2 info2;/* [case(2)] */
 }/* [relative_base,nodiscriminant,public] */;
 
+struct spoolss_PrintProcDataTypesInfo1 {
+       const char * name_array;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
+}/* [gensize,public] */;
+
+union spoolss_PrintProcDataTypesInfo {
+       struct spoolss_PrintProcDataTypesInfo1 info1;/* [case] */
+}/* [relative_base,nodiscriminant,public] */;
+
 /* bitmap spoolss_PrinterChangeFlags */
 #define PRINTER_CHANGE_ADD_PRINTER ( 0x00000001 )
 #define PRINTER_CHANGE_SET_PRINTER ( 0x00000002 )
@@ -1290,87 +1284,152 @@ union spoolss_MonitorInfo {
 #define PRINTER_CHANGE_DELETE_PRINTER_DRIVER ( 0x40000000 )
 #define PRINTER_CHANGE_TIMEOUT ( 0x80000000 )
 
-enum spoolss_Field
+enum spoolss_JobNotifyField
+#ifndef USE_UINT_ENUMS
+ {
+       JOB_NOTIFY_FIELD_PRINTER_NAME=0x00,
+       JOB_NOTIFY_FIELD_MACHINE_NAME=0x01,
+       JOB_NOTIFY_FIELD_PORT_NAME=0x02,
+       JOB_NOTIFY_FIELD_USER_NAME=0x03,
+       JOB_NOTIFY_FIELD_NOTIFY_NAME=0x04,
+       JOB_NOTIFY_FIELD_DATATYPE=0x05,
+       JOB_NOTIFY_FIELD_PRINT_PROCESSOR=0x06,
+       JOB_NOTIFY_FIELD_PARAMETERS=0x07,
+       JOB_NOTIFY_FIELD_DRIVER_NAME=0x08,
+       JOB_NOTIFY_FIELD_DEVMODE=0x09,
+       JOB_NOTIFY_FIELD_STATUS=0x0a,
+       JOB_NOTIFY_FIELD_STATUS_STRING=0x0b,
+       JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR=0x0c,
+       JOB_NOTIFY_FIELD_DOCUMENT=0x0d,
+       JOB_NOTIFY_FIELD_PRIORITY=0x0e,
+       JOB_NOTIFY_FIELD_POSITION=0x0f,
+       JOB_NOTIFY_FIELD_SUBMITTED=0x10,
+       JOB_NOTIFY_FIELD_START_TIME=0x11,
+       JOB_NOTIFY_FIELD_UNTIL_TIME=0x12,
+       JOB_NOTIFY_FIELD_TIME=0x13,
+       JOB_NOTIFY_FIELD_TOTAL_PAGES=0x14,
+       JOB_NOTIFY_FIELD_PAGES_PRINTED=0x15,
+       JOB_NOTIFY_FIELD_TOTAL_BYTES=0x16,
+       JOB_NOTIFY_FIELD_BYTES_PRINTED=0x17
+}
+#else
+ { __donnot_use_enum_spoolss_JobNotifyField=0x7FFFFFFF}
+#define JOB_NOTIFY_FIELD_PRINTER_NAME ( 0x00 )
+#define JOB_NOTIFY_FIELD_MACHINE_NAME ( 0x01 )
+#define JOB_NOTIFY_FIELD_PORT_NAME ( 0x02 )
+#define JOB_NOTIFY_FIELD_USER_NAME ( 0x03 )
+#define JOB_NOTIFY_FIELD_NOTIFY_NAME ( 0x04 )
+#define JOB_NOTIFY_FIELD_DATATYPE ( 0x05 )
+#define JOB_NOTIFY_FIELD_PRINT_PROCESSOR ( 0x06 )
+#define JOB_NOTIFY_FIELD_PARAMETERS ( 0x07 )
+#define JOB_NOTIFY_FIELD_DRIVER_NAME ( 0x08 )
+#define JOB_NOTIFY_FIELD_DEVMODE ( 0x09 )
+#define JOB_NOTIFY_FIELD_STATUS ( 0x0a )
+#define JOB_NOTIFY_FIELD_STATUS_STRING ( 0x0b )
+#define JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR ( 0x0c )
+#define JOB_NOTIFY_FIELD_DOCUMENT ( 0x0d )
+#define JOB_NOTIFY_FIELD_PRIORITY ( 0x0e )
+#define JOB_NOTIFY_FIELD_POSITION ( 0x0f )
+#define JOB_NOTIFY_FIELD_SUBMITTED ( 0x10 )
+#define JOB_NOTIFY_FIELD_START_TIME ( 0x11 )
+#define JOB_NOTIFY_FIELD_UNTIL_TIME ( 0x12 )
+#define JOB_NOTIFY_FIELD_TIME ( 0x13 )
+#define JOB_NOTIFY_FIELD_TOTAL_PAGES ( 0x14 )
+#define JOB_NOTIFY_FIELD_PAGES_PRINTED ( 0x15 )
+#define JOB_NOTIFY_FIELD_TOTAL_BYTES ( 0x16 )
+#define JOB_NOTIFY_FIELD_BYTES_PRINTED ( 0x17 )
+#endif
+;
+
+enum spoolss_PrintNotifyField
 #ifndef USE_UINT_ENUMS
  {
-       SPOOLSS_FIELD_SERVER_NAME=0,
-       SPOOLSS_FIELD_PRINTER_NAME=1,
-       SPOOLSS_FIELD_SHARE_NAME=2,
-       SPOOLSS_FIELD_PORT_NAME=3,
-       SPOOLSS_FIELD_DRIVER_NAME=4,
-       SPOOLSS_FIELD_COMMENT=5,
-       SPOOLSS_FIELD_LOCATION=6,
-       SPOOLSS_FIELD_DEVMODE=7,
-       SPOOLSS_FIELD_SEPFILE=8,
-       SPOOLSS_FIELD_PRINT_PROCESSOR=9,
-       SPOOLSS_FIELD_PARAMETERS=10,
-       SPOOLSS_FIELD_DATATYPE=11,
-       SPOOLSS_FIELD_SECURITY_DESCRIPTOR=12,
-       SPOOLSS_FIELD_ATTRIBUTES=13,
-       SPOOLSS_FIELD_PRIORITY=14,
-       SPOOLSS_FIELD_DEFAULT_PRIORITY=15,
-       SPOOLSS_FIELD_START_TIME=16,
-       SPOOLSS_FIELD_UNTIL_TIME=17,
-       SPOOLSS_FIELD_STATUS=18,
-       SPOOLSS_FIELD_STATUS_STRING=19,
-       SPOOLSS_FIELD_CJOBS=20,
-       SPOOLSS_FIELD_AVERAGE_PPM=21,
-       SPOOLSS_FIELD_TOTAL_PAGES=22,
-       SPOOLSS_FIELD_PAGES_PRINTED=23,
-       SPOOLSS_FIELD_TOTAL_BYTES=24,
-       SPOOLSS_FIELD_BYTES_PRINTED=25
+       PRINTER_NOTIFY_FIELD_SERVER_NAME=0x00,
+       PRINTER_NOTIFY_FIELD_PRINTER_NAME=0x01,
+       PRINTER_NOTIFY_FIELD_SHARE_NAME=0x02,
+       PRINTER_NOTIFY_FIELD_PORT_NAME=0x03,
+       PRINTER_NOTIFY_FIELD_DRIVER_NAME=0x04,
+       PRINTER_NOTIFY_FIELD_COMMENT=0x05,
+       PRINTER_NOTIFY_FIELD_LOCATION=0x06,
+       PRINTER_NOTIFY_FIELD_DEVMODE=0x07,
+       PRINTER_NOTIFY_FIELD_SEPFILE=0x08,
+       PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR=0x09,
+       PRINTER_NOTIFY_FIELD_PARAMETERS=0x0a,
+       PRINTER_NOTIFY_FIELD_DATATYPE=0x0b,
+       PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR=0x0c,
+       PRINTER_NOTIFY_FIELD_ATTRIBUTES=0x0d,
+       PRINTER_NOTIFY_FIELD_PRIORITY=0x0e,
+       PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY=0x0f,
+       PRINTER_NOTIFY_FIELD_START_TIME=0x10,
+       PRINTER_NOTIFY_FIELD_UNTIL_TIME=0x11,
+       PRINTER_NOTIFY_FIELD_STATUS=0x12,
+       PRINTER_NOTIFY_FIELD_STATUS_STRING=0x13,
+       PRINTER_NOTIFY_FIELD_CJOBS=0x14,
+       PRINTER_NOTIFY_FIELD_AVERAGE_PPM=0x15,
+       PRINTER_NOTIFY_FIELD_TOTAL_PAGES=0x16,
+       PRINTER_NOTIFY_FIELD_PAGES_PRINTED=0x17,
+       PRINTER_NOTIFY_FIELD_TOTAL_BYTES=0x18,
+       PRINTER_NOTIFY_FIELD_BYTES_PRINTED=0x19,
+       PRINTER_NOTIFY_FIELD_OBJECT_GUID=0x1a,
+       PRINTER_NOTIFY_FIELD_FRIENDLY_NAME=0x1b
 }
 #else
- { __donnot_use_enum_spoolss_Field=0x7FFFFFFF}
-#define SPOOLSS_FIELD_SERVER_NAME ( 0 )
-#define SPOOLSS_FIELD_PRINTER_NAME ( 1 )
-#define SPOOLSS_FIELD_SHARE_NAME ( 2 )
-#define SPOOLSS_FIELD_PORT_NAME ( 3 )
-#define SPOOLSS_FIELD_DRIVER_NAME ( 4 )
-#define SPOOLSS_FIELD_COMMENT ( 5 )
-#define SPOOLSS_FIELD_LOCATION ( 6 )
-#define SPOOLSS_FIELD_DEVMODE ( 7 )
-#define SPOOLSS_FIELD_SEPFILE ( 8 )
-#define SPOOLSS_FIELD_PRINT_PROCESSOR ( 9 )
-#define SPOOLSS_FIELD_PARAMETERS ( 10 )
-#define SPOOLSS_FIELD_DATATYPE ( 11 )
-#define SPOOLSS_FIELD_SECURITY_DESCRIPTOR ( 12 )
-#define SPOOLSS_FIELD_ATTRIBUTES ( 13 )
-#define SPOOLSS_FIELD_PRIORITY ( 14 )
-#define SPOOLSS_FIELD_DEFAULT_PRIORITY ( 15 )
-#define SPOOLSS_FIELD_START_TIME ( 16 )
-#define SPOOLSS_FIELD_UNTIL_TIME ( 17 )
-#define SPOOLSS_FIELD_STATUS ( 18 )
-#define SPOOLSS_FIELD_STATUS_STRING ( 19 )
-#define SPOOLSS_FIELD_CJOBS ( 20 )
-#define SPOOLSS_FIELD_AVERAGE_PPM ( 21 )
-#define SPOOLSS_FIELD_TOTAL_PAGES ( 22 )
-#define SPOOLSS_FIELD_PAGES_PRINTED ( 23 )
-#define SPOOLSS_FIELD_TOTAL_BYTES ( 24 )
-#define SPOOLSS_FIELD_BYTES_PRINTED ( 25 )
+ { __donnot_use_enum_spoolss_PrintNotifyField=0x7FFFFFFF}
+#define PRINTER_NOTIFY_FIELD_SERVER_NAME ( 0x00 )
+#define PRINTER_NOTIFY_FIELD_PRINTER_NAME ( 0x01 )
+#define PRINTER_NOTIFY_FIELD_SHARE_NAME ( 0x02 )
+#define PRINTER_NOTIFY_FIELD_PORT_NAME ( 0x03 )
+#define PRINTER_NOTIFY_FIELD_DRIVER_NAME ( 0x04 )
+#define PRINTER_NOTIFY_FIELD_COMMENT ( 0x05 )
+#define PRINTER_NOTIFY_FIELD_LOCATION ( 0x06 )
+#define PRINTER_NOTIFY_FIELD_DEVMODE ( 0x07 )
+#define PRINTER_NOTIFY_FIELD_SEPFILE ( 0x08 )
+#define PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR ( 0x09 )
+#define PRINTER_NOTIFY_FIELD_PARAMETERS ( 0x0a )
+#define PRINTER_NOTIFY_FIELD_DATATYPE ( 0x0b )
+#define PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR ( 0x0c )
+#define PRINTER_NOTIFY_FIELD_ATTRIBUTES ( 0x0d )
+#define PRINTER_NOTIFY_FIELD_PRIORITY ( 0x0e )
+#define PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY ( 0x0f )
+#define PRINTER_NOTIFY_FIELD_START_TIME ( 0x10 )
+#define PRINTER_NOTIFY_FIELD_UNTIL_TIME ( 0x11 )
+#define PRINTER_NOTIFY_FIELD_STATUS ( 0x12 )
+#define PRINTER_NOTIFY_FIELD_STATUS_STRING ( 0x13 )
+#define PRINTER_NOTIFY_FIELD_CJOBS ( 0x14 )
+#define PRINTER_NOTIFY_FIELD_AVERAGE_PPM ( 0x15 )
+#define PRINTER_NOTIFY_FIELD_TOTAL_PAGES ( 0x16 )
+#define PRINTER_NOTIFY_FIELD_PAGES_PRINTED ( 0x17 )
+#define PRINTER_NOTIFY_FIELD_TOTAL_BYTES ( 0x18 )
+#define PRINTER_NOTIFY_FIELD_BYTES_PRINTED ( 0x19 )
+#define PRINTER_NOTIFY_FIELD_OBJECT_GUID ( 0x1a )
+#define PRINTER_NOTIFY_FIELD_FRIENDLY_NAME ( 0x1b )
 #endif
 ;
 
 enum spoolss_NotifyType
 #ifndef USE_UINT_ENUMS
  {
-       SPOOLSS_NOTIFY_PRINTER=0,
-       SPOOLSS_NOTIFY_JOB=1
+       PRINTER_NOTIFY_TYPE=0x00,
+       JOB_NOTIFY_TYPE=0x01
 }
 #else
  { __donnot_use_enum_spoolss_NotifyType=0x7FFFFFFF}
-#define SPOOLSS_NOTIFY_PRINTER ( 0 )
-#define SPOOLSS_NOTIFY_JOB ( 1 )
+#define PRINTER_NOTIFY_TYPE ( 0x00 )
+#define JOB_NOTIFY_TYPE ( 0x01 )
 #endif
 ;
 
+union spoolss_Field {
+       uint16_t field;/* [case(PRINTER_NOTIFY_TYPE)] */
+}/* [noprint,nodiscriminant] */;
+
 struct spoolss_NotifyOptionType {
        enum spoolss_NotifyType type;
        uint16_t u1;
        uint32_t u2;
        uint32_t u3;
        uint32_t count;
-       enum spoolss_Field *fields;/* [unique,size_is(count)] */
+       union spoolss_Field *fields;/* [unique,switch_is(type),size_is(count)] */
 };
 
 /* bitmap spoolssNotifyOptionFlags */
@@ -1417,7 +1476,7 @@ union spoolss_NotifyData {
 
 struct spoolss_Notify {
        enum spoolss_NotifyType type;
-       enum spoolss_Field field;
+       union spoolss_Field field;/* [switch_is(type)] */
        enum spoolss_NotifyTable variable_type;
        uint32_t job_id;
        union spoolss_NotifyData data;/* [switch_is(variable_type)] */
@@ -1485,6 +1544,14 @@ struct spoolss_UserLevelCtr {
 #define JOB_ACCESS_ADMINISTER ( 0x00000010 )
 #define JOB_ACCESS_READ ( 0x00000020 )
 
+struct spoolss_PrinterEnumValues {
+       const char * value_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */
+       uint32_t value_name_len;/* [value(2*strlen_m_term(value_name))] */
+       enum winreg_Type type;
+       union spoolss_PrinterData *data;/* [relative,subcontext_size(r->data_length),subcontext(0),switch_is(type)] */
+       uint32_t data_length;/* [value(ndr_size_spoolss_PrinterData(data,type,ndr->iconv_convenience,ndr->flags))] */
+}/* [relative_base,gensize,public] */;
+
 /* bitmap spoolss_DeleteDriverFlags */
 #define DPD_DELETE_UNUSED_FILES ( 0x00000001 )
 #define DPD_DELETE_SPECIFIC_VERSION ( 0x00000002 )
@@ -1596,7 +1663,7 @@ struct spoolss_EnumPrinters {
 
        struct {
                uint32_t *count;/* [ref] */
-               union spoolss_PrinterInfo *info;/* [unique,switch_is(level),size_is(*count)] */
+               union spoolss_PrinterInfo **info;/* [ref,switch_is(level),size_is(,*count)] */
                uint32_t *needed;/* [ref] */
                WERROR result;
        } out;
@@ -1698,7 +1765,7 @@ struct spoolss_EnumJobs {
 
        struct {
                uint32_t *count;/* [ref] */
-               union spoolss_JobInfo *info;/* [unique,switch_is(level),size_is(*count)] */
+               union spoolss_JobInfo **info;/* [ref,switch_is(level),size_is(,*count)] */
                uint32_t *needed;/* [ref] */
                WERROR result;
        } out;
@@ -1815,7 +1882,7 @@ struct spoolss_EnumPrinterDrivers {
 
        struct {
                uint32_t *count;/* [ref] */
-               union spoolss_DriverInfo *info;/* [unique,switch_is(level),size_is(*count)] */
+               union spoolss_DriverInfo **info;/* [ref,switch_is(level),size_is(,*count)] */
                uint32_t *needed;/* [ref] */
                WERROR result;
        } out;
@@ -1921,7 +1988,7 @@ struct spoolss_EnumPrintProcessors {
 
        struct {
                uint32_t *count;/* [ref] */
-               union spoolss_PrintProcessorInfo *info;/* [unique,switch_is(level),size_is(*count)] */
+               union spoolss_PrintProcessorInfo **info;/* [ref,switch_is(level),size_is(,*count)] */
                uint32_t *needed;/* [ref] */
                WERROR result;
        } out;
@@ -2078,8 +2145,8 @@ struct _spoolss_GetPrinterData {
        } in;
 
        struct {
-               enum spoolss_PrinterDataType *type;/* [ref] */
-               DATA_BLOB data;
+               enum winreg_Type *type;/* [ref] */
+               DATA_BLOB *data;/* [ref] */
                uint32_t *needed;/* [ref] */
                WERROR result;
        } out;
@@ -2089,11 +2156,11 @@ struct _spoolss_GetPrinterData {
 
 struct __spoolss_GetPrinterData {
        struct {
-               enum spoolss_PrinterDataType type;
+               enum winreg_Type type;
        } in;
 
        struct {
-               union spoolss_PrinterData data;/* [switch_is(type)] */
+               union spoolss_PrinterData *data;/* [ref,switch_is(type)] */
        } out;
 
 };
@@ -2107,8 +2174,8 @@ struct spoolss_GetPrinterData {
        } in;
 
        struct {
-               enum spoolss_PrinterDataType *type;/* [ref] */
-               union spoolss_PrinterData data;/* [subcontext_size(offered),subcontext(4),switch_is(*type)] */
+               enum winreg_Type *type;/* [ref] */
+               union spoolss_PrinterData *data;/* [subcontext_size(offered),ref,subcontext(4),switch_is(*type)] */
                uint32_t *needed;/* [ref] */
                WERROR result;
        } out;
@@ -2120,7 +2187,7 @@ struct _spoolss_SetPrinterData {
        struct {
                struct policy_handle *handle;/* [ref] */
                const char *value_name;/* [charset(UTF16)] */
-               enum spoolss_PrinterDataType type;
+               enum winreg_Type type;
                DATA_BLOB data;
                uint32_t _offered;
        } in;
@@ -2134,11 +2201,11 @@ struct _spoolss_SetPrinterData {
 
 struct __spoolss_SetPrinterData {
        struct {
-               enum spoolss_PrinterDataType type;
+               enum winreg_Type type;
        } in;
 
        struct {
-               union spoolss_PrinterData data;/* [switch_is(type)] */
+               union spoolss_PrinterData *data;/* [ref,switch_is(type)] */
        } out;
 
 };
@@ -2148,7 +2215,7 @@ struct spoolss_SetPrinterData {
        struct {
                struct policy_handle *handle;/* [ref] */
                const char *value_name;/* [charset(UTF16)] */
-               enum spoolss_PrinterDataType type;
+               enum winreg_Type type;
                union spoolss_PrinterData data;/* [subcontext(4),switch_is(type)] */
                uint32_t _offered;/* [value(ndr_size_spoolss_PrinterData(&data,type,ndr->iconv_convenience,flags))] */
        } in;
@@ -2282,7 +2349,7 @@ struct spoolss_EnumForms {
 
        struct {
                uint32_t *count;/* [ref] */
-               union spoolss_FormInfo *info;/* [unique,switch_is(level),size_is(*count)] */
+               union spoolss_FormInfo **info;/* [ref,switch_is(level),size_is(,*count)] */
                uint32_t *needed;/* [ref] */
                WERROR result;
        } out;
@@ -2331,7 +2398,7 @@ struct spoolss_EnumPorts {
 
        struct {
                uint32_t *count;/* [ref] */
-               union spoolss_PortInfo *info;/* [unique,switch_is(level),size_is(*count)] */
+               union spoolss_PortInfo **info;/* [ref,switch_is(level),size_is(,*count)] */
                uint32_t *needed;/* [ref] */
                WERROR result;
        } out;
@@ -2380,7 +2447,7 @@ struct spoolss_EnumMonitors {
 
        struct {
                uint32_t *count;/* [ref] */
-               union spoolss_MonitorInfo *info;/* [unique,switch_is(level),size_is(*count)] */
+               union spoolss_MonitorInfo **info;/* [ref,switch_is(level),size_is(,*count)] */
                uint32_t *needed;/* [ref] */
                WERROR result;
        } out;
@@ -2506,8 +2573,51 @@ struct spoolss_DeletePrintProvidor {
 };
 
 
+struct _spoolss_EnumPrintProcDataTypes {
+       struct {
+               const char *servername;/* [unique,charset(UTF16)] */
+               const char *print_processor_name;/* [unique,charset(UTF16)] */
+               uint32_t level;
+               DATA_BLOB *buffer;/* [unique] */
+               uint32_t offered;
+       } in;
+
+       struct {
+               DATA_BLOB *info;/* [unique] */
+               uint32_t *needed;/* [ref] */
+               uint32_t *count;/* [ref] */
+               WERROR result;
+       } out;
+
+};
+
+
+struct __spoolss_EnumPrintProcDataTypes {
+       struct {
+               uint32_t level;
+               uint32_t count;
+       } in;
+
+       struct {
+               union spoolss_PrintProcDataTypesInfo *info;/* [switch_is(level)] */
+       } out;
+
+};
+
+
 struct spoolss_EnumPrintProcDataTypes {
        struct {
+               const char *servername;/* [unique,charset(UTF16)] */
+               const char *print_processor_name;/* [unique,charset(UTF16)] */
+               uint32_t level;
+               DATA_BLOB *buffer;/* [unique] */
+               uint32_t offered;
+       } in;
+
+       struct {
+               uint32_t *count;/* [ref] */
+               union spoolss_PrintProcDataTypesInfo **info;/* [ref,switch_is(level),size_is(,*count)] */
+               uint32_t *needed;/* [ref] */
                WERROR result;
        } out;
 
@@ -2774,8 +2884,8 @@ struct spoolss_EnumPrinterData {
        struct {
                const char *value_name;/* [charset(UTF16),size_is(value_offered/2)] */
                uint32_t *value_needed;/* [ref] */
-               uint32_t *printerdata_type;/* [ref] */
-               DATA_BLOB *buffer;/* [ref] */
+               enum winreg_Type *type;/* [ref] */
+               uint8_t *data;/* [ref,flag(LIBNDR_PRINT_ARRAY_HEX),size_is(data_offered)] */
                uint32_t *data_needed;/* [ref] */
                WERROR result;
        } out;
@@ -2825,7 +2935,7 @@ struct spoolss_SetPrinterDataEx {
                struct policy_handle *handle;/* [ref] */
                const char *key_name;/* [charset(UTF16)] */
                const char *value_name;/* [charset(UTF16)] */
-               uint32_t type;
+               enum winreg_Type type;
                uint8_t *buffer;/* [ref,size_is(offered)] */
                uint32_t offered;
        } in;
@@ -2846,7 +2956,7 @@ struct spoolss_GetPrinterDataEx {
        } in;
 
        struct {
-               uint32_t *type;/* [ref] */
+               enum winreg_Type *type;/* [ref] */
                uint8_t *buffer;/* [ref,size_is(offered)] */
                uint32_t *needed;/* [ref] */
                WERROR result;
@@ -2855,7 +2965,7 @@ struct spoolss_GetPrinterDataEx {
 };
 
 
-struct spoolss_EnumPrinterDataEx {
+struct _spoolss_EnumPrinterDataEx {
        struct {
                struct policy_handle *handle;/* [ref] */
                const char *key_name;/* [charset(UTF16)] */
@@ -2863,7 +2973,7 @@ struct spoolss_EnumPrinterDataEx {
        } in;
 
        struct {
-               uint8_t *buffer;/* [ref,size_is(offered)] */
+               DATA_BLOB info;
                uint32_t *needed;/* [ref] */
                uint32_t *count;/* [ref] */
                WERROR result;
@@ -2872,15 +2982,44 @@ struct spoolss_EnumPrinterDataEx {
 };
 
 
+struct __spoolss_EnumPrinterDataEx {
+       struct {
+               uint32_t count;
+       } in;
+
+       struct {
+               struct spoolss_PrinterEnumValues *info;
+       } out;
+
+};
+
+
+struct spoolss_EnumPrinterDataEx {
+       struct {
+               struct policy_handle *handle;/* [ref] */
+               const char *key_name;/* [charset(UTF16)] */
+               uint32_t offered;
+       } in;
+
+       struct {
+               uint32_t *count;/* [ref] */
+               struct spoolss_PrinterEnumValues **info;/* [ref,size_is(,*count)] */
+               uint32_t *needed;/* [ref] */
+               WERROR result;
+       } out;
+
+};
+
+
 struct spoolss_EnumPrinterKey {
        struct {
                struct policy_handle *handle;/* [ref] */
                const char *key_name;/* [charset(UTF16)] */
-               uint32_t key_buffer_size;
+               uint32_t offered;
        } in;
 
        struct {
-               uint16_t *key_buffer;/* [ref,size_is(key_buffer_size/2)] */
+               const char ** *key_buffer;/* [subcontext_size(offered),ref,subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */
                uint32_t *needed;/* [ref] */
                WERROR result;
        } out;
index 891be8537670b266405a799525f0e7c8386e1797..79efbb59708a1ca9d4341e31081ff0e6cd5dfd9f 100644 (file)
@@ -51,7 +51,7 @@ static bool api_spoolss_EnumPrinters(pipes_struct *p)
                return false;
        }
 
-       r->out.info = talloc_zero_array(r, union spoolss_PrinterInfo, *r->out.count);
+       r->out.info = talloc_zero(r, union spoolss_PrinterInfo *);
        if (r->out.info == NULL) {
                talloc_free(r);
                return false;
@@ -382,7 +382,7 @@ static bool api_spoolss_EnumJobs(pipes_struct *p)
                return false;
        }
 
-       r->out.info = talloc_zero_array(r, union spoolss_JobInfo, *r->out.count);
+       r->out.info = talloc_zero(r, union spoolss_JobInfo *);
        if (r->out.info == NULL) {
                talloc_free(r);
                return false;
@@ -852,7 +852,7 @@ static bool api_spoolss_EnumPrinterDrivers(pipes_struct *p)
                return false;
        }
 
-       r->out.info = talloc_zero_array(r, union spoolss_DriverInfo, *r->out.count);
+       r->out.info = talloc_zero(r, union spoolss_DriverInfo *);
        if (r->out.info == NULL) {
                talloc_free(r);
                return false;
@@ -1249,7 +1249,7 @@ static bool api_spoolss_EnumPrintProcessors(pipes_struct *p)
                return false;
        }
 
-       r->out.info = talloc_zero_array(r, union spoolss_PrintProcessorInfo, *r->out.count);
+       r->out.info = talloc_zero(r, union spoolss_PrintProcessorInfo *);
        if (r->out.info == NULL) {
                talloc_free(r);
                return false;
@@ -2113,12 +2113,18 @@ static bool api_spoolss_GetPrinterData(pipes_struct *p)
        }
 
        ZERO_STRUCT(r->out);
-       r->out.type = talloc_zero(r, enum spoolss_PrinterDataType);
+       r->out.type = talloc_zero(r, enum winreg_Type);
        if (r->out.type == NULL) {
                talloc_free(r);
                return false;
        }
 
+       r->out.data = talloc_zero(r, union spoolss_PrinterData);
+       if (r->out.data == NULL) {
+               talloc_free(r);
+               return false;
+       }
+
        r->out.needed = talloc_zero(r, uint32_t);
        if (r->out.needed == NULL) {
                talloc_free(r);
@@ -2731,7 +2737,7 @@ static bool api_spoolss_EnumForms(pipes_struct *p)
                return false;
        }
 
-       r->out.info = talloc_zero_array(r, union spoolss_FormInfo, *r->out.count);
+       r->out.info = talloc_zero(r, union spoolss_FormInfo *);
        if (r->out.info == NULL) {
                talloc_free(r);
                return false;
@@ -2823,7 +2829,7 @@ static bool api_spoolss_EnumPorts(pipes_struct *p)
                return false;
        }
 
-       r->out.info = talloc_zero_array(r, union spoolss_PortInfo, *r->out.count);
+       r->out.info = talloc_zero(r, union spoolss_PortInfo *);
        if (r->out.info == NULL) {
                talloc_free(r);
                return false;
@@ -2915,7 +2921,7 @@ static bool api_spoolss_EnumMonitors(pipes_struct *p)
                return false;
        }
 
-       r->out.info = talloc_zero_array(r, union spoolss_MonitorInfo, *r->out.count);
+       r->out.info = talloc_zero(r, union spoolss_MonitorInfo *);
        if (r->out.info == NULL) {
                talloc_free(r);
                return false;
@@ -4022,6 +4028,25 @@ static bool api_spoolss_EnumPrintProcDataTypes(pipes_struct *p)
                NDR_PRINT_IN_DEBUG(spoolss_EnumPrintProcDataTypes, r);
        }
 
+       ZERO_STRUCT(r->out);
+       r->out.count = talloc_zero(r, uint32_t);
+       if (r->out.count == NULL) {
+               talloc_free(r);
+               return false;
+       }
+
+       r->out.info = talloc_zero(r, union spoolss_PrintProcDataTypesInfo *);
+       if (r->out.info == NULL) {
+               talloc_free(r);
+               return false;
+       }
+
+       r->out.needed = talloc_zero(r, uint32_t);
+       if (r->out.needed == NULL) {
+               talloc_free(r);
+               return false;
+       }
+
        r->out.result = _spoolss_EnumPrintProcDataTypes(p, r);
 
        if (p->rng_fault_state) {
@@ -5630,14 +5655,14 @@ static bool api_spoolss_EnumPrinterData(pipes_struct *p)
                return false;
        }
 
-       r->out.printerdata_type = talloc_zero(r, uint32_t);
-       if (r->out.printerdata_type == NULL) {
+       r->out.type = talloc_zero(r, enum winreg_Type);
+       if (r->out.type == NULL) {
                talloc_free(r);
                return false;
        }
 
-       r->out.buffer = talloc_zero(r, DATA_BLOB);
-       if (r->out.buffer == NULL) {
+       r->out.data = talloc_zero_array(r, uint8_t, r->in.data_offered);
+       if (r->out.data == NULL) {
                talloc_free(r);
                return false;
        }
@@ -6087,7 +6112,7 @@ static bool api_spoolss_GetPrinterDataEx(pipes_struct *p)
        }
 
        ZERO_STRUCT(r->out);
-       r->out.type = talloc_zero(r, uint32_t);
+       r->out.type = talloc_zero(r, enum winreg_Type);
        if (r->out.type == NULL) {
                talloc_free(r);
                return false;
@@ -6179,20 +6204,20 @@ static bool api_spoolss_EnumPrinterDataEx(pipes_struct *p)
        }
 
        ZERO_STRUCT(r->out);
-       r->out.buffer = talloc_zero_array(r, uint8_t, r->in.offered);
-       if (r->out.buffer == NULL) {
+       r->out.count = talloc_zero(r, uint32_t);
+       if (r->out.count == NULL) {
                talloc_free(r);
                return false;
        }
 
-       r->out.needed = talloc_zero(r, uint32_t);
-       if (r->out.needed == NULL) {
+       r->out.info = talloc_zero(r, struct spoolss_PrinterEnumValues *);
+       if (r->out.info == NULL) {
                talloc_free(r);
                return false;
        }
 
-       r->out.count = talloc_zero(r, uint32_t);
-       if (r->out.count == NULL) {
+       r->out.needed = talloc_zero(r, uint32_t);
+       if (r->out.needed == NULL) {
                talloc_free(r);
                return false;
        }
@@ -6271,7 +6296,7 @@ static bool api_spoolss_EnumPrinterKey(pipes_struct *p)
        }
 
        ZERO_STRUCT(r->out);
-       r->out.key_buffer = talloc_zero_array(r, uint16_t, r->in.key_buffer_size / 2);
+       r->out.key_buffer = talloc_zero(r, const char **);
        if (r->out.key_buffer == NULL) {
                talloc_free(r);
                return false;
@@ -7551,7 +7576,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_MEMORY;
                        }
 
-                       r->out.info = talloc_zero_array(mem_ctx, union spoolss_PrinterInfo, *r->out.count);
+                       r->out.info = talloc_zero(mem_ctx, union spoolss_PrinterInfo *);
                        if (r->out.info == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
@@ -7608,7 +7633,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_MEMORY;
                        }
 
-                       r->out.info = talloc_zero_array(mem_ctx, union spoolss_JobInfo, *r->out.count);
+                       r->out.info = talloc_zero(mem_ctx, union spoolss_JobInfo *);
                        if (r->out.info == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
@@ -7671,7 +7696,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_MEMORY;
                        }
 
-                       r->out.info = talloc_zero_array(mem_ctx, union spoolss_DriverInfo, *r->out.count);
+                       r->out.info = talloc_zero(mem_ctx, union spoolss_DriverInfo *);
                        if (r->out.info == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
@@ -7728,7 +7753,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_MEMORY;
                        }
 
-                       r->out.info = talloc_zero_array(mem_ctx, union spoolss_PrintProcessorInfo, *r->out.count);
+                       r->out.info = talloc_zero(mem_ctx, union spoolss_PrintProcessorInfo *);
                        if (r->out.info == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
@@ -7846,11 +7871,16 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                case NDR_SPOOLSS_GETPRINTERDATA: {
                        struct spoolss_GetPrinterData *r = (struct spoolss_GetPrinterData *)_r;
                        ZERO_STRUCT(r->out);
-                       r->out.type = talloc_zero(mem_ctx, enum spoolss_PrinterDataType);
+                       r->out.type = talloc_zero(mem_ctx, enum winreg_Type);
                        if (r->out.type == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
 
+                       r->out.data = talloc_zero(mem_ctx, union spoolss_PrinterData);
+                       if (r->out.data == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+                       }
+
                        r->out.needed = talloc_zero(mem_ctx, uint32_t);
                        if (r->out.needed == NULL) {
                        return NT_STATUS_NO_MEMORY;
@@ -7923,7 +7953,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_MEMORY;
                        }
 
-                       r->out.info = talloc_zero_array(mem_ctx, union spoolss_FormInfo, *r->out.count);
+                       r->out.info = talloc_zero(mem_ctx, union spoolss_FormInfo *);
                        if (r->out.info == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
@@ -7945,7 +7975,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_MEMORY;
                        }
 
-                       r->out.info = talloc_zero_array(mem_ctx, union spoolss_PortInfo, *r->out.count);
+                       r->out.info = talloc_zero(mem_ctx, union spoolss_PortInfo *);
                        if (r->out.info == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
@@ -7967,7 +7997,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_MEMORY;
                        }
 
-                       r->out.info = talloc_zero_array(mem_ctx, union spoolss_MonitorInfo, *r->out.count);
+                       r->out.info = talloc_zero(mem_ctx, union spoolss_MonitorInfo *);
                        if (r->out.info == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
@@ -8067,6 +8097,22 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
                case NDR_SPOOLSS_ENUMPRINTPROCDATATYPES: {
                        struct spoolss_EnumPrintProcDataTypes *r = (struct spoolss_EnumPrintProcDataTypes *)_r;
+                       ZERO_STRUCT(r->out);
+                       r->out.count = talloc_zero(mem_ctx, uint32_t);
+                       if (r->out.count == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+                       }
+
+                       r->out.info = talloc_zero(mem_ctx, union spoolss_PrintProcDataTypesInfo *);
+                       if (r->out.info == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+                       }
+
+                       r->out.needed = talloc_zero(mem_ctx, uint32_t);
+                       if (r->out.needed == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+                       }
+
                        r->out.result = _spoolss_EnumPrintProcDataTypes(cli->pipes_struct, r);
                        return NT_STATUS_OK;
                }
@@ -8257,13 +8303,13 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_MEMORY;
                        }
 
-                       r->out.printerdata_type = talloc_zero(mem_ctx, uint32_t);
-                       if (r->out.printerdata_type == NULL) {
+                       r->out.type = talloc_zero(mem_ctx, enum winreg_Type);
+                       if (r->out.type == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
 
-                       r->out.buffer = talloc_zero(mem_ctx, DATA_BLOB);
-                       if (r->out.buffer == NULL) {
+                       r->out.data = talloc_zero_array(mem_ctx, uint8_t, r->in.data_offered);
+                       if (r->out.data == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
 
@@ -8309,7 +8355,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                case NDR_SPOOLSS_GETPRINTERDATAEX: {
                        struct spoolss_GetPrinterDataEx *r = (struct spoolss_GetPrinterDataEx *)_r;
                        ZERO_STRUCT(r->out);
-                       r->out.type = talloc_zero(mem_ctx, uint32_t);
+                       r->out.type = talloc_zero(mem_ctx, enum winreg_Type);
                        if (r->out.type == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
@@ -8331,18 +8377,18 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                case NDR_SPOOLSS_ENUMPRINTERDATAEX: {
                        struct spoolss_EnumPrinterDataEx *r = (struct spoolss_EnumPrinterDataEx *)_r;
                        ZERO_STRUCT(r->out);
-                       r->out.buffer = talloc_zero_array(mem_ctx, uint8_t, r->in.offered);
-                       if (r->out.buffer == NULL) {
+                       r->out.count = talloc_zero(mem_ctx, uint32_t);
+                       if (r->out.count == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
 
-                       r->out.needed = talloc_zero(mem_ctx, uint32_t);
-                       if (r->out.needed == NULL) {
+                       r->out.info = talloc_zero(mem_ctx, struct spoolss_PrinterEnumValues *);
+                       if (r->out.info == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
 
-                       r->out.count = talloc_zero(mem_ctx, uint32_t);
-                       if (r->out.count == NULL) {
+                       r->out.needed = talloc_zero(mem_ctx, uint32_t);
+                       if (r->out.needed == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
 
@@ -8353,7 +8399,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                case NDR_SPOOLSS_ENUMPRINTERKEY: {
                        struct spoolss_EnumPrinterKey *r = (struct spoolss_EnumPrinterKey *)_r;
                        ZERO_STRUCT(r->out);
-                       r->out.key_buffer = talloc_zero_array(mem_ctx, uint16_t, r->in.key_buffer_size / 2);
+                       r->out.key_buffer = talloc_zero(mem_ctx, const char **);
                        if (r->out.key_buffer == NULL) {
                        return NT_STATUS_NO_MEMORY;
                        }
index f2944b0f3938bd73aa60b403ccb4073afbc2bd61..a1bb95aa9fa471dae9e5330cd0e144041df3be46 100644 (file)
@@ -66,7 +66,57 @@ import "misc.idl", "security.idl", "winreg.idl";
                SPOOLSS_MINOR_VERSION_ME                = 0x0000005a
        } spoolss_MinorVersion;
 
-       typedef struct {
+       const int PRINTER_STATUS_OK             = 0x00000000;
+
+       typedef bitmap {
+               PRINTER_STATUS_PAUSED           = 0x00000001,
+               PRINTER_STATUS_ERROR            = 0x00000002,
+               PRINTER_STATUS_PENDING_DELETION = 0x00000004,
+               PRINTER_STATUS_PAPER_JAM        = 0x00000008,
+               PRINTER_STATUS_PAPER_OUT        = 0x00000010,
+               PRINTER_STATUS_MANUAL_FEED      = 0x00000020,
+               PRINTER_STATUS_PAPER_PROBLEM    = 0x00000040,
+               PRINTER_STATUS_OFFLINE          = 0x00000080,
+               PRINTER_STATUS_IO_ACTIVE        = 0x00000100,
+               PRINTER_STATUS_BUSY             = 0x00000200,
+               PRINTER_STATUS_PRINTING         = 0x00000400,
+               PRINTER_STATUS_OUTPUT_BIN_FULL  = 0x00000800,
+               PRINTER_STATUS_NOT_AVAILABLE    = 0x00001000,
+               PRINTER_STATUS_WAITING          = 0x00002000,
+               PRINTER_STATUS_PROCESSING       = 0x00004000,
+               PRINTER_STATUS_INITIALIZING     = 0x00008000,
+               PRINTER_STATUS_WARMING_UP       = 0x00010000,
+               PRINTER_STATUS_TONER_LOW        = 0x00020000,
+               PRINTER_STATUS_NO_TONER         = 0x00040000,
+               PRINTER_STATUS_PAGE_PUNT        = 0x00080000,
+               PRINTER_STATUS_USER_INTERVENTION= 0x00100000,
+               PRINTER_STATUS_OUT_OF_MEMORY    = 0x00200000,
+               PRINTER_STATUS_DOOR_OPEN        = 0x00400000,
+               PRINTER_STATUS_SERVER_UNKNOWN   = 0x00800000,
+               PRINTER_STATUS_POWER_SAVE       = 0x01000000
+       } spoolss_PrinterStatus;
+
+       /* JOB status codes. */
+
+       const int JOB_STATUS_QUEUED = 0x0000;
+
+       typedef [bitmap32bit] bitmap {
+               JOB_STATUS_PAUSED               = 0x00000001,
+               JOB_STATUS_ERROR                = 0x00000002,
+               JOB_STATUS_DELETING             = 0x00000004,
+               JOB_STATUS_SPOOLING             = 0x00000008,
+               JOB_STATUS_PRINTING             = 0x00000010,
+               JOB_STATUS_OFFLINE              = 0x00000020,
+               JOB_STATUS_PAPEROUT             = 0x00000040,
+               JOB_STATUS_PRINTED              = 0x00000080,
+               JOB_STATUS_DELETED              = 0x00000100,
+               JOB_STATUS_BLOCKED_DEVQ         = 0x00000200,
+               JOB_STATUS_USER_INTERVENTION    = 0x00000400,
+               JOB_STATUS_RESTART              = 0x00000800,
+               JOB_STATUS_COMPLETE             = 0x00001000
+       } spoolss_JobStatus;
+
+       typedef [public,gensize] struct {
                [relative] nstring *printername;
                [relative] nstring *servername;
                uint32 cjobs;
@@ -82,13 +132,13 @@ import "misc.idl", "security.idl", "winreg.idl";
                uint32 session_counter;
                uint32 num_error_out_of_paper;
                uint32 num_error_not_ready;
-               uint32 job_error;
+               spoolss_JobStatus job_error;
                uint32 number_of_processors;
                spoolss_ProcessorType processor_type;
                uint32 high_part_total_bytes;
                uint32 change_id;
                WERROR last_error;
-               uint32 status;
+               spoolss_PrinterStatus status;
                uint32 enumerate_network_printers;
                uint32 c_setprinter;
                spoolss_ProcessorArchitecture processor_architecture;
@@ -198,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;
@@ -224,35 +274,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                PRINTER_ATTRIBUTE_TS                    = 0x00008000
        } spoolss_PrinterAttributes;
 
-       typedef bitmap {
-               PRINTER_STATUS_PAUSED           = 0x00000001,
-               PRINTER_STATUS_ERROR            = 0x00000002,
-               PRINTER_STATUS_PENDING_DELETION = 0x00000004,
-               PRINTER_STATUS_PAPER_JAM        = 0x00000008,
-               PRINTER_STATUS_PAPER_OUT        = 0x00000010,
-               PRINTER_STATUS_MANUAL_FEED      = 0x00000020,
-               PRINTER_STATUS_PAPER_PROBLEM    = 0x00000040,
-               PRINTER_STATUS_OFFLINE          = 0x00000080,
-               PRINTER_STATUS_IO_ACTIVE        = 0x00000100,
-               PRINTER_STATUS_BUSY             = 0x00000200,
-               PRINTER_STATUS_PRINTING         = 0x00000400,
-               PRINTER_STATUS_OUTPUT_BIN_FULL  = 0x00000800,
-               PRINTER_STATUS_NOT_AVAILABLE    = 0x00001000,
-               PRINTER_STATUS_WAITING          = 0x00002000,
-               PRINTER_STATUS_PROCESSING       = 0x00004000,
-               PRINTER_STATUS_INITIALIZING     = 0x00008000,
-               PRINTER_STATUS_WARMING_UP       = 0x00010000,
-               PRINTER_STATUS_TONER_LOW        = 0x00020000,
-               PRINTER_STATUS_NO_TONER         = 0x00040000,
-               PRINTER_STATUS_PAGE_PUNT        = 0x00080000,
-               PRINTER_STATUS_USER_INTERVENTION= 0x00100000,
-               PRINTER_STATUS_OUT_OF_MEMORY    = 0x00200000,
-               PRINTER_STATUS_DOOR_OPEN        = 0x00400000,
-               PRINTER_STATUS_SERVER_UNKNOWN   = 0x00800000,
-               PRINTER_STATUS_POWER_SAVE       = 0x01000000
-       } spoolss_PrinterStatus;
-
-       typedef struct {
+       typedef [public,gensize] struct {
                [relative] nstring *servername;
                [relative] nstring *printername;
                [relative] nstring *sharename;
@@ -267,7 +289,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [relative] nstring *parameters;
                [relative,subcontext(0)] security_descriptor *secdesc;
                spoolss_PrinterAttributes attributes;
-               uint32 priority;
+               [range(0,99)] uint32 priority;
                uint32 defaultpriority;
                uint32 starttime;
                uint32 untiltime;
@@ -276,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;
@@ -294,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;
 
@@ -306,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;
@@ -315,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;
@@ -357,7 +379,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                 * and the array has no size in front
                 */
                [out,ref] uint32 *count,
-               [out,unique,switch_is(level),size_is(*count)] spoolss_PrinterInfo *info,
+               [out,ref,switch_is(level),size_is(,*count)] spoolss_PrinterInfo **info,
                [out,ref] uint32 *needed
        );
 
@@ -379,27 +401,7 @@ import "misc.idl", "security.idl", "winreg.idl";
        /******************/
        /* Function: 0x02 */
 
-       /* JOB status codes. */
-
-       const int JOB_STATUS_QUEUED = 0x0000;
-
-       typedef [bitmap32bit] bitmap {
-               JOB_STATUS_PAUSED               = 0x00000001,
-               JOB_STATUS_ERROR                = 0x00000002,
-               JOB_STATUS_DELETING             = 0x00000004,
-               JOB_STATUS_SPOOLING             = 0x00000008,
-               JOB_STATUS_PRINTING             = 0x00000010,
-               JOB_STATUS_OFFLINE              = 0x00000020,
-               JOB_STATUS_PAPEROUT             = 0x00000040,
-               JOB_STATUS_PRINTED              = 0x00000080,
-               JOB_STATUS_DELETED              = 0x00000100,
-               JOB_STATUS_BLOCKED_DEVQ         = 0x00000200,
-               JOB_STATUS_USER_INTERVENTION    = 0x00000400,
-               JOB_STATUS_RESTART              = 0x00000800,
-               JOB_STATUS_COMPLETE             = 0x00001000
-       } spoolss_JobStatus;
-
-       typedef struct {
+       typedef [public,gensize] struct {
                uint32 job_id;
                [relative] nstring *printer_name;
                [relative] nstring *server_name;
@@ -408,14 +410,14 @@ import "misc.idl", "security.idl", "winreg.idl";
                [relative] nstring *data_type;
                [relative] nstring *text_status;
                spoolss_JobStatus status;
-               uint32 priority;
+               [range(0,99)] uint32 priority;
                uint32 position;
                uint32 total_pages;
                uint32 pages_printed;
                spoolss_Time submitted;
        } spoolss_JobInfo1;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                uint32 job_id;
                [relative] nstring *printer_name;
                [relative] nstring *server_name;
@@ -430,7 +432,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [relative] nstring *text_status;
                [relative] security_descriptor *secdesc;
                spoolss_JobStatus status;
-               uint32 priority;
+               [range(0,99)] uint32 priority;
                uint32 position;
                uint32 start_time;
                uint32 until_time;
@@ -441,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;
@@ -462,7 +464,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [relative] nstring *text_status;
                [relative] security_descriptor *secdesc;
                spoolss_JobStatus status;
-               uint32 priority;
+               [range(0,99)] uint32 priority;
                uint32 position;
                uint32 start_time;
                uint32 until_time;
@@ -474,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;
@@ -491,7 +493,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [string,charset(UTF16)] uint16 *data_type;
                [string,charset(UTF16)] uint16 *text_status;
                spoolss_JobStatus status;
-               uint32 priority;
+               [range(0,99)] uint32 priority;
                uint32 position;
                uint32 total_pages;
                uint32 pages_printed;
@@ -509,11 +511,11 @@ import "misc.idl", "security.idl", "winreg.idl";
                [string,charset(UTF16)] uint16 *print_processor;
                [string,charset(UTF16)] uint16 *parameters;
                [string,charset(UTF16)] uint16 *driver_name;
-               spoolss_DeviceMode *devmode;
+               uint32 _devmode_ptr; /* pointer to truncated devicemode */
                [string,charset(UTF16)] uint16 *text_status;
-               security_descriptor *secdesc;
+               uint32 _secdesc_ptr;
                spoolss_JobStatus status;
-               uint32 priority;
+               [range(0,99)] uint32 priority;
                uint32 position;
                uint32 start_time;
                uint32 until_time;
@@ -535,11 +537,11 @@ import "misc.idl", "security.idl", "winreg.idl";
                [string,charset(UTF16)] uint16 *print_processor;
                [string,charset(UTF16)] uint16 *parameters;
                [string,charset(UTF16)] uint16 *driver_name;
-               spoolss_DeviceMode *devmode;
+               uint32 _devmode_ptr; /* pointer to truncated devicemode */
                [string,charset(UTF16)] uint16 *text_status;
-               security_descriptor *secdesc;
+               uint32 _secdesc_ptr;
                spoolss_JobStatus status;
-               uint32 priority;
+               [range(0,99)] uint32 priority;
                uint32 position;
                uint32 start_time;
                uint32 until_time;
@@ -621,7 +623,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [in,unique] DATA_BLOB *buffer,
                [in]     uint32 offered,
                [out,ref] uint32 *count,
-               [out,unique,switch_is(level),size_is(*count)] spoolss_JobInfo *info,
+               [out,ref,switch_is(level),size_is(,*count)] spoolss_JobInfo **info,
                [out,ref] uint32 *needed
        );
 
@@ -702,7 +704,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [string,charset(UTF16)] uint16 *parameters;
                [subcontext(0)] security_descriptor *secdesc;
                spoolss_PrinterAttributes attributes;
-               uint32 priority;
+               [range(0,99)] uint32 priority;
                uint32 defaultpriority;
                uint32 starttime;
                uint32 untiltime;
@@ -1050,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;
@@ -1086,7 +1088,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [in,unique] DATA_BLOB *buffer,
                [in] uint32 offered,
                [out,ref] uint32 *count,
-               [out,unique,switch_is(level),size_is(*count)] spoolss_DriverInfo *info,
+               [out,ref,switch_is(level),size_is(,*count)] spoolss_DriverInfo **info,
                [out,ref] uint32 *needed
        );
 
@@ -1138,7 +1140,7 @@ import "misc.idl", "security.idl", "winreg.idl";
 
        /******************/
        /* Function: 0x0f */
-       typedef struct {
+       typedef [public,gensize] struct {
                [relative] nstring *print_processor_name;
        } spoolss_PrintProcessorInfo1;
 
@@ -1169,7 +1171,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [in,unique] DATA_BLOB *buffer,
                [in] uint32 offered,
                [out,ref] uint32 *count,
-               [out,unique,switch_is(level),size_is(*count)] spoolss_PrintProcessorInfo *info,
+               [out,ref,switch_is(level),size_is(,*count)] spoolss_PrintProcessorInfo **info,
                [out,ref] uint32 *needed
        );
 
@@ -1300,20 +1302,12 @@ import "misc.idl", "security.idl", "winreg.idl";
                uint32 unknown3;/* hmm? w2k3: 131346(0x20112) winxp sp1: 503382272 0x1E010100 */
        } spoolss_OSVersionEx;
 
-       typedef [v1_enum] enum {
-               SPOOLSS_PRINTER_DATA_TYPE_NULL = 0,
-               SPOOLSS_PRINTER_DATA_TYPE_STRING = 1,
-               SPOOLSS_PRINTER_DATA_TYPE_BINARY = 3,
-               SPOOLSS_PRINTER_DATA_TYPE_UINT32 = 4,
-               SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY = 7
-       } spoolss_PrinterDataType;
-
        typedef [nodiscriminant,public,gensize] union {
-               [case(SPOOLSS_PRINTER_DATA_TYPE_NULL)];
-               [case(SPOOLSS_PRINTER_DATA_TYPE_STRING)] nstring string;
-               [case(SPOOLSS_PRINTER_DATA_TYPE_BINARY),flag(NDR_REMAINING)] DATA_BLOB binary;
-               [case(SPOOLSS_PRINTER_DATA_TYPE_UINT32)] uint32 value;
-               [case(SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY)] nstring_array string_array;
+               [case(REG_NONE)];
+               [case(REG_SZ)] nstring string;
+               [case(REG_BINARY),flag(NDR_REMAINING)] DATA_BLOB binary;
+               [case(REG_DWORD)] uint32 value;
+               [case(REG_MULTI_SZ)] nstring_array string_array;
                [default,flag(NDR_REMAINING)] DATA_BLOB data;
        } spoolss_PrinterData;
 
@@ -1321,20 +1315,20 @@ import "misc.idl", "security.idl", "winreg.idl";
                [in,ref] policy_handle *handle,
                [in]     [string,charset(UTF16)] uint16 value_name[],
                [in]     uint32 offered,
-               [out,ref] spoolss_PrinterDataType *type,
-               [out]    DATA_BLOB data,
+               [out,ref] winreg_Type *type,
+               [out,ref] DATA_BLOB *data,
                [out,ref] uint32 *needed
        );
        [noopnum,noprint,public] void __spoolss_GetPrinterData(
-               [in] spoolss_PrinterDataType type,
-               [out,switch_is(type)] spoolss_PrinterData data
+               [in] winreg_Type type,
+               [out,ref,switch_is(type)] spoolss_PrinterData *data
        );
        [nopull,nopush,public] WERROR spoolss_GetPrinterData(
                [in,ref] policy_handle *handle,
                [in]     [string,charset(UTF16)] uint16 value_name[],
                [in]     uint32 offered,
-               [out,ref] spoolss_PrinterDataType *type,
-               [out,subcontext(4),subcontext_size(offered),switch_is(*type)] spoolss_PrinterData data,
+               [out,ref] winreg_Type *type,
+               [out,ref,subcontext(4),subcontext_size(offered),switch_is(*type)] spoolss_PrinterData *data,
                [out,ref] uint32 *needed
        );
 
@@ -1343,18 +1337,18 @@ import "misc.idl", "security.idl", "winreg.idl";
        [noopnum,nopull,noprint,public] WERROR _spoolss_SetPrinterData(
                [in,ref] policy_handle *handle,
                [in] [string,charset(UTF16)] uint16 value_name[],
-               [in] spoolss_PrinterDataType type,
+               [in] winreg_Type type,
                [in] DATA_BLOB data,
                [in] uint32 _offered
        );
        [noopnum,nopull,noprint,public] void __spoolss_SetPrinterData(
-               [in] spoolss_PrinterDataType type,
-               [out,switch_is(type)] spoolss_PrinterData data
+               [in] winreg_Type type,
+               [out,ref,switch_is(type)] spoolss_PrinterData *data
        );
        [nopush] WERROR spoolss_SetPrinterData(
                [in,ref] policy_handle *handle,
                [in] [string,charset(UTF16)] uint16 value_name[],
-               [in] spoolss_PrinterDataType type,
+               [in] winreg_Type type,
                [in,subcontext(4),switch_is(type)] spoolss_PrinterData data,
                [in,value(ndr_size_spoolss_PrinterData(&data,type,ndr->iconv_convenience,flags))] uint32 _offered
        );
@@ -1390,7 +1384,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                uint32 bottom;
        } spoolss_FormArea;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                spoolss_FormFlags flags;
                [relative] nstring *form_name;
                spoolss_FormSize size;
@@ -1403,7 +1397,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                SPOOLSS_FORM_STRING_TYPE_LANG_PAIR      = 0x00000004
        } spoolss_FormStringType;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                spoolss_FormFlags flags;
                [relative] nstring *form_name;
                spoolss_FormSize size;
@@ -1503,11 +1497,21 @@ import "misc.idl", "security.idl", "winreg.idl";
                [in,unique] DATA_BLOB *buffer,
                [in]     uint32 offered,
                [out,ref] uint32 *count,
-               [out,unique,switch_is(level),size_is(*count)] spoolss_FormInfo *info,
+               [out,ref,switch_is(level),size_is(,*count)] spoolss_FormInfo **info,
                [out,ref] uint32 *needed
        );
 
-       typedef struct {
+       /*
+        * Special strings for the OpenPrinter() call.  See the MSDN DDK
+        * docs on the XcvDataPort() for more details.
+        */
+
+       const string SPL_LOCAL_PORT             = "Local Port";
+       const string SPL_TCPIP_PORT             = "Standard TCP/IP Port";
+       const string SPL_XCV_MONITOR_LOCALMON   = ",XcvMonitor Local Port";
+       const string SPL_XCV_MONITOR_TCPMON     = ",XcvMonitor Standard TCP/IP Port";
+
+       typedef [public,gensize] struct {
                [relative] nstring *port_name;
        } spoolss_PortInfo1;
 
@@ -1518,7 +1522,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                SPOOLSS_PORT_TYPE_NET_ATTACHED  = 0x00000008
        } spoolss_PortType;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                [relative] nstring *port_name;
                [relative] nstring *monitor_name;
                [relative] nstring *description;
@@ -1548,13 +1552,13 @@ import "misc.idl", "security.idl", "winreg.idl";
                PORT_STATUS_TYPE_INFO           = 0x00000003
        } spoolss_PortSeverity;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                spoolss_PortStatus status;
                [relative] nstring *status_string;
                spoolss_PortSeverity severity;
        } spoolss_PortInfo3;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                [relative] nstring *port_name;
                DATA_BLOB monitor_data; /* relative ?? */
        } spoolss_PortInfoFF;
@@ -1589,17 +1593,17 @@ import "misc.idl", "security.idl", "winreg.idl";
                [in,unique] DATA_BLOB *buffer,
                [in] uint32 offered,
                [out,ref] uint32 *count,
-               [out,unique,switch_is(level),size_is(*count)] spoolss_PortInfo *info,
+               [out,ref,switch_is(level),size_is(,*count)] spoolss_PortInfo **info,
                [out,ref] uint32 *needed
        );
 
        /******************/
        /* Function: 0x24 */
-       typedef struct {
+       typedef [public,gensize] struct {
                [relative] nstring *monitor_name;
        } spoolss_MonitorInfo1;
 
-       typedef struct {
+       typedef [public,gensize] struct {
                [relative] nstring *monitor_name;
                [relative] nstring *environment;
                [relative] nstring *dll_name;
@@ -1631,7 +1635,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [in,unique] DATA_BLOB *buffer,
                [in] uint32 offered,
                [out,ref] uint32 *count,
-               [out,unique,switch_is(level),size_is(*count)] spoolss_MonitorInfo *info,
+               [out,ref,switch_is(level),size_is(,*count)] spoolss_MonitorInfo **info,
                [out,ref] uint32 *needed
        );
 
@@ -1712,7 +1716,40 @@ import "misc.idl", "security.idl", "winreg.idl";
 
        /******************/
        /* Function: 0x33 */
-       [todo] WERROR spoolss_EnumPrintProcDataTypes(
+
+       typedef [public,gensize] struct {
+               [relative] nstring *name_array;
+       } spoolss_PrintProcDataTypesInfo1;
+
+       typedef [nodiscriminant,relative_base,public] union {
+               [case(1)] spoolss_PrintProcDataTypesInfo1 info1;
+               [default];
+       } spoolss_PrintProcDataTypesInfo;
+
+       [public,noopnum,noprint] WERROR _spoolss_EnumPrintProcDataTypes(
+               [in,unique] [string,charset(UTF16)] uint16 *servername,
+               [in,unique] [string,charset(UTF16)] uint16 *print_processor_name,
+               [in] uint32 level,
+               [in,unique] DATA_BLOB *buffer,
+               [in] uint32 offered,
+               [out,unique] DATA_BLOB *info,
+               [out,ref] uint32 *needed,
+               [out,ref] uint32 *count
+       );
+       [public,noopnum,noprint] void __spoolss_EnumPrintProcDataTypes(
+               [in] uint32 level,
+               [in] uint32 count,
+               [out,switch_is(level)] spoolss_PrintProcDataTypesInfo info[count]
+       );
+       [nopull,nopush] WERROR spoolss_EnumPrintProcDataTypes(
+               [in,unique] [string,charset(UTF16)] uint16 *servername,
+               [in,unique] [string,charset(UTF16)] uint16 *print_processor_name,
+               [in] uint32 level,
+               [in,unique] DATA_BLOB *buffer,
+               [in] uint32 offered,
+               [out,ref] uint32 *count,
+               [out,ref,switch_is(level),size_is(,*count)] spoolss_PrintProcDataTypesInfo **info,
+               [out,ref] uint32 *needed
        );
 
        /******************/
@@ -1855,40 +1892,75 @@ import "misc.idl", "security.idl", "winreg.idl";
        [todo] WERROR spoolss_ResetPrinterEx(
        );
 
-       typedef [enum16bit] enum {
-               SPOOLSS_FIELD_SERVER_NAME               =  0,
-               SPOOLSS_FIELD_PRINTER_NAME              =  1,
-               SPOOLSS_FIELD_SHARE_NAME        =  2,
-               SPOOLSS_FIELD_PORT_NAME                 =  3,
-               SPOOLSS_FIELD_DRIVER_NAME               =  4,
-               SPOOLSS_FIELD_COMMENT                   =  5,
-               SPOOLSS_FIELD_LOCATION                  =  6,
-               SPOOLSS_FIELD_DEVMODE                   =  7,
-               SPOOLSS_FIELD_SEPFILE                   =  8,
-               SPOOLSS_FIELD_PRINT_PROCESSOR   =  9,
-               SPOOLSS_FIELD_PARAMETERS                = 10,
-               SPOOLSS_FIELD_DATATYPE                  = 11,
-               SPOOLSS_FIELD_SECURITY_DESCRIPTOR=12,
-               SPOOLSS_FIELD_ATTRIBUTES                = 13,
-               SPOOLSS_FIELD_PRIORITY                  = 14,
-               SPOOLSS_FIELD_DEFAULT_PRIORITY  = 15,
-               SPOOLSS_FIELD_START_TIME                = 16,
-               SPOOLSS_FIELD_UNTIL_TIME                = 17,
-               SPOOLSS_FIELD_STATUS                    = 18,
-               SPOOLSS_FIELD_STATUS_STRING             = 19,
-               SPOOLSS_FIELD_CJOBS                             = 20,
-               SPOOLSS_FIELD_AVERAGE_PPM               = 21,
-               SPOOLSS_FIELD_TOTAL_PAGES               = 22,
-               SPOOLSS_FIELD_PAGES_PRINTED     = 23,
-               SPOOLSS_FIELD_TOTAL_BYTES               = 24,
-               SPOOLSS_FIELD_BYTES_PRINTED             = 25
-       } spoolss_Field;
+       typedef [enum16bit,public] enum {
+               JOB_NOTIFY_FIELD_PRINTER_NAME                   = 0x00,
+               JOB_NOTIFY_FIELD_MACHINE_NAME                   = 0x01,
+               JOB_NOTIFY_FIELD_PORT_NAME                      = 0x02,
+               JOB_NOTIFY_FIELD_USER_NAME                      = 0x03,
+               JOB_NOTIFY_FIELD_NOTIFY_NAME                    = 0x04,
+               JOB_NOTIFY_FIELD_DATATYPE                       = 0x05,
+               JOB_NOTIFY_FIELD_PRINT_PROCESSOR                = 0x06,
+               JOB_NOTIFY_FIELD_PARAMETERS                     = 0x07,
+               JOB_NOTIFY_FIELD_DRIVER_NAME                    = 0x08,
+               JOB_NOTIFY_FIELD_DEVMODE                        = 0x09,
+               JOB_NOTIFY_FIELD_STATUS                         = 0x0a,
+               JOB_NOTIFY_FIELD_STATUS_STRING                  = 0x0b,
+               JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR            = 0x0c,
+               JOB_NOTIFY_FIELD_DOCUMENT                       = 0x0d,
+               JOB_NOTIFY_FIELD_PRIORITY                       = 0x0e,
+               JOB_NOTIFY_FIELD_POSITION                       = 0x0f,
+               JOB_NOTIFY_FIELD_SUBMITTED                      = 0x10,
+               JOB_NOTIFY_FIELD_START_TIME                     = 0x11,
+               JOB_NOTIFY_FIELD_UNTIL_TIME                     = 0x12,
+               JOB_NOTIFY_FIELD_TIME                           = 0x13,
+               JOB_NOTIFY_FIELD_TOTAL_PAGES                    = 0x14,
+               JOB_NOTIFY_FIELD_PAGES_PRINTED                  = 0x15,
+               JOB_NOTIFY_FIELD_TOTAL_BYTES                    = 0x16,
+               JOB_NOTIFY_FIELD_BYTES_PRINTED                  = 0x17
+       } spoolss_JobNotifyField;
+
+       typedef [enum16bit,public] enum {
+               PRINTER_NOTIFY_FIELD_SERVER_NAME                = 0x00,
+               PRINTER_NOTIFY_FIELD_PRINTER_NAME               = 0x01,
+               PRINTER_NOTIFY_FIELD_SHARE_NAME                 = 0x02,
+               PRINTER_NOTIFY_FIELD_PORT_NAME                  = 0x03,
+               PRINTER_NOTIFY_FIELD_DRIVER_NAME                = 0x04,
+               PRINTER_NOTIFY_FIELD_COMMENT                    = 0x05,
+               PRINTER_NOTIFY_FIELD_LOCATION                   = 0x06,
+               PRINTER_NOTIFY_FIELD_DEVMODE                    = 0x07,
+               PRINTER_NOTIFY_FIELD_SEPFILE                    = 0x08,
+               PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR            = 0x09,
+               PRINTER_NOTIFY_FIELD_PARAMETERS                 = 0x0a,
+               PRINTER_NOTIFY_FIELD_DATATYPE                   = 0x0b,
+               PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR        = 0x0c,
+               PRINTER_NOTIFY_FIELD_ATTRIBUTES                 = 0x0d,
+               PRINTER_NOTIFY_FIELD_PRIORITY                   = 0x0e,
+               PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY           = 0x0f,
+               PRINTER_NOTIFY_FIELD_START_TIME                 = 0x10,
+               PRINTER_NOTIFY_FIELD_UNTIL_TIME                 = 0x11,
+               PRINTER_NOTIFY_FIELD_STATUS                     = 0x12,
+               PRINTER_NOTIFY_FIELD_STATUS_STRING              = 0x13,
+               PRINTER_NOTIFY_FIELD_CJOBS                      = 0x14,
+               PRINTER_NOTIFY_FIELD_AVERAGE_PPM                = 0x15,
+               PRINTER_NOTIFY_FIELD_TOTAL_PAGES                = 0x16,
+               PRINTER_NOTIFY_FIELD_PAGES_PRINTED              = 0x17,
+               PRINTER_NOTIFY_FIELD_TOTAL_BYTES                = 0x18,
+               PRINTER_NOTIFY_FIELD_BYTES_PRINTED              = 0x19,
+               PRINTER_NOTIFY_FIELD_OBJECT_GUID                = 0x1a,
+               PRINTER_NOTIFY_FIELD_FRIENDLY_NAME              = 0x1b
+       } spoolss_PrintNotifyField;
 
        typedef [enum16bit] enum {
-               SPOOLSS_NOTIFY_PRINTER                  = 0,
-               SPOOLSS_NOTIFY_JOB                              = 1
+               PRINTER_NOTIFY_TYPE     = 0x00,
+               JOB_NOTIFY_TYPE         = 0x01
        } spoolss_NotifyType;
 
+       typedef [nodiscriminant,noprint] union {
+               [case(PRINTER_NOTIFY_TYPE)] uint16 field;
+               [case(JOB_NOTIFY_TYPE)] uint16 field;
+               [default] uint16 field;
+       } spoolss_Field;
+
        /******************/
        /* Function: 0x41 */
        typedef struct {
@@ -1897,7 +1969,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                uint32 u2;
                uint32 u3;
                uint32 count;
-               [size_is(count)] spoolss_Field *fields;
+               [size_is(count),switch_is(type)] spoolss_Field *fields;
        } spoolss_NotifyOptionType;
 
        typedef [bitmap32bit] bitmap {
@@ -1946,7 +2018,7 @@ import "misc.idl", "security.idl", "winreg.idl";
 
        typedef struct {
                spoolss_NotifyType type;
-               spoolss_Field field;
+               [switch_is(type)] spoolss_Field field;
                spoolss_NotifyTable variable_type;
                uint32 job_id;
                [switch_is(variable_type)] spoolss_NotifyData data;
@@ -2128,8 +2200,8 @@ import "misc.idl", "security.idl", "winreg.idl";
                [out,size_is(value_offered/2),charset(UTF16)] uint16 value_name[],
                [in]     uint32 value_offered,
                [out,ref] uint32 *value_needed,
-               [out,ref] uint32 *printerdata_type,
-               [out,ref] DATA_BLOB *buffer,
+               [out,ref] winreg_Type *type,
+               [out,ref,size_is(data_offered),flag(LIBNDR_PRINT_ARRAY_HEX)] uint8 *data,
                [in]     uint32 data_offered,
                [out,ref] uint32 *data_needed
        );
@@ -2162,7 +2234,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [in,ref] policy_handle *handle,
                [in]     [string,charset(UTF16)] uint16 key_name[],
                [in]     [string,charset(UTF16)] uint16 value_name[],
-               [in]     uint32 type,
+               [in]     winreg_Type type,
                [in,ref] [size_is(offered)] uint8 *buffer,
                [in]     uint32 offered
        );
@@ -2173,7 +2245,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [in,ref] policy_handle *handle,
                [in]     [string,charset(UTF16)] uint16 key_name[],
                [in]     [string,charset(UTF16)] uint16 value_name[],
-               [out,ref] uint32 *type,
+               [out,ref] winreg_Type *type,
                [out,ref] [size_is(offered)] uint8 *buffer,
                [in]     uint32 offered,
                [out,ref] uint32 *needed
@@ -2181,22 +2253,43 @@ import "misc.idl", "security.idl", "winreg.idl";
 
        /******************/
        /* Function: 0x4f */
-       [public] WERROR spoolss_EnumPrinterDataEx(
+
+       typedef [relative_base,public,gensize] struct {
+               [relative] nstring *value_name;
+               [value(2*strlen_m_term(value_name))] uint32 value_name_len;
+               winreg_Type type;
+               [relative,switch_is(type),subcontext(0),subcontext_size(r->data_length)] spoolss_PrinterData *data;
+               [value(ndr_size_spoolss_PrinterData(data, type, ndr->iconv_convenience, ndr->flags))] uint32 data_length;
+       } spoolss_PrinterEnumValues;
+
+       [public,noopnum,noprint] WERROR _spoolss_EnumPrinterDataEx(
                [in,ref] policy_handle *handle,
                [in]     [string,charset(UTF16)] uint16 key_name[],
-               [out,ref] [size_is(offered)] uint8 *buffer,
-               [in]     uint32 offered,
+               [out] DATA_BLOB info,
+               [in] uint32 offered,
                [out,ref] uint32 *needed,
                [out,ref] uint32 *count
        );
+       [public,noopnum,noprint] void __spoolss_EnumPrinterDataEx(
+               [in] uint32 count,
+               [out] spoolss_PrinterEnumValues info[count]
+       );
+       [nopull,nopush] WERROR spoolss_EnumPrinterDataEx(
+               [in,ref] policy_handle *handle,
+               [in]     [string,charset(UTF16)] uint16 key_name[],
+               [in] uint32 offered,
+               [out,ref] uint32 *count,
+               [out,ref,size_is(,*count)] spoolss_PrinterEnumValues **info,
+               [out,ref] uint32 *needed
+       );
 
        /******************/
        /* Function: 0x50 */
        [public] WERROR spoolss_EnumPrinterKey(
                [in, ref] policy_handle *handle,
                [in] [string,charset(UTF16)] uint16 key_name[],
-               [out,ref] [size_is(key_buffer_size/2)] uint16 *key_buffer,
-               [in] uint32 key_buffer_size,
+               [out,ref] [subcontext(0),subcontext_size(offered)] nstring_array **key_buffer,
+               [in] uint32 offered,
                [out,ref] uint32 *needed
        );
 
index 2341f51faa03315032ea03c8c81fecdbc090e164..8188ec998fe28e4b233a8e594a1a3cae6be3f1b7 100644 (file)
@@ -179,10 +179,10 @@ _PUBLIC_ void ndr_print_debug_helper(struct ndr_print *ndr, const char *format,
        }
 
        for (i=0;i<ndr->depth;i++) {
-               DEBUGADD(0,("    "));
+               DEBUGADD(1,("    "));
        }
 
-       DEBUGADD(0,("%s\n", s));
+       DEBUGADD(1,("%s\n", s));
        free(s);
 }
 
@@ -211,7 +211,7 @@ _PUBLIC_ void ndr_print_debug(ndr_print_fn_t fn, const char *name, void *ptr)
 {
        struct ndr_print *ndr;
 
-       DEBUG(0,(" "));
+       DEBUG(1,(" "));
 
        ndr = talloc_zero(NULL, struct ndr_print);
        if (!ndr) return;
@@ -229,7 +229,7 @@ _PUBLIC_ void ndr_print_union_debug(ndr_print_fn_t fn, const char *name, uint32_
 {
        struct ndr_print *ndr;
 
-       DEBUG(0,(" "));
+       DEBUG(1,(" "));
 
        ndr = talloc_zero(NULL, struct ndr_print);
        if (!ndr) return;
@@ -248,7 +248,7 @@ _PUBLIC_ void ndr_print_function_debug(ndr_print_function_t fn, const char *name
 {
        struct ndr_print *ndr;
 
-       DEBUG(0,(" "));
+       DEBUG(1,(" "));
 
        ndr = talloc_zero(NULL, struct ndr_print);
        if (!ndr) return;
index afc06be4e0d70a67a195632c8fd944b71abecf69..0acae3dedbf2f60989501365f808f9c8544d26c8 100644 (file)
@@ -5,6 +5,7 @@
 
    Copyright (C) Andrew Tridgell 2003
    Copyright (C) Tim Potter 2003
+   Copyright (C) Guenther Deschner 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
@@ -52,9 +53,9 @@
        _r.out.needed   = r->out.needed;\
        _r.out.count    = r->out.count;\
        _r.out.result   = r->out.result;\
-       if (r->out.info && !r->in.buffer) {\
+       if (r->out.info && *r->out.info && !r->in.buffer) {\
                return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\
-                       "SPOOLSS Buffer: r->out.info but there's no r->in.buffer");\
+                       "SPOOLSS Buffer: *r->out.info but there's no r->in.buffer");\
        }\
        if (r->in.buffer) {\
                DATA_BLOB _data_blob_info;\
@@ -65,7 +66,7 @@
                        struct __##fn __r;\
                        __r.in.level    = r->in.level;\
                        __r.in.count    = *r->out.count;\
-                       __r.out.info    = r->out.info;\
+                       __r.out.info    = *r->out.info;\
                        NDR_CHECK(ndr_push___##fn(_ndr_info, flags, &__r)); \
                }\
                if (r->in.offered > _ndr_info->offset) {\
                        "SPOOLSS Buffer: r->in.offered[%u] doesn't match length of r->in.buffer[%u]",\
                        (unsigned)r->in.offered, (unsigned)r->in.buffer->length);\
        }\
+       NDR_PULL_ALLOC(ndr, r->out.info);\
+       ZERO_STRUCTP(r->out.info);\
 } while(0)
 
 #define NDR_SPOOLSS_PULL_ENUM_OUT(fn) do { \
        _r.out.needed   = r->out.needed;\
        _r.out.count    = r->out.count;\
        NDR_CHECK(ndr_pull__##fn(ndr, flags, &_r));\
-       r->out.info     = NULL;\
+       if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {\
+               NDR_PULL_ALLOC(ndr, r->out.info);\
+       }\
+       *r->out.info = NULL;\
        r->out.needed   = _r.out.needed;\
        r->out.count    = _r.out.count;\
        r->out.result   = _r.out.result;\
        if (_r.out.info) {\
-               struct ndr_pull *_ndr_info = ndr_pull_init_blob(_r.out.info, ndr, ndr->iconv_convenience);\
+               struct ndr_pull *_ndr_info;\
+               NDR_PULL_ALLOC(ndr, *r->out.info);\
+               _ndr_info = ndr_pull_init_blob(_r.out.info, *r->out.info, ndr->iconv_convenience);\
                NDR_ERR_HAVE_NO_MEMORY(_ndr_info);\
                _ndr_info->flags= ndr->flags;\
                if (r->in.offered != _ndr_info->data_size) {\
                        __r.in.count    = *r->out.count;\
                        __r.out.info    = NULL;\
                        NDR_CHECK(ndr_pull___##fn(_ndr_info, flags, &__r));\
-                       r->out.info     = __r.out.info;\
+                       *r->out.info    = __r.out.info;\
                }\
        }\
 } while(0)
 } while (0)
 
 /* TODO: set _ndr_info->flags correct */
-#define NDR_SPOOLSS_SIZE_ENUM(fn) do { \
+#define NDR_SPOOLSS_SIZE_ENUM_LEVEL(fn) do { \
        struct __##fn __r;\
        DATA_BLOB _data_blob_info;\
        struct ndr_push *_ndr_info = ndr_push_init_ctx(mem_ctx, iconv_convenience);\
        return _data_blob_info.length;\
 } while(0)
 
+/* TODO: set _ndr_info->flags correct */
+#define NDR_SPOOLSS_SIZE_ENUM(fn) do { \
+       struct __##fn __r;\
+       DATA_BLOB _data_blob_info;\
+       struct ndr_push *_ndr_info = ndr_push_init_ctx(mem_ctx, iconv_convenience);\
+       if (!_ndr_info) return 0;\
+       _ndr_info->flags|=0;\
+       __r.in.count    = count;\
+       __r.out.info    = info;\
+       _NDR_CHECK_UINT32(ndr_push___##fn(_ndr_info, NDR_OUT, &__r)); \
+       _data_blob_info = ndr_push_blob(_ndr_info);\
+       return _data_blob_info.length;\
+} while(0)
+
+
 /*
   spoolss_EnumPrinters
 */
@@ -209,7 +232,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)
 {
-       NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPrinters);
+       NDR_SPOOLSS_SIZE_ENUM_LEVEL(spoolss_EnumPrinters);
 }
 
 /*
@@ -243,9 +266,9 @@ 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);
+       NDR_SPOOLSS_SIZE_ENUM_LEVEL(spoolss_EnumJobs);
 }
 
 /*
@@ -277,7 +300,7 @@ enum ndr_err_code ndr_pull_spoolss_EnumPrinterDrivers(struct ndr_pull *ndr, int
 
 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)
 {
-       NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPrinterDrivers);
+       NDR_SPOOLSS_SIZE_ENUM_LEVEL(spoolss_EnumPrinterDrivers);
 }
 
 /*
@@ -305,7 +328,7 @@ enum ndr_err_code ndr_pull_spoolss_EnumForms(struct ndr_pull *ndr, int flags, st
 
 uint32_t ndr_size_spoolss_EnumForms_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, uint32_t level, uint32_t count, union spoolss_FormInfo *info)
 {
-       NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumForms);
+       NDR_SPOOLSS_SIZE_ENUM_LEVEL(spoolss_EnumForms);
 }
 
 /*
@@ -333,7 +356,7 @@ enum ndr_err_code ndr_pull_spoolss_EnumPorts(struct ndr_pull *ndr, int flags, st
 
 uint32_t ndr_size_spoolss_EnumPorts_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, uint32_t level, uint32_t count, union spoolss_PortInfo *info)
 {
-       NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPorts);
+       NDR_SPOOLSS_SIZE_ENUM_LEVEL(spoolss_EnumPorts);
 }
 
 /*
@@ -361,7 +384,7 @@ 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)
 {
-       NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumMonitors);
+       NDR_SPOOLSS_SIZE_ENUM_LEVEL(spoolss_EnumMonitors);
 }
 
 /*
@@ -391,10 +414,143 @@ 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);
+       NDR_SPOOLSS_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcessors);
+}
+
+/*
+  spoolss_EnumPrintProcessors
+*/
+enum ndr_err_code ndr_push_spoolss_EnumPrintProcDataTypes(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrintProcDataTypes *r)
+{
+       NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumPrintProcDataTypes,{
+               _r.in.servername                = r->in.servername;
+               _r.in.print_processor_name      = r->in.print_processor_name;
+       },{
+               _r.in.servername                = r->in.servername;
+               _r.in.print_processor_name      = r->in.print_processor_name;
+       });
+       return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_pull_spoolss_EnumPrintProcDataTypes(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrintProcDataTypes *r)
+{
+       NDR_SPOOLSS_PULL_ENUM(spoolss_EnumPrintProcDataTypes,{
+               r->in.servername                = _r.in.servername;
+               r->in.print_processor_name      = _r.in.print_processor_name;
+       },{
+               _r.in.servername                = r->in.servername;
+               _r.in.print_processor_name      = r->in.print_processor_name;
+       });
+       return NDR_ERR_SUCCESS;
+}
+
+uint32_t ndr_size_spoolss_EnumPrintProcDataTypes_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience,
+                                                     uint32_t level, uint32_t count, union spoolss_PrintProcDataTypesInfo *info)
+{
+       NDR_SPOOLSS_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcDataTypes);
+}
+
+/*
+  spoolss_EnumPrinterDataEx
+*/
+
+enum ndr_err_code ndr_push_spoolss_EnumPrinterDataEx(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrinterDataEx *r)
+{
+       struct _spoolss_EnumPrinterDataEx _r;
+       if (flags & NDR_IN) {
+               _r.in.handle    = r->in.handle;
+               _r.in.key_name  = r->in.key_name;
+               _r.in.offered   = r->in.offered;
+               NDR_CHECK(ndr_push__spoolss_EnumPrinterDataEx(ndr, flags, &_r));
+       }
+       if (flags & NDR_OUT) {
+               struct ndr_push *_ndr_info;
+               _r.in.handle    = r->in.handle;
+               _r.in.key_name  = r->in.key_name;
+               _r.in.offered   = r->in.offered;
+               _r.out.count    = r->out.count;
+               _r.out.needed   = r->out.needed;
+               _r.out.result   = r->out.result;
+               _r.out.info     = data_blob(NULL, 0);
+               if (r->in.offered >= *r->out.needed) {
+                       struct __spoolss_EnumPrinterDataEx __r;
+                       _ndr_info = ndr_push_init_ctx(ndr, ndr->iconv_convenience);
+                       NDR_ERR_HAVE_NO_MEMORY(_ndr_info);
+                       _ndr_info->flags= ndr->flags;
+                       __r.in.count    = *r->out.count;
+                       __r.out.info    = *r->out.info;
+                       NDR_CHECK(ndr_push___spoolss_EnumPrinterDataEx(_ndr_info, flags, &__r));
+                       if (r->in.offered > _ndr_info->offset) {
+                               uint32_t _padding_len = r->in.offered - _ndr_info->offset;
+                               NDR_CHECK(ndr_push_zero(_ndr_info, _padding_len));
+                       }
+                       _r.out.info = ndr_push_blob(_ndr_info);
+               }
+               NDR_CHECK(ndr_push__spoolss_EnumPrinterDataEx(ndr, flags, &_r));
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_pull_spoolss_EnumPrinterDataEx(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinterDataEx *r)
+{
+       struct _spoolss_EnumPrinterDataEx _r;
+       if (flags & NDR_IN) {
+               _r.in.handle    = r->in.handle;
+               _r.in.key_name  = r->in.key_name;
+               ZERO_STRUCT(r->out);
+               NDR_CHECK(ndr_pull__spoolss_EnumPrinterDataEx(ndr, flags, &_r));
+               r->in.handle    = _r.in.handle;
+               r->in.key_name  = _r.in.key_name;
+               r->in.offered   = _r.in.offered;
+               r->out.needed   = _r.out.needed;
+               r->out.count    = _r.out.count;
+               NDR_PULL_ALLOC(ndr, r->out.info);
+               ZERO_STRUCTP(r->out.info);
+       }
+       if (flags & NDR_OUT) {
+               _r.in.handle    = r->in.handle;
+               _r.in.key_name  = r->in.key_name;
+               _r.in.offered   = r->in.offered;
+               _r.out.count    = r->out.count;
+               _r.out.needed   = r->out.needed;
+               NDR_CHECK(ndr_pull__spoolss_EnumPrinterDataEx(ndr, flags, &_r));
+               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                       NDR_PULL_ALLOC(ndr, r->out.info);
+               }
+               *r->out.info    = NULL;
+               r->out.needed   = _r.out.needed;
+               r->out.count    = _r.out.count;
+               r->out.result   = _r.out.result;
+               if (_r.out.info.length) {
+                       struct ndr_pull *_ndr_info;
+                       NDR_PULL_ALLOC(ndr, *r->out.info);
+                       _ndr_info = ndr_pull_init_blob(&_r.out.info, *r->out.info, ndr->iconv_convenience);
+                       NDR_ERR_HAVE_NO_MEMORY(_ndr_info);
+                       _ndr_info->flags= ndr->flags;
+                       if (r->in.offered != _ndr_info->data_size) {
+                               return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,
+                                       "SPOOLSS Buffer: offered[%u] doesn't match length of buffer[%u]",
+                                       (unsigned)r->in.offered, (unsigned)_ndr_info->data_size);
+                       }
+                       if (*r->out.needed <= _ndr_info->data_size) {
+                               struct __spoolss_EnumPrinterDataEx __r;
+                               __r.in.count    = *r->out.count;
+                               __r.out.info    = NULL;
+                               NDR_CHECK(ndr_pull___spoolss_EnumPrinterDataEx(_ndr_info, flags, &__r));
+                               *r->out.info    = __r.out.info;
+                       }
+               }
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+uint32_t ndr_size_spoolss_EnumPrinterDataEx_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience,
+                                                uint32_t count, struct spoolss_PrinterEnumValues *info)
+{
+       NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPrinterDataEx);
 }
 
 /*
@@ -411,15 +567,17 @@ enum ndr_err_code ndr_push_spoolss_GetPrinterData(struct ndr_push *ndr, int flag
        }
        if (flags & NDR_OUT) {
                struct ndr_push *_ndr_info;
+               DATA_BLOB blob = data_blob(NULL, 0);
                _r.in.handle    = r->in.handle;
                _r.in.value_name= r->in.value_name;
                _r.in.offered   = r->in.offered;
                _r.out.type     = r->out.type;
-               _r.out.data     = data_blob(NULL, 0);
+               _r.out.data     = &blob;
                _r.out.needed   = r->out.needed;
                _r.out.result   = r->out.result;
                {
                        struct __spoolss_GetPrinterData __r;
+                       DATA_BLOB _blob;
                        _ndr_info = ndr_push_init_ctx(ndr, ndr->iconv_convenience);
                        NDR_ERR_HAVE_NO_MEMORY(_ndr_info);
                        _ndr_info->flags= ndr->flags;
@@ -430,7 +588,8 @@ enum ndr_err_code ndr_push_spoolss_GetPrinterData(struct ndr_push *ndr, int flag
                                uint32_t _padding_len = r->in.offered - _ndr_info->offset;
                                NDR_CHECK(ndr_push_zero(_ndr_info, _padding_len));
                        }
-                       _r.out.data = ndr_push_blob(_ndr_info);
+                       _blob = ndr_push_blob(_ndr_info);
+                       _r.out.data = &_blob;
                }
                NDR_CHECK(ndr_push__spoolss_GetPrinterData(ndr, flags, &_r));
        }
@@ -441,13 +600,14 @@ enum ndr_err_code ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flag
 {
        struct _spoolss_GetPrinterData _r;
        if (flags & NDR_IN) {
+               DATA_BLOB blob = data_blob(NULL,0);
                ZERO_STRUCT(r->out);
 
                _r.in.handle    = r->in.handle;
                _r.in.value_name= r->in.value_name;
                _r.in.offered   = r->in.offered;
                _r.out.type     = r->out.type;
-               _r.out.data     = data_blob(NULL,0),
+               _r.out.data     = &blob;
                _r.out.needed   = r->out.needed;
                NDR_CHECK(ndr_pull__spoolss_GetPrinterData(ndr, flags, &_r));
                r->in.handle    = _r.in.handle;
@@ -456,26 +616,30 @@ enum ndr_err_code ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flag
                r->out.needed   = _r.out.needed;
        }
        if (flags & NDR_OUT) {
+               DATA_BLOB blob = data_blob_talloc(ndr,NULL,0);
                _r.in.handle    = r->in.handle;
                _r.in.value_name= r->in.value_name;
                _r.in.offered   = r->in.offered;
                _r.out.type     = r->out.type;
-               _r.out.data     = data_blob(NULL,0),
+               _r.out.data     = &blob;
                _r.out.needed   = r->out.needed;
                _r.out.result   = r->out.result;
                NDR_CHECK(ndr_pull__spoolss_GetPrinterData(ndr, flags, &_r));
                r->out.type     = _r.out.type;
-               ZERO_STRUCT(r->out.data);
+               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                       NDR_PULL_ALLOC(ndr, r->out.data);
+               }
+               ZERO_STRUCTP(r->out.data);
                r->out.needed   = _r.out.needed;
                r->out.result   = _r.out.result;
-               if (_r.out.data.length != r->in.offered) {
+               if (_r.out.data && _r.out.data->length != r->in.offered) {
                        return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,
                                "SPOOLSS Buffer: r->in.offered[%u] doesn't match length of out buffer[%u]",
-                               (unsigned)r->in.offered, (unsigned)_r.out.data.length);
+                               (unsigned)r->in.offered, (unsigned)_r.out.data->length);
                }
-               if (_r.out.data.length > 0 && *r->out.needed <= _r.out.data.length) {
+               if (_r.out.data && _r.out.data->length > 0 && *r->out.needed <= _r.out.data->length) {
                        struct __spoolss_GetPrinterData __r;
-                       struct ndr_pull *_ndr_data = ndr_pull_init_blob(&_r.out.data, ndr, ndr->iconv_convenience);
+                       struct ndr_pull *_ndr_data = ndr_pull_init_blob(_r.out.data, ndr, ndr->iconv_convenience);
                        NDR_ERR_HAVE_NO_MEMORY(_ndr_data);
                        _ndr_data->flags= ndr->flags;
                        __r.in.type     = *r->out.type;
@@ -483,7 +647,7 @@ enum ndr_err_code ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flag
                        NDR_CHECK(ndr_pull___spoolss_GetPrinterData(_ndr_data, flags, &__r));
                        r->out.data     = __r.out.data;
                } else {
-                       *r->out.type    = SPOOLSS_PRINTER_DATA_TYPE_NULL;
+                       *r->out.type    = REG_NONE;
                }
        }
        return NDR_ERR_SUCCESS;
@@ -505,7 +669,7 @@ enum ndr_err_code ndr_push_spoolss_SetPrinterData(struct ndr_push *ndr, int flag
                _ndr_data->flags= ndr->flags;
 
                __r.in.type     = r->in.type;
-               __r.out.data    = r->in.data;
+               __r.out.data    = discard_const_p(union spoolss_PrinterData, &r->in.data);
                NDR_CHECK(ndr_push___spoolss_SetPrinterData(_ndr_data, NDR_OUT, &__r));
                _data_blob_data = ndr_push_blob(_ndr_data);
 
@@ -1022,3 +1186,25 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr,
        }
        return NDR_ERR_SUCCESS;
 }
+
+void ndr_print_spoolss_Field(struct ndr_print *ndr, const char *name, const union spoolss_Field *r)
+{
+       int level;
+       level = ndr_print_get_switch_value(ndr, r);
+       ndr_print_union(ndr, name, level, "spoolss_Field");
+       switch (level) {
+               case PRINTER_NOTIFY_TYPE:
+                       ndr_print_spoolss_PrintNotifyField(ndr, "field", r->field);
+               break;
+
+               case JOB_NOTIFY_TYPE:
+                       ndr_print_spoolss_JobNotifyField(ndr, "field", r->field);
+               break;
+
+               default:
+                       ndr_print_uint16(ndr, "field", r->field);
+               break;
+
+       }
+}
+
index 5ed848d7e0786195402cf8e5a10a4ca7a61bf4a1..aa6e277c5f380524290238f60ece58fa68eefcd2 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,16 @@ 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,
+                                                     uint32_t level, uint32_t count, union spoolss_PrintProcDataTypesInfo *info);
+enum ndr_err_code ndr_push_spoolss_EnumPrinterDataEx(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrinterDataEx *r);
+enum ndr_err_code ndr_pull_spoolss_EnumPrinterDataEx(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinterDataEx *r);
+uint32_t ndr_size_spoolss_EnumPrinterDataEx_info(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience,
+                                                uint32_t count, struct spoolss_PrinterEnumValues *info);
 enum ndr_err_code ndr_push_spoolss_GetPrinterData(struct ndr_push *ndr, int flags, const struct spoolss_GetPrinterData *r);
 enum ndr_err_code ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flags, struct spoolss_GetPrinterData *r);
 enum ndr_err_code ndr_push_spoolss_SetPrinterData(struct ndr_push *ndr, int flags, const struct spoolss_SetPrinterData *r);
@@ -41,6 +49,7 @@ uint32_t _ndr_size_spoolss_DeviceMode(struct spoolss_DeviceMode *devmode, struct
 size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r, struct smb_iconv_convenience *ic, int flags);
 _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo101(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo101 *r);
 _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo101 *r);
+void ndr_print_spoolss_Field(struct ndr_print *ndr, const char *name, const union spoolss_Field *r);
 
 #undef _PRINTF_ATTRIBUTE
 #define _PRINTF_ATTRIBUTE(a1, a2)
index 7e56af76f73d9cf1c58c8c5ee92a2989cac97e56..94537663137c647f50d49ebe632265b1335c2a74 100644 (file)
@@ -41,7 +41,11 @@ dnl $PYTHON_CFLAGS
 dnl $PYTHON_LDFLAGS
 AC_DEFUN([AC_SAMBA_PYTHON_DEVEL],
 [
-       AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
+       if test -z "$PYTHON_VERSION"; then
+               AC_PATH_PROGS([PYTHON], [python2.6 python2.5 python2.4 python])
+       else
+               AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
+       fi
        if test -z "$PYTHON"; then
                working_python=no
                AC_MSG_WARN([No python found])
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 0395a1fd5b91dc545ef315858e0fda0fa2354c0e..25d673e231dd98fcd7f06826d11ac122d3340658 100644 (file)
@@ -171,6 +171,8 @@ struct pwb_context {
        uint32_t ctrl;
 };
 
+#ifndef TALLOC_FREE
 #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
+#endif
 #define TALLOC_ZERO_P(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
 #define TALLOC_P(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
index f674e8386c947a389c07a7bc8c2e407593cae0c7..94794ccfd09b80b46e842bef821ebd35520ed2f1 100644 (file)
@@ -348,6 +348,7 @@ fi
 %{_mandir}/man1/vfstest.1*
 %{_mandir}/man5/smbpasswd.5*
 %{_mandir}/man7/samba.7*
+%{_mandir}/man7/winbind_krb5_locator.7*
 %{_mandir}/man8/nmbd.8*
 %{_mandir}/man8/pdbedit.8*
 %{_mandir}/man8/smbd.8*
@@ -396,6 +397,7 @@ fi
 
 %{_bindir}/rpcclient
 %{_bindir}/smbcacls
+%{_bindir}/sharesec
 %{_bindir}/findsmb
 %{_bindir}/smbcquotas
 %{_bindir}/nmblookup
@@ -417,6 +419,7 @@ fi
 %{_mandir}/man1/nmblookup.1*
 %{_mandir}/man1/rpcclient.1*
 %{_mandir}/man1/smbcacls.1*
+%{_mandir}/man1/sharesec.1*
 %{_mandir}/man1/smbclient.1*
 %{_mandir}/man1/smbtar.1*
 %{_mandir}/man1/smbtree.1*
@@ -437,6 +440,7 @@ fi
 %attr(755,root,root) /%{_libarch}/libnss_winbind.so*
 %attr(755,root,root) /%{_libarch}/security/pam_winbind.so
 %attr(755,root,root) /%{_libarch}/security/pam_smbpass.so
+/usr/share/locale/de/LC_MESSAGES/pam_winbind.mo
 
 %{_includedir}/libsmbclient.h
 %{_libarchdir}/libsmbclient.*
@@ -464,6 +468,7 @@ fi
 %{_bindir}/ldbdel
 %{_bindir}/ldbedit
 %{_bindir}/ldbmodify
+%{_bindir}/ldbrename
 %{_bindir}/ldbsearch
 
 %{_mandir}/man1/profiles.1*
@@ -478,6 +483,7 @@ fi
 %{_mandir}/man1/ldbdel.1*
 %{_mandir}/man1/ldbedit.1*
 %{_mandir}/man1/ldbmodify.1*
+%{_mandir}/man1/ldbrename.1*
 %{_mandir}/man1/ldbsearch.1*
 
 %changelog
index 204003c53b1c5616bd2cb3a2695a2266f5233392..cbd49337ed7d5a9195d84a66c59c27ed62551ebf 100755 (executable)
@@ -4,7 +4,7 @@
 # information that is created by mkversion in advance.
 #
 # This is a standalone wrapper for update-pkginfo, which
-# is ususally called from release-scripts/create-tarball.
+# is usually called from release-scripts/create-tarball.
 # This allows for testing some aspects of packaging without
 # the need to go through all of create-tarball.
 #
index 8f31e408d514ea2da8583a75e8d8aa5722c26d5b..c6b7e11792604ed3f66d4206ad8d74d3241e8f41 100644 (file)
@@ -3,8 +3,9 @@ Introduction:
 This directory contains the source code of the pidl (Perl IDL) 
 compiler for Samba 4. 
 
-The main sources for pidl are available by Subversion on
-svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/pidl
+The main sources for pidl are available using Git as part of
+the combined Samba 3 / Samba 4 tree. Use:
+git clone git://git.samba.org/samba.git
 
 Pidl works by building a parse tree from a .pidl file (a simple 
 dump of it's internal parse tree) or a .idl file 
index 34aebc7f0fb112265df27386224f101ff13ec7b5..7ce9708e148d31a21fa1c3a6aa7fdd958e1d5923 100644 (file)
@@ -1256,7 +1256,7 @@ sub ParseStructPush($$$$)
 
        EnvSubstituteValue($env, $struct);
 
-       $self->DeclareArrayVariables($_) foreach (@{$struct->{ELEMENTS}});
+       $self->DeclareArrayVariablesNoZero($_, $env) foreach (@{$struct->{ELEMENTS}});
 
        $self->start_flags($struct, $ndr);
 
@@ -1481,6 +1481,24 @@ sub DeclareArrayVariables($$)
        }
 }
 
+sub DeclareArrayVariablesNoZero($$$)
+{
+       my ($self,$e,$env) = @_;
+
+       foreach my $l (@{$e->{LEVELS}}) {
+               next if has_fast_array($e,$l);
+               next if is_charset_array($e,$l);
+               if ($l->{TYPE} eq "ARRAY") {
+                   my $length = ParseExpr($l->{LENGTH_IS}, $env, $e->{ORIGINAL});
+                   if ($length eq "0") {
+                       warning($e->{ORIGINAL}, "pointless array cntr: 'cntr_$e->{NAME}_$l->{LEVEL_INDEX}': length=$length");
+                   } else {
+                       $self->pidl("uint32_t cntr_$e->{NAME}_$l->{LEVEL_INDEX};");
+                   }
+               }
+       }
+}
+
 sub DeclareMemCtxVariables($$)
 {
        my ($self,$e) = @_;
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 28b543783841c4054c457d1d4a1d0d61dc6e1c01..cf74182f27886cbabb3d584dffbbb5be66d6de0f 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.
@@ -366,7 +365,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
          lib/substitute.o lib/dbwrap_util.o \
          lib/ms_fnmatch.o lib/select.o lib/errmap_unix.o \
          lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \
-         ../lib/util/charset/iconv.o lib/pam_errors.o intl/lang_tdb.o \
+         lib/iconv.o lib/pam_errors.o intl/lang_tdb.o \
          lib/conn_tdb.o lib/adt_tree.o lib/gencache.o \
          lib/module.o lib/events.o @LIBTEVENT_OBJ0@ \
          lib/ldap_escape.o @CHARSET_STATIC@ \
@@ -449,7 +448,19 @@ LIBSAMBA_OBJ = $(LIBSMB_OBJ0) \
 LIBCLI_LDAP_MESSAGE_OBJ = ../libcli/ldap/ldap_message.o
 LIBCLI_LDAP_NDR_OBJ = ../libcli/ldap/ldap_ndr.o
 
-CLDAP_OBJ = libads/cldap.o $(LIBCLI_LDAP_MESSAGE_OBJ) $(LIBCLI_LDAP_NDR_OBJ)
+LIBTSOCKET_OBJ = ../lib/tsocket/tsocket.o \
+               ../lib/tsocket/tsocket_helpers.o \
+               ../lib/tsocket/tsocket_bsd.o \
+               ../lib/tsocket/tsocket_recvfrom.o \
+               ../lib/tsocket/tsocket_sendto.o \
+               ../lib/tsocket/tsocket_connect.o \
+               ../lib/tsocket/tsocket_writev.o \
+               ../lib/tsocket/tsocket_readv.o
+
+CLDAP_OBJ = libads/cldap.o \
+       ../libcli/cldap/cldap.o \
+       ../lib/util/idtree.o \
+       $(LIBCLI_LDAP_MESSAGE_OBJ) $(LIBCLI_LDAP_NDR_OBJ) $(LIBTSOCKET_OBJ)
 
 LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
             libsmb/clikrb5.o libsmb/clispnego.o ../lib/util/asn1.o \
@@ -457,7 +468,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) \
@@ -578,7 +589,7 @@ RPC_NTSVCS_OBJ = rpc_server/srv_ntsvcs_nt.o \
 
 RPC_DFS_OBJ =  ../librpc/gen_ndr/srv_dfs.o rpc_server/srv_dfs_nt.o
 
-RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o \
+RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss_nt.o \
                  ../librpc/gen_ndr/srv_spoolss.o
 
 RPC_EVENTLOG_OBJ = rpc_server/srv_eventlog_nt.o \
@@ -591,9 +602,7 @@ RPC_ECHO_OBJ = rpc_server/srv_echo_nt.o ../librpc/gen_ndr/srv_echo.o
 
 RPC_SERVER_OBJ = @RPC_STATIC@ $(RPC_PIPE_OBJ)
 
-RPC_PARSE_OBJ = $(RPC_PARSE_OBJ2) \
-                rpc_parse/parse_spoolss.o \
-               rpc_parse/parse_buffer.o
+RPC_PARSE_OBJ = $(RPC_PARSE_OBJ2)
 
 RPC_CLIENT_OBJ = rpc_client/cli_pipe.o rpc_client/rpc_transport_np.o \
        rpc_client/rpc_transport_sock.o rpc_client/rpc_transport_smbd.o
@@ -611,7 +620,7 @@ PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
                passdb/util_unixsids.o passdb/lookup_sid.o \
                passdb/login_cache.o @PDB_STATIC@ \
                lib/account_pol.o $(PRIVILEGES_OBJ) \
-               lib/util_nscd.o lib/winbind_util.o
+               lib/util_nscd.o lib/winbind_util.o $(SERVER_MUTEX_OBJ)
 
 DEVEL_HELP_WEIRD_OBJ = modules/weird.o
 CP850_OBJ = modules/CP850.o
@@ -667,6 +676,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
@@ -714,7 +724,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
               smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \
               smbd/blocking.o smbd/sec_ctx.o smbd/srvstr.o \
               smbd/vfs.o smbd/perfcount.o smbd/statcache.o smbd/seal.o \
-               smbd/posix_acls.o lib/sysacls.o $(SERVER_MUTEX_OBJ) \
+               smbd/posix_acls.o lib/sysacls.o \
               smbd/process.o smbd/service.o smbd/error.o \
               printing/printfsp.o lib/sysquotas.o lib/sysquotas_linux.o \
               lib/sysquotas_xfs.o lib/sysquotas_4A.o \
@@ -931,7 +941,7 @@ NET_OBJ = $(NET_OBJ1) \
          $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(LIBADDNS_OBJ0) \
          $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \
          $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
-         $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(SERVER_MUTEX_OBJ) \
+         $(SMBLDAP_OBJ) $(DCUTIL_OBJ) \
          $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(READLINE_OBJ) \
          $(LDB_OBJ) $(LIBGPO_OBJ) @BUILD_INIPARSER@ $(DISPLAY_SEC_OBJ) \
          $(REG_SMBCONF_OBJ) @LIBNETAPI_STATIC@ $(LIBNET_OBJ) \
@@ -1094,7 +1104,7 @@ WINBINDD_OBJ = \
                $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
                $(DCUTIL_OBJ) $(IDMAP_OBJ) $(NSS_INFO_OBJ) \
                $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) \
-               $(LIBADS_SERVER_OBJ) $(SERVER_MUTEX_OBJ) $(LDB_OBJ) \
+               $(LIBADS_SERVER_OBJ) $(LDB_OBJ) \
                $(TDB_VALIDATE_OBJ)
 
 WBINFO_OBJ = ../nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
@@ -1161,7 +1171,7 @@ NTLM_AUTH_OBJ1 = utils/ntlm_auth.o utils/ntlm_auth_diagnostics.o
 
 NTLM_AUTH_OBJ = ${NTLM_AUTH_OBJ1} $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \
                ../lib/util/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \
-               $(SERVER_MUTEX_OBJ) $(LIBADS_SERVER_OBJ) \
+               $(LIBADS_SERVER_OBJ) \
                $(PASSDB_OBJ) $(GROUPDB_OBJ) \
                $(SMBLDAP_OBJ) $(LIBNMB_OBJ) \
                $(LDB_OBJ) $(WBCOMMON_OBJ) @LIBWBCLIENT_STATIC@ \
@@ -1631,6 +1641,10 @@ bin/ldbrename: $(BINARY_PREREQS) $(LDBRENAME_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED
                $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
                $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
 
+bin/versiontest: $(BINARY_PREREQS) lib/version_test.o $(VERSION_OBJ)
+       @echo Linking $@
+       @$(CC) $(FLAGS) -o $@ $(VERSION_OBJ) lib/version_test.o
+
 
 #####################################################################
 #
@@ -2208,7 +2222,7 @@ installliblua:: installdirs liblua
        @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR)
        -$(INSTALLLIBCMD_SH) $(LIBLUA_SHARED_TARGET_SONAME) $(DESTDIR)$(LIBDIR)
        @rm -f $(DESTDIR)$(LIBDIR)/`basename $(LIBLUA_SHARED_TARGET)`
-       -if test -e $(LIBLUA_SHARED_TARGET_SONAME) ; then \
+       -if test -f $(LIBLUA_SHARED_TARGET_SONAME) ; then \
                ln -f -s `basename $(LIBLUA_SHARED_TARGET_SONAME)` \
                        $(DESTDIR)$(LIBDIR)/`basename $(LIBLUA_SHARED_TARGET)` ; \
        fi
@@ -2279,7 +2293,7 @@ bin/librpc_dssetup.@SHLIBEXT@: $(BINARY_PREREQS) $(RPC_DSSETUP_OBJ)
        @echo "Linking $@"
        @$(SHLD_MODULE) $(RPC_DSSETUP_OBJ)
 
-bin/librpc_spoolss2.@SHLIBEXT@: $(BINARY_PREREQS) $(RPC_SPOOLSS_OBJ)
+bin/librpc_spoolss.@SHLIBEXT@: $(BINARY_PREREQS) $(RPC_SPOOLSS_OBJ)
        @echo "Linking $@"
        @$(SHLD_MODULE) $(RPC_SPOOLSS_OBJ)
 
@@ -2567,6 +2581,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 aaa9e35d9689bdc8768db5b99f81aa90cb4cce78..a6f31bcf173b6382c33b4915d0b03efe2542f9c1 100644 (file)
@@ -103,6 +103,9 @@ struct cli_state *cli;
 static char CLI_DIRSEP_CHAR = '\\';
 static char CLI_DIRSEP_STR[] = { '\\', '\0' };
 
+/* Authentication for client connections. */
+struct user_auth_info *auth_info;
+
 /* Accessor functions for directory paths. */
 static char *fileselection;
 static const char *client_get_fileselection(void)
@@ -299,7 +302,7 @@ static int do_dskattr(void)
        char *targetpath = NULL;
        TALLOC_CTX *ctx = talloc_tos();
 
-       if ( !cli_resolve_path(ctx, "", cli, client_get_cur_dir(), &targetcli, &targetpath)) {
+       if ( !cli_resolve_path(ctx, "", auth_info, cli, client_get_cur_dir(), &targetcli, &targetpath)) {
                d_printf("Error in dskattr: %s\n", cli_errstr(cli));
                return 1;
        }
@@ -393,7 +396,7 @@ static int do_cd(const char *new_dir)
        new_cd = clean_name(ctx, new_cd);
        client_set_cur_dir(new_cd);
 
-       if ( !cli_resolve_path(ctx, "", cli, new_cd, &targetcli, &targetpath)) {
+       if ( !cli_resolve_path(ctx, "", auth_info, cli, new_cd, &targetcli, &targetpath)) {
                d_printf("cd %s: %s\n", new_cd, cli_errstr(cli));
                client_set_cur_dir(saved_dir);
                goto out;
@@ -819,7 +822,7 @@ void do_list(const char *mask,
 
                        /* check for dfs */
 
-                       if ( !cli_resolve_path(ctx, "", cli, head, &targetcli, &targetpath ) ) {
+                       if ( !cli_resolve_path(ctx, "", auth_info, cli, head, &targetcli, &targetpath ) ) {
                                d_printf("do_list: [%s] %s\n", head, cli_errstr(cli));
                                remove_do_list_queue_head();
                                continue;
@@ -852,7 +855,7 @@ void do_list(const char *mask,
                }
        } else {
                /* check for dfs */
-               if (cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetpath)) {
+               if (cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetpath)) {
                        if (cli_list(targetcli, targetpath, attribute, do_list_helper, NULL) == -1) {
                                d_printf("%s listing %s\n",
                                        cli_errstr(targetcli), targetpath);
@@ -1018,7 +1021,7 @@ static int do_get(const char *rname, const char *lname_in, bool reget)
                strlower_m(lname);
        }
 
-       if (!cli_resolve_path(ctx, "", cli, rname, &targetcli, &targetname ) ) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, rname, &targetcli, &targetname ) ) {
                d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli));
                return 1;
        }
@@ -1381,7 +1384,7 @@ static bool do_mkdir(const char *name)
        struct cli_state *targetcli;
        char *targetname = NULL;
 
-       if (!cli_resolve_path(ctx, "", cli, name, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, name, &targetcli, &targetname)) {
                d_printf("mkdir %s: %s\n", name, cli_errstr(cli));
                return false;
        }
@@ -1419,7 +1422,7 @@ static bool do_altname(const char *name)
 
 static int cmd_quit(void)
 {
-       cli_cm_shutdown();
+       cli_shutdown(cli);
        exit(0);
        /* NOTREACHED */
        return 0;
@@ -1464,7 +1467,7 @@ static int cmd_mkdir(void)
                        return 1;
                }
 
-               if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+               if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                        return 1;
                }
 
@@ -1625,7 +1628,7 @@ static int do_put(const char *rname, const char *lname, bool reput)
        struct push_state state;
        NTSTATUS status;
 
-       if (!cli_resolve_path(ctx, "", cli, rname, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, rname, &targetcli, &targetname)) {
                d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli));
                return 1;
        }
@@ -1714,7 +1717,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);
        }
 
@@ -2183,7 +2186,7 @@ static int cmd_wdel(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("cmd_wdel %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
@@ -2218,7 +2221,7 @@ static int cmd_open(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("open %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
@@ -2311,7 +2314,7 @@ static int cmd_posix_open(void)
        }
        mode = (mode_t)strtol(buf, (char **)NULL, 8);
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("posix_open %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
@@ -2359,7 +2362,7 @@ static int cmd_posix_mkdir(void)
        }
        mode = (mode_t)strtol(buf, (char **)NULL, 8);
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("posix_mkdir %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
@@ -2393,7 +2396,7 @@ static int cmd_posix_unlink(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("posix_unlink %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
@@ -2427,7 +2430,7 @@ static int cmd_posix_rmdir(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("posix_rmdir %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
@@ -2667,7 +2670,7 @@ static int cmd_rmdir(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("rmdir %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
@@ -2714,7 +2717,7 @@ static int cmd_link(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, oldname, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, oldname, &targetcli, &targetname)) {
                d_printf("link %s: %s\n", oldname, cli_errstr(cli));
                return 1;
        }
@@ -2765,7 +2768,7 @@ static int cmd_symlink(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, oldname, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, oldname, &targetcli, &targetname)) {
                d_printf("link %s: %s\n", oldname, cli_errstr(cli));
                return 1;
        }
@@ -2813,7 +2816,7 @@ static int cmd_chmod(void)
 
        mode = (mode_t)strtol(buf, NULL, 8);
 
-       if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) {
                d_printf("chmod %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -2966,7 +2969,7 @@ static int cmd_getfacl(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) {
                d_printf("stat %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -3132,7 +3135,7 @@ static int cmd_stat(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) {
                d_printf("stat %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -3233,7 +3236,7 @@ static int cmd_chown(void)
        if (!src) {
                return 1;
        }
-       if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname) ) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname) ) {
                d_printf("chown %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -3287,12 +3290,12 @@ static int cmd_rename(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetsrc)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetsrc)) {
                d_printf("rename %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, dest, &targetcli, &targetdest)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, dest, &targetcli, &targetdest)) {
                d_printf("rename %s: %s\n", dest, cli_errstr(cli));
                return 1;
        }
@@ -3362,7 +3365,7 @@ static int cmd_hardlink(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) {
                d_printf("hardlink %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -3815,7 +3818,7 @@ static int cmd_logon(void)
 
 static int cmd_list_connect(void)
 {
-       cli_cm_display();
+       cli_cm_display(cli);
        return 0;
 }
 
@@ -3829,7 +3832,7 @@ static int cmd_show_connect( void )
        struct cli_state *targetcli;
        char *targetpath;
 
-       if (!cli_resolve_path(ctx, "", cli, client_get_cur_dir(),
+       if (!cli_resolve_path(ctx, "", auth_info, cli, client_get_cur_dir(),
                                &targetcli, &targetpath ) ) {
                d_printf("showconnect %s: %s\n", cur_dir, cli_errstr(cli));
                return 1;
@@ -4051,7 +4054,8 @@ static int process_command_string(const char *cmd_in)
        if (!cli) {
                cli = cli_cm_open(talloc_tos(), NULL,
                                have_ip ? dest_ss_str : desthost,
-                               service, true, smb_encrypt,
+                               service, auth_info,
+                               true, smb_encrypt,
                                max_protocol, port, name_type);
                if (!cli) {
                        return 1;
@@ -4220,7 +4224,7 @@ static char **remote_completion(const char *text, int len)
                goto cleanup;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, dirmask, &targetcli, &targetpath)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, dirmask, &targetcli, &targetpath)) {
                goto cleanup;
        }
        if (cli_list(targetcli, targetpath, aDIR | aSYSTEM | aHIDDEN,
@@ -4517,7 +4521,7 @@ static int process(const char *base_directory)
 
        cli = cli_cm_open(talloc_tos(), NULL,
                        have_ip ? dest_ss_str : desthost,
-                       service, true, smb_encrypt,
+                       service, auth_info, true, smb_encrypt,
                        max_protocol, port, name_type);
        if (!cli) {
                return 1;
@@ -4526,7 +4530,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;
                }
        }
@@ -4537,7 +4541,7 @@ static int process(const char *base_directory)
                process_stdin();
        }
 
-       cli_cm_shutdown();
+       cli_shutdown(cli);
        return rc;
 }
 
@@ -4550,7 +4554,7 @@ static int do_host_query(const char *query_host)
        struct sockaddr_storage ss;
 
        cli = cli_cm_open(talloc_tos(), NULL,
-                       query_host, "IPC$", true, smb_encrypt,
+                       query_host, "IPC$", auth_info, true, smb_encrypt,
                        max_protocol, port, name_type);
        if (!cli)
                return 1;
@@ -4568,9 +4572,9 @@ 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,
+                               query_host, "IPC$", auth_info, true, smb_encrypt,
                                max_protocol, 139, name_type);
        }
 
@@ -4581,7 +4585,7 @@ static int do_host_query(const char *query_host)
 
        list_servers(lp_workgroup());
 
-       cli_cm_shutdown();
+       cli_shutdown(cli);
 
        return(0);
 }
@@ -4598,7 +4602,7 @@ static int do_tar_op(const char *base_directory)
        if (!cli) {
                cli = cli_cm_open(talloc_tos(), NULL,
                        have_ip ? dest_ss_str : desthost,
-                       service, true, smb_encrypt,
+                       service, auth_info, true, smb_encrypt,
                        max_protocol, port, name_type);
                if (!cli)
                        return 1;
@@ -4609,14 +4613,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);
 }
@@ -4625,7 +4629,7 @@ static int do_tar_op(const char *base_directory)
  Handle a message operation.
 ****************************************************************************/
 
-static int do_message_op(struct user_auth_info *auth_info)
+static int do_message_op(struct user_auth_info *a_info)
 {
        struct sockaddr_storage ss;
        struct nmb_name called, calling;
@@ -4663,12 +4667,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();
+       send_message(get_cmdline_auth_info_username(a_info));
+       cli_shutdown(cli);
 
        return 0;
 }
@@ -4714,7 +4718,6 @@ static int do_message_op(struct user_auth_info *auth_info)
                POPT_TABLEEND
        };
        TALLOC_CTX *frame = talloc_stackframe();
-       struct user_auth_info *auth_info;
 
        if (!client_set_cur_dir("\\")) {
                exit(ENOMEM);
@@ -4970,12 +4973,11 @@ static int do_message_op(struct user_auth_info *auth_info)
 
        poptFreeContext(pc);
 
-       /* Store the username and password for dfs support */
-
-       cli_cm_set_credentials(auth_info);
-
        DEBUG(3,("Client started (version %s).\n", samba_version_string()));
 
+       /* Ensure we have a password (or equivalent). */
+       set_cmdline_auth_info_getpass(auth_info);
+
        if (tar_type) {
                if (cmdstr)
                        process_command_string(cmdstr);
index 18edf037e26613eced1e46783dd730e638dd02e7..c9f3e87c4df2bd120f27afc878e0b9e7f2e5d66b 100644 (file)
@@ -1513,6 +1513,7 @@ int process_tar(void)
 
                                        if (strrchr_m(cliplist[i], '\\')) {
                                                char *p;
+                                               char saved_char;
                                                char *saved_dir = talloc_strdup(ctx,
                                                                        client_get_cur_dir());
                                                if (!saved_dir) {
@@ -1531,13 +1532,28 @@ int process_tar(void)
                                                if (!tarmac) {
                                                        return 1;
                                                }
+                                               /*
+                                                * Strip off the last \\xxx
+                                                * xxx element of tarmac to set
+                                                * it as current directory.
+                                                */
                                                p = strrchr_m(tarmac, '\\');
                                                if (!p) {
                                                        return 1;
                                                }
+                                               saved_char = p[1];
                                                p[1] = '\0';
+
                                                client_set_cur_dir(tarmac);
 
+                                               /*
+                                                * Restore the character we
+                                                * just replaced to
+                                                * put the pathname
+                                                * back as it was.
+                                                */
+                                               p[1] = saved_char;
+
                                                DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
                                                do_list(tarmac,attribute,do_tar, False, True);
 
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 d67feccb9b518a56a4c621991dc82b10195e7e0c..dc5850aba1d25e6a5938657fe131ecf97b441b46 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 test 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
@@ -266,7 +285,7 @@ if test "$ac_cv_prog_gnu_ld" = "yes"; then
         else
            AC_MSG_CHECKING(GNU ld release version)
            changequote(,)dnl
-           ac_cv_gnu_ld_vernr=`echo $ac_cv_gnu_ld_version | sed -n 's,^.*\([1-9][0-9]*\.[0-9][0-9]*\).*$,\1,p'`
+           ac_cv_gnu_ld_vernr=`echo $ac_cv_gnu_ld_version | sed -n 's,^.*[^0-9\.]\+\([1-9][0-9]*\.[0-9][0-9]*\).*$,\1,p'`
            ac_cv_gnu_ld_vernr_major=`echo $ac_cv_gnu_ld_vernr | cut -d '.' -f 1`
            ac_cv_gnu_ld_vernr_minor=`echo $ac_cv_gnu_ld_vernr | cut -d '.' -f 2`
            changequote([,])dnl
@@ -278,7 +297,7 @@ if test "$ac_cv_prog_gnu_ld" = "yes"; then
            if test "$ac_cv_gnu_ld_vernr_major" -lt 2 || test "$ac_cv_gnu_ld_vernr_minor" -lt 14; then
              ac_cv_gnu_ld_no_default_allow_shlib_undefined=yes
            fi
-           if test "$ac_cv_gnu_ld_vernr_major" -gt 2 || test "$ac_cv_gnu_ld_vernr_major"=2 && test "$ac_cv_gnu_ld_vernr_minor" -ge 12; then
+           if test "$ac_cv_gnu_ld_vernr_major" -gt 2 || test "$ac_cv_gnu_ld_vernr_major" = 2 && test "$ac_cv_gnu_ld_vernr_minor" -ge 12; then
              ac_cv_gnu_ld_version_script=yes
            fi
         fi
@@ -414,10 +433,10 @@ AC_SUBST(DYNEXP)
 
 dnl Add modules that have to be built by default here
 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"
+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_spoolss 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)
@@ -3261,6 +3277,9 @@ if test x"$with_ads_support" != x"no"; then
   ac_save_CPPFLAGS=$CPPFLAGS
   ac_save_LDFLAGS=$LDFLAGS
 
+  # remove needless evil rpath stuff as early as possible:
+  LIB_REMOVE_USR_LIB(KRB5_LIBS)
+  LIB_REMOVE_USR_LIB(KRB5_LDFLAGS)
   CFLAGS="$KRB5_CFLAGS $CFLAGS"
   CPPFLAGS="$KRB5_CPPFLAGS $CPPFLAGS"
   LDFLAGS="$KRB5_LDFLAGS $LDFLAGS"
@@ -4722,35 +4741,6 @@ SMB_LIBRARY(lua, 0)
 SMB_LIBRARY(addns, 0, no, [undefined API])
 
 
-#################################################
-# check to see if we should set the protected madvise flag,
-# which will keep smbd alive in low memory conditions
-AC_MSG_CHECKING(whether to protect smbd from being killed in low memory)
-AC_ARG_WITH(madvise-protect,
-[AS_HELP_STRING([--with-madvise-protect], [Include low memory madvise protection (default=no)])],
-[ case "$withval" in
-  yes)
-    AC_TRY_COMPILE([
-        #include <sys/mman.h>
-        ],[
-        int a = MADV_PROTECT;
-        ],
-        [samba_cv_madvise_protect=yes],
-        [samba_cv_madvise_protect=no])
-    if test x"$samba_cv_madvise_protect" = x"yes"; then
-        AC_MSG_RESULT(yes)
-        AC_DEFINE(WITH_MADVISE_PROTECTED,1,[Whether to include low memory protection support])
-    else
-        AC_MSG_ERROR(Low memory protection supporte requires availability of MADVISE_PROTECT flag.)
-    fi
-    ;;
-  *)
-    AC_MSG_RESULT(no)
-    ;;
-  esac ],
-  AC_MSG_RESULT(no)
-)
-
 #################################################
 # these tests are taken from the GNU fileutils package
 AC_CHECKING(how to get filesystem space usage)
@@ -6100,7 +6090,7 @@ do
 done
 
 dnl Always build these modules static
-MODULE_rpc_spoolss2=STATIC
+MODULE_rpc_spoolss=STATIC
 MODULE_rpc_srvsvc=STATIC
 MODULE_idmap_tdb=STATIC
 MODULE_idmap_passdb=STATIC
@@ -6144,7 +6134,7 @@ SMB_MODULE(rpc_ntsvcs, \$(RPC_NTSVCS_OBJ), "bin/librpc_ntsvcs.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_netlogon, \$(RPC_NETLOG_OBJ), "bin/librpc_NETLOGON.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_netdfs, \$(RPC_DFS_OBJ), "bin/librpc_netdfs.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_srvsvc, \$(RPC_SVC_OBJ), "bin/librpc_svcsvc.$SHLIBEXT", RPC)
-SMB_MODULE(rpc_spoolss2, \$(RPC_SPOOLSS_OBJ), "bin/librpc_spoolss2.$SHLIBEXT", RPC)
+SMB_MODULE(rpc_spoolss, \$(RPC_SPOOLSS_OBJ), "bin/librpc_spoolss.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_eventlog, \$(RPC_EVENTLOG_OBJ), "bin/librpc_eventlog.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_samr, \$(RPC_SAMR_OBJ), "bin/librpc_samr.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_rpcecho, \$(RPC_ECHO_OBJ), "bin/librpc_rpcecho.$SHLIBEXT", RPC)
@@ -6214,6 +6204,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)
@@ -6370,7 +6361,6 @@ AC_ZLIB([ZLIB_OBJS=""], [
 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)
index d62d1c05d2c00b36bafbf5c13753930f628723e0..320a90e66bf2c44861e095cdb4e17f7ba6d642fe 100644 (file)
@@ -104,7 +104,7 @@ struct rpc_cli_transport {
                                        uint32_t max_rdata_len,
                                        void *priv);
        /**
-        * Get the result from the read_send operation.
+        * Get the result from the trans_send operation.
         */
        NTSTATUS (*trans_recv)(struct async_req *req, TALLOC_CTX *mem_ctx,
                               uint8_t **prdata, uint32_t *prdata_len);
@@ -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 ca918b37df78e6b0221f8efc0afbb7c6923e3ca5..4bf4b5c7357037e125e097c8239c2167da24aad2 100644 (file)
@@ -584,10 +584,6 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx);
 #include "../lib/util/time.h"
 #include "../lib/util/asn1.h"
 
-/* And a little extension. Abort on type mismatch */
-#define talloc_get_type_abort(ptr, type) \
-       (type *)talloc_check_name_abort(ptr, #type)
-
 #include "ads.h"
 #include "ads_dns.h"
 #include "interfaces.h"
@@ -626,7 +622,6 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx);
 #include "ntdomain.h"
 #include "reg_objects.h"
 #include "reg_db.h"
-#include "rpc_spoolss.h"
 #include "rpc_perfcount.h"
 #include "rpc_perfcount_defs.h"
 #include "librpc/gen_ndr/notify.h"
index 166685c38015646509f8dde8c2906c7dc78cbbb2..0bfcd8fab781922e2e095403fb9d1cf59f479915 100644 (file)
@@ -74,7 +74,7 @@ struct _SMBCSRV {
        bool no_pathinfo;
        bool no_pathinfo2;
         bool no_nt_session;
-        POLICY_HND pol;
+        struct policy_handle pol;
 
        SMBCSRV *next, *prev;
        
@@ -181,6 +181,12 @@ struct SMBC_internal_data {
          */
         bool                                    case_sensitive;
 
+       /*
+        * Auth info needed for DFS traversal.
+        */
+
+       struct user_auth_info                   *auth_info;
+
         struct smbc_server_cache * server_cache;
 
         /* POSIX emulation functions */
index 43fd363b55486398492941218c5b31ffb5d7fff2..7dc60a8f03b645d1eb0872faa77ca4360080788a 100644 (file)
@@ -440,7 +440,7 @@ typedef struct _Printer{
                fstring localmachine;
                uint32 printerlocal;
                struct spoolss_NotifyOption *option;
-               POLICY_HND client_hnd;
+               struct policy_handle client_hnd;
                bool client_connected;
                uint32 change;
                /* are we in a FindNextPrinterChangeNotify() call? */
@@ -459,4 +459,20 @@ typedef struct _Printer{
        
 } Printer_entry;
 
+/*
+ * The printer attributes.
+ * I #defined all of them (grabbed form MSDN)
+ * I'm only using:
+ * ( SHARED | NETWORK | RAW_ONLY )
+ * RAW_ONLY _MUST_ be present otherwise NT will send an EMF file
+ */
+
+#define PRINTER_ATTRIBUTE_SAMBA                        (PRINTER_ATTRIBUTE_RAW_ONLY|\
+                                                PRINTER_ATTRIBUTE_SHARED|\
+                                                PRINTER_ATTRIBUTE_LOCAL)
+#define PRINTER_ATTRIBUTE_NOT_SAMBA            (PRINTER_ATTRIBUTE_NETWORK)
+
+#define DRIVER_ANY_VERSION             0xffffffff
+#define DRIVER_MAX_VERSION             4
+
 #endif /* NT_PRINTING_H_ */
index 0eff9bdbace72cdf9df955c7d1f2040801f0aa60..c95931b5d03dc36a3be7dc48298dbd7fedb9677b 100644 (file)
@@ -117,7 +117,7 @@ typedef struct _input_data {
 struct policy {
        struct policy *next, *prev;
 
-       POLICY_HND pol_hnd;
+       struct policy_handle pol_hnd;
 
        void *data_ptr;
 };
@@ -293,11 +293,4 @@ struct api_struct {
 
 /* end higher order functions */
 
-typedef struct {
-       uint32 size;
-       prs_struct prs;
-       uint32 struct_start;
-       uint32 string_at_end;
-} RPC_BUFFER;
-
 #endif /* _NT_DOMAIN_H */
index 93c1e3f0ab4e250bd674b79f390bbb4a664e1eae..9cbc6bd340ad4be1ad029795e207c317eeaaffbc 100644 (file)
@@ -186,7 +186,6 @@ enum pdb_search_type {
 };
 
 struct pdb_search {
-       TALLOC_CTX *mem_ctx;
        enum pdb_search_type type;
        struct samr_displayentry *cache;
        uint32 num_entries;
index bbd013a18f3c210beb4b735a5f550d1986366761..ae8378f28b44581771eae6331702bd9ec3fb299a 100644 (file)
@@ -53,6 +53,7 @@ struct user_auth_info {
        int signing_state;
        bool smb_encrypt;
        bool use_machine_account;
+       bool fallback_after_kerberos;
 };
 
 #endif /* _POPT_COMMON_H */
index e1eab8dc162ac8ba12b614ea1a093e1619b852b2..3d87f75c7b2a4bef70f82bdee36ebc9eadaadacf 100644 (file)
@@ -347,9 +347,6 @@ size_t convert_string(charset_t from, charset_t to,
 bool convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
                             void const *src, size_t srclen, void *dst,
                             size_t *converted_size, bool allow_bad_conv);
-bool convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
-                          void const *src, size_t srclen, void **dst,
-                          size_t *converted_size, bool allow_bad_conv);
 size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen);
 char *strdup_upper(const char *s);
 char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s);
@@ -1075,27 +1072,31 @@ const char *my_netbios_names(int i);
 bool set_netbios_aliases(const char **str_array);
 bool init_names(void);
 struct user_auth_info *user_auth_info_init(TALLOC_CTX *mem_ctx);
-const char *get_cmdline_auth_info_username(struct user_auth_info *auth_info);
+const char *get_cmdline_auth_info_username(const struct user_auth_info *auth_info);
 void set_cmdline_auth_info_username(struct user_auth_info *auth_info,
                                    const char *username);
 void set_cmdline_auth_info_password(struct user_auth_info *auth_info,
                                    const char *password);
-const char *get_cmdline_auth_info_password(struct user_auth_info *auth_info);
+const char *get_cmdline_auth_info_password(const struct user_auth_info *auth_info);
 bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info,
                                         const char *arg);
-int get_cmdline_auth_info_signing_state(struct user_auth_info *auth_info);
+int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info);
 void set_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info,
                                        bool b);
-bool get_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info);
+bool get_cmdline_auth_info_use_kerberos(const struct user_auth_info *auth_info);
+void set_cmdline_auth_info_fallback_after_kerberos(struct user_auth_info *auth_info,
+                                       bool b);
+bool get_cmdline_auth_info_fallback_after_kerberos(const struct user_auth_info *auth_info);
 void set_cmdline_auth_info_use_krb5_ticket(struct user_auth_info *auth_info);
 void set_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info);
 void set_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info);
-bool get_cmdline_auth_info_got_pass(struct user_auth_info *auth_info);
-bool get_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info);
-bool get_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info);
+bool get_cmdline_auth_info_got_pass(const struct user_auth_info *auth_info);
+bool get_cmdline_auth_info_smb_encrypt(const struct user_auth_info *auth_info);
+bool get_cmdline_auth_info_use_machine_account(const struct user_auth_info *auth_info);
 struct user_auth_info *get_cmdline_auth_info_copy(TALLOC_CTX *mem_ctx,
-                                                struct user_auth_info *info);
+                                                const struct user_auth_info *info);
 bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info *auth_info);
+void set_cmdline_auth_info_getpass(struct user_auth_info *auth_info);
 bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
                             gid_t **gids, size_t *num_gids);
 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf);
@@ -1173,7 +1174,6 @@ bool mask_match_search(const char *string, const char *pattern, bool is_case_sen
 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive);
 bool unix_wild_match(const char *pattern, const char *string);
 bool name_to_fqdn(fstring fqdn, const char *name);
-void *talloc_check_name_abort(const void *ptr, const char *name);
 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob);
 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options);
 pid_t procid_to_pid(const struct server_id *proc);
@@ -1209,7 +1209,7 @@ void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned coun
 void *talloc_zeronull(const void *context, size_t size, const char *name);
 NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
                                char **pbase, char **pstream);
-bool is_valid_policy_hnd(const POLICY_HND *hnd);
+bool is_valid_policy_hnd(const struct policy_handle *hnd);
 bool policy_hnd_equal(const struct policy_handle *hnd1,
                      const struct policy_handle *hnd2);
 const char *strip_hostname(const char *s);
@@ -1400,13 +1400,13 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
                                        uint16_t port,
                                        int timeout);
 NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd);
-struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
-                                            struct event_context *ev,
-                                            struct timeval wait_time,
-                                            const struct sockaddr_storage *pss,
-                                            uint16_t port,
-                                            int timeout);
-NTSTATUS open_socket_out_defer_recv(struct async_req *req, int *pfd);
+struct tevent_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
+                                             struct event_context *ev,
+                                             struct timeval wait_time,
+                                             const struct sockaddr_storage *pss,
+                                             uint16_t port,
+                                             int timeout);
+NTSTATUS open_socket_out_defer_recv(struct tevent_req *req, int *pfd);
 bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs,
                         int timeout, int *fd_index, int *fd);
 int open_udp_socket(const char *host, int port);
@@ -1557,7 +1557,6 @@ char *rpcstr_pull_unistr2_talloc(TALLOC_CTX *ctx, const UNISTR2 *src);
 int rpcstr_push(void *dest, const char *src, size_t dest_len, int flags);
 int rpcstr_push_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src);
 void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen);
-void unistr3_to_ascii(char *dest, const UNISTR3 *str, size_t maxlen);
 char *unistr2_to_ascii_talloc(TALLOC_CTX *ctx, const UNISTR2 *str);
 const char *unistr2_static(const UNISTR2 *str);
 smb_ucs2_t toupper_w(smb_ucs2_t val);
@@ -2359,27 +2358,17 @@ 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,
                                const char *share,
+                               const struct user_auth_info *auth_info,
                                bool show_hdr,
                                bool force_encrypt,
                                int max_protocol,
                                int port,
                                int name_type);
-void cli_cm_shutdown(void);
-void cli_cm_display(void);
-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);
-void cli_cm_set_signing_state(int state);
-void cli_cm_set_username(const char *username);
-void cli_cm_set_password(const char *newpass);
-void cli_cm_set_use_kerberos(void);
-void cli_cm_set_fallback_after_kerberos(void);
-void cli_cm_set_dest_ss(struct sockaddr_storage *pss);
+void cli_cm_display(const struct cli_state *c);
 bool cli_dfs_get_referral(TALLOC_CTX *ctx,
                        struct cli_state *cli,
                        const char *path,
@@ -2388,6 +2377,7 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx,
                        uint16 *consumed);
 bool cli_resolve_path(TALLOC_CTX *ctx,
                        const char *mountpt,
+                       const struct user_auth_info *dfs_auth_info,
                        struct cli_state *rootcli,
                        const char *path,
                        struct cli_state **targetcli,
@@ -2430,9 +2420,12 @@ 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);
-void cli_setup_signing_state(struct cli_state *cli, int signing_state);
+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);
 void cli_shutdown(struct cli_state *cli);
 void cli_sockopt(struct cli_state *cli, const char *options);
@@ -3160,11 +3153,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);
@@ -3210,7 +3198,7 @@ bool srv_oplock_set_signing(bool onoff);
 bool srv_check_sign_mac(const char *inbuf, bool must_be_ok);
 void srv_calculate_sign_mac(char *outbuf);
 void srv_defer_sign_response(uint16 mid);
-void srv_cancel_sign_response(uint16 mid);
+void srv_cancel_sign_response(uint16 mid, bool cancel);
 void srv_set_signing_negotiated(void);
 bool srv_is_signing_active(void);
 bool srv_is_signing_negotiated(void);
@@ -3415,11 +3403,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,
@@ -3485,9 +3478,9 @@ bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp);
 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp);
 NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close,
                                 uint32 dosmode);
-void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok);
-void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, UNIX_USER_TOKEN *tok);
-bool set_delete_on_close(files_struct *fsp, bool delete_on_close, UNIX_USER_TOKEN *tok);
+void set_delete_on_close_token(struct share_mode_lock *lck, const UNIX_USER_TOKEN *tok);
+void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, const UNIX_USER_TOKEN *tok);
+bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USER_TOKEN *tok);
 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time);
 bool set_write_time(struct file_id fileid, struct timespec write_time);
 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
@@ -4618,14 +4611,14 @@ bool pdb_sid_to_id(const DOM_SID *sid, union unid_t *id,
 bool pdb_rid_algorithm(void);
 bool pdb_new_rid(uint32 *rid);
 bool initialize_password_db(bool reload, struct event_context *event_ctx);
-struct pdb_search *pdb_search_init(enum pdb_search_type type);
-struct pdb_search *pdb_search_users(uint32 acct_flags);
-struct pdb_search *pdb_search_groups(void);
-struct pdb_search *pdb_search_aliases(const DOM_SID *sid);
+struct pdb_search *pdb_search_init(TALLOC_CTX *mem_ctx,
+                                  enum pdb_search_type type);
+struct pdb_search *pdb_search_users(TALLOC_CTX *mem_ctx, uint32 acct_flags);
+struct pdb_search *pdb_search_groups(TALLOC_CTX *mem_ctx);
+struct pdb_search *pdb_search_aliases(TALLOC_CTX *mem_ctx, const DOM_SID *sid);
 uint32 pdb_search_entries(struct pdb_search *search,
                          uint32 start_idx, uint32 max_entries,
                          struct samr_displayentry **result);
-void pdb_search_destroy(struct pdb_search *search);
 bool pdb_get_trusteddom_pw(const char *domain, char** pwd, DOM_SID *sid, 
                           time_t *pass_last_set_time);
 bool pdb_set_trusteddom_pw(const char* domain, const char* pwd,
@@ -4796,7 +4789,6 @@ bool nt_printing_init(struct messaging_context *msg_ctx);
 uint32 update_c_setprinter(bool initialize);
 uint32 get_c_setprinter(void);
 int get_builtin_ntforms(nt_forms_struct **list);
-bool get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form);
 bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form);
 int get_ntforms(nt_forms_struct **list);
 int write_ntforms(nt_forms_struct **list, int number);
@@ -4932,7 +4924,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, 
@@ -5178,13 +5170,13 @@ WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY **regkey,
 NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
                                TALLOC_CTX *mem_ctx,
                                bool sec_qos, uint32 des_access,
-                               POLICY_HND *pol);
+                               struct policy_handle *pol);
 NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
                                 TALLOC_CTX *mem_ctx, bool sec_qos,
-                                uint32 des_access, POLICY_HND *pol);
+                                uint32 des_access, struct policy_handle *pol);
 NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,
                                TALLOC_CTX *mem_ctx,
-                               POLICY_HND *pol,
+                               struct policy_handle *pol,
                                int num_sids,
                                const DOM_SID *sids,
                                char ***pdomains,
@@ -5192,7 +5184,7 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,
                                enum lsa_SidType **ptypes);
 NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,
                                 TALLOC_CTX *mem_ctx,
-                                POLICY_HND *pol, int num_names,
+                                struct policy_handle *pol, int num_names,
                                 const char **names,
                                 const char ***dom_names,
                                 int level,
@@ -5406,7 +5398,7 @@ NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd,
 
 NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                          uint32 reg_type, uint32 access_mask,
-                         POLICY_HND *reg_hnd);
+                         struct policy_handle *reg_hnd);
 
 /* The following definitions come from rpc_client/cli_samr.c  */
 
@@ -5439,7 +5431,7 @@ void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
 NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli,
                                  TALLOC_CTX *mem_ctx,
                                  uint32_t access_mask,
-                                 POLICY_HND *connect_pol);
+                                 struct policy_handle *connect_pol);
 
 /* The following definitions come from rpc_client/cli_spoolss.c  */
 
@@ -5475,43 +5467,100 @@ WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli,
                             uint32_t level,
                             uint32_t offered,
                             union spoolss_JobInfo *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_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                             uint32 level, uint32 *num_ports, PORT_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_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                            POLICY_HND *handle, int level, uint32 *num_forms,
-                            FORM_1 **forms);
-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_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                 POLICY_HND *hnd, const char *valuename, 
-                                 REGISTRY_VALUE *value);
-WERROR rpccli_spoolss_setprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                 POLICY_HND *hnd, REGISTRY_VALUE *value);
-WERROR rpccli_spoolss_enumprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                  POLICY_HND *hnd, uint32 ndx,
-                                  uint32 value_offered, uint32 data_offered,
-                                  uint32 *value_needed, uint32 *data_needed,
-                                  REGISTRY_VALUE *value);
-WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                    POLICY_HND *hnd, const char *keyname, 
-                                    REGVAL_CTR *ctr);
-WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                 POLICY_HND *hnd, const char *keyname,
-                                 uint16 **keylist, uint32 *len);
+WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli,
+                               TALLOC_CTX *mem_ctx,
+                               struct policy_handle *handle,
+                               uint32_t level,
+                               uint32_t offered,
+                               uint32_t *count,
+                               union spoolss_FormInfo **info);
+WERROR rpccli_spoolss_enumprintprocessors(struct rpc_pipe_client *cli,
+                                         TALLOC_CTX *mem_ctx,
+                                         const char *servername,
+                                         const char *environment,
+                                         uint32_t level,
+                                         uint32_t offered,
+                                         uint32_t *count,
+                                         union spoolss_PrintProcessorInfo **info);
+WERROR rpccli_spoolss_enumprintprocessordatatypes(struct rpc_pipe_client *cli,
+                                                 TALLOC_CTX *mem_ctx,
+                                                 const char *servername,
+                                                 const char *print_processor_name,
+                                                 uint32_t level,
+                                                 uint32_t offered,
+                                                 uint32_t *count,
+                                                 union spoolss_PrintProcDataTypesInfo **info);
+WERROR rpccli_spoolss_enumports(struct rpc_pipe_client *cli,
+                               TALLOC_CTX *mem_ctx,
+                               const char *servername,
+                               uint32_t level,
+                               uint32_t offered,
+                               uint32_t *count,
+                               union spoolss_PortInfo **info);
+WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli,
+                                  TALLOC_CTX *mem_ctx,
+                                  const char *servername,
+                                  uint32_t level,
+                                  uint32_t offered,
+                                  uint32_t *count,
+                                  union spoolss_MonitorInfo **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);
+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,
+                                    struct policy_handle *handle,
+                                    const char *value_name,
+                                    uint32_t offered,
+                                    enum winreg_Type *type,
+                                    union spoolss_PrinterData *data);
+WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct policy_handle *handle,
+                                    const char *key_name,
+                                    const char ***key_buffer,
+                                    uint32_t offered);
+WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct policy_handle *handle,
+                                       const char *key_name,
+                                       uint32_t offered,
+                                       uint32_t *count,
+                                       struct spoolss_PrinterEnumValues **info);
 
 /* The following definitions come from rpc_client/init_spoolss.c  */
 
 bool init_systemtime(struct spoolss_Time *r,
                     struct tm *unixtime);
+WERROR pull_spoolss_PrinterData(TALLOC_CTX *mem_ctx,
+                               const DATA_BLOB *blob,
+                               union spoolss_PrinterData *data,
+                               enum winreg_Type type);
+WERROR push_spoolss_PrinterData(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
+                               enum winreg_Type type,
+                               union spoolss_PrinterData *data);
 
 /* The following definitions come from rpc_client/init_lsa.c  */
 
@@ -5624,44 +5673,16 @@ NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli,
                        const struct ndr_interface_table *table,
                        uint32 opnum, void *r);
 
-/* The following definitions come from rpc_parse/parse_buffer.c  */
-
-bool rpcbuf_init(RPC_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx);
-bool prs_rpcbuffer(const char *desc, prs_struct *ps, int depth, RPC_BUFFER *buffer);
-bool prs_rpcbuffer_p(const char *desc, prs_struct *ps, int depth, RPC_BUFFER **buffer);
-bool rpcbuf_alloc_size(RPC_BUFFER *buffer, uint32 buffer_size);
-void rpcbuf_move(RPC_BUFFER *src, RPC_BUFFER **dest);
-uint32 rpcbuf_get_size(RPC_BUFFER *buffer);
-bool smb_io_relstr(const char *desc, RPC_BUFFER *buffer, int depth, UNISTR *string);
-bool smb_io_relarraystr(const char *desc, RPC_BUFFER *buffer, int depth, uint16 **string);
-bool smb_io_relsecdesc(const char *desc, RPC_BUFFER *buffer, int depth, SEC_DESC **secdesc);
-uint32 size_of_relative_string(UNISTR *string);
-
 /* The following definitions come from rpc_parse/parse_misc.c  */
 
 bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth);
-bool smb_io_nttime(const char *desc, prs_struct *ps, int depth, NTTIME *nttime);
+bool smb_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime);
+bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime);
 bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth);
 bool smb_io_uuid(const char *desc, struct GUID *uuid, 
                 prs_struct *ps, int depth);
 void init_unistr(UNISTR *str, const char *buf);
-bool smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth);
-bool smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth);
-void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf);
-void copy_unistr2(UNISTR2 *str, const UNISTR2 *from);
 void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags);
-void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf);
-void init_unistr2_from_unistr(TALLOC_CTX *ctx, UNISTR2 *to, const UNISTR *from);
-void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob) ;
-bool prs_io_unistr2_p(const char *desc, prs_struct *ps, int depth, UNISTR2 **uni2);
-bool prs_io_unistr2(const char *desc, prs_struct *ps, int depth, UNISTR2 *uni2 );
-bool smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth);
-bool smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth);
-void init_unistr3(UNISTR3 *str, const char *buf);
-bool smb_io_unistr3(const char *desc, UNISTR3 *name, prs_struct *ps, int depth);
-bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64);
-uint32 str_len_uni(UNISTR *source);
-bool policy_handle_is_valid(const POLICY_HND *hnd);
 
 /* The following definitions come from rpc_parse/parse_prs.c  */
 
@@ -5709,6 +5730,7 @@ bool prs_pointer( const char *name, prs_struct *ps, int depth,
 bool prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16);
 bool prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32);
 bool prs_int32(const char *name, prs_struct *ps, int depth, int32 *data32);
+bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64);
 bool prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status);
 bool prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *status);
 bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status);
@@ -5716,9 +5738,7 @@ bool prs_uint8s(bool charmode, const char *name, prs_struct *ps, int depth, uint
 bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
 bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
 bool prs_uint32s(bool charmode, const char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
-bool prs_buffer5(bool charmode, const char *name, prs_struct *ps, int depth, BUFFER5 *str);
 bool prs_unistr2(bool charmode, const char *name, prs_struct *ps, int depth, UNISTR2 *str);
-bool prs_unistr3(bool charmode, const char *name, UNISTR3 *str, prs_struct *ps, int depth);
 bool prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str);
 bool prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_buf_size);
 bool prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str);
@@ -5788,140 +5808,6 @@ bool smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len,
 bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth);
 bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth);
 
-/* The following definitions come from rpc_parse/parse_spoolss.c  */
-
-bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime);
-bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime);
-bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode);
-bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
-                                  const POLICY_HND *handle,
-                                  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_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth);
-bool smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *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);
-bool smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth);
-bool smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth);
-bool smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth);
-bool smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth);
-bool smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth);
-bool smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth);
-bool smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_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_form_1(FORM_1 *info);
-uint32 spoolss_size_port_info_1(PORT_INFO_1 *info);
-uint32 spoolss_size_port_info_2(PORT_INFO_2 *info);
-uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info);
-uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info);
-uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p);
-uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info);
-uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info);
-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 make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
-                               fstring 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 spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth);
-bool spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth);
-bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *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_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth);
-bool spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth);
-bool spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth);
-bool spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth);
-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);
-bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
-               const POLICY_HND *hnd,
-               uint32 idx, uint32 valuelen, uint32 datalen);
-bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
-                                     const POLICY_HND *hnd, const char *key,
-                                     uint32 size);
-bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *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);
-bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth);
-bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth);
-bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
-                             uint32 level, RPC_BUFFER *buffer,
-                             uint32 offered);
-
 /* The following definitions come from rpc_server/srv_eventlog_lib.c  */
 
 TDB_CONTEXT *elog_init_tdb( char *tdbfilename );
@@ -5959,9 +5845,9 @@ NTSTATUS evlog_tdb_entry_to_evt_entry(TALLOC_CTX *mem_ctx,
 
 bool init_pipe_handle_list(pipes_struct *p,
                           const struct ndr_syntax_id *syntax);
-bool create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void *data_ptr);
-bool find_policy_by_hnd(pipes_struct *p, POLICY_HND *hnd, void **data_p);
-bool close_policy_hnd(pipes_struct *p, POLICY_HND *hnd);
+bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_ptr);
+bool find_policy_by_hnd(pipes_struct *p, struct policy_handle *hnd, void **data_p);
+bool close_policy_hnd(pipes_struct *p, struct policy_handle *hnd);
 void close_policy_by_pipe(pipes_struct *p);
 bool pipe_access_check(pipes_struct *p);
 
@@ -6000,14 +5886,14 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
                 const char *client_address,
                 struct auth_serversupplied_info *server_info,
                 struct fake_file_handle **phandle);
-struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+                                struct fake_file_handle *handle,
+                                const uint8_t *data, size_t len);
+NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten);
+struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
                                struct fake_file_handle *handle,
-                               const uint8_t *data, size_t len);
-NTSTATUS np_write_recv(struct async_req *req, ssize_t *nwritten);
-struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
-                              struct fake_file_handle *handle,
-                              uint8_t *data, size_t len);
-NTSTATUS np_read_recv(struct async_req *req, ssize_t *nread,
+                               uint8_t *data, size_t len);
+NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
                      bool *is_data_outstanding);
 
 /* The following definitions come from rpc_server/srv_samr_util.c  */
@@ -6022,11 +5908,6 @@ void copy_id23_to_sam_passwd(struct samu *to,
 void copy_id25_to_sam_passwd(struct samu *to,
                             struct samr_UserInfo25 *from);
 
-/* The following definitions come from rpc_server/srv_spoolss.c  */
-
-void spoolss2_get_pipe_fns( struct api_struct **fns, int *n_fns );
-NTSTATUS rpc_spoolss2_init(void);
-
 /* The following definitions come from rpc_server/srv_spoolss_nt.c  */
 
 WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename );
@@ -6041,11 +5922,11 @@ void reset_all_printerdata(struct messaging_context *msg,
                           uint32_t msg_type,
                           struct server_id server_id,
                           DATA_BLOB *data);
-bool convert_devicemode(const char *printername, const DEVICEMODE *devmode,
-                               NT_DEVICEMODE **pp_nt_devmode);
+bool convert_devicemode(const char *printername,
+                       const struct spoolss_DeviceMode *devmode,
+                       NT_DEVICEMODE **pp_nt_devmode);
 WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
                                   uint32 type, uint8 *data, int real_len  );
-WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u);
 void spoolss_notify_server_name(int snum,
                                       struct spoolss_Notify *data,
                                       print_queue_struct *queue,
@@ -6113,27 +5994,13 @@ void spoolss_notify_cjobs(int snum,
                                 TALLOC_CTX *mem_ctx);
 void construct_info_data(struct spoolss_Notify *info_data,
                         enum spoolss_NotifyType type,
-                        enum spoolss_Field field,
+                        uint16_t 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(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 _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u);
 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines );
-WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u);
-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_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u);
-WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u);
-WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *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);
 
 /* The following definitions come from rpc_server/srv_srvsvc_nt.c  */
 
@@ -6724,6 +6591,8 @@ void msg_file_was_renamed(struct messaging_context *msg,
 struct case_semantics_state;
 struct case_semantics_state *set_posix_case_semantics(TALLOC_CTX *mem_ctx,
                                                      connection_struct *conn);
+NTSTATUS open_streams_for_delete(connection_struct *conn,
+                                const char *fname);
 NTSTATUS create_file_default(connection_struct *conn,
                             struct smb_request *req,
                             uint16_t root_dir_fid,
index afa18899caa77cc62571337497cfcc52c3c59a1b..84ac8b17d4b0d1ddcbe2d8556952f1e5b5eb4b51 100644 (file)
 
 #define prs_init_empty( _ps_, _ctx_, _io_ ) (void) prs_init((_ps_), 0, (_ctx_), (_io_))
 
-/* macro to expand cookie-cutter code in cli_xxx() using rpc_api_pipe_req() */
-
-#define CLI_DO_RPC_WERR( pcli, ctx, interface, opnum, q_in, r_out, \
-                             q_ps, r_ps, q_io_fn, r_io_fn, default_error ) \
-{\
-       SMB_ASSERT(ndr_syntax_id_equal(&pcli->abstract_syntax, interface)); \
-       if (!prs_init( &q_ps, RPC_MAX_PDU_FRAG_LEN, ctx, MARSHALL )) { \
-               return WERR_NOMEM;\
-       }\
-       if ( q_io_fn("", &q_in, &q_ps, 0) ) {\
-               NTSTATUS _smb_pipe_stat_ = rpc_api_pipe_req(ctx, pcli, opnum, &q_ps, &r_ps); \
-               if (!NT_STATUS_IS_OK(_smb_pipe_stat_)) {\
-                       prs_mem_free( &q_ps );\
-                       prs_mem_free( &r_ps );\
-                       return ntstatus_to_werror(_smb_pipe_stat_);\
-               }\
-               if (!r_io_fn("", &r_out, &r_ps, 0)) {\
-                       prs_mem_free( &q_ps );\
-                       prs_mem_free( &r_ps );\
-                       return default_error;\
-               }\
-       } else {\
-               prs_mem_free( &q_ps );\
-               prs_mem_free( &r_ps );\
-               return default_error;\
-       }\
-       prs_mem_free( &q_ps );\
-       prs_mem_free( &r_ps );\
-}
-
 #endif /* _RPC_CLIENT_H */
index b63f0eac5e39059e579c61ecd8cfde629fe417be..580b14f1d810ad9a50e21b658d7b119b1474a15e 100644 (file)
@@ -159,8 +159,6 @@ enum schannel_direction {
 /* RPC_IFACE */
 typedef struct ndr_syntax_id RPC_IFACE;
 
-extern const struct ndr_syntax_id syntax_spoolss;
-
 #define RPC_IFACE_LEN (UUID_SIZE + 4)
 
 /* RPC_HDR - dce rpc header */
index 1e9d43bfa06424a1f4c86f1432102b868c1f1bf2..797e1926db34d9433cf6dead0ed2bee21203d292 100644 (file)
@@ -90,8 +90,6 @@ enum unistr2_term_codes { UNI_FLAGS_NONE = 0, UNI_STR_TERMINATE = 1, UNI_MAXLEN_
 /********************************************************************** 
  * RPC policy handle used pretty much everywhere
  **********************************************************************/
-typedef struct policy_handle POLICY_HND;
 
 #define OUR_HANDLE(hnd) (((hnd)==NULL) ? "NULL" :\
        ( IVAL((hnd)->uuid.node,2) == (uint32)sys_getpid() ? "OURS" : \
@@ -99,17 +97,6 @@ typedef struct policy_handle POLICY_HND;
                ((unsigned int)sys_getpid() )
 
 
-/********************************************************************** 
- * Buffers use by spoolss (i might be able to replace it with
- * an RPC_DATA_BLOB)
- **********************************************************************/
-
-typedef struct {
-       uint32 buf_len;
-       uint16 *buffer; /* data */
-} BUFFER5;
-
-
 /********************************************************************** 
  * UNICODE string variations
  **********************************************************************/
@@ -130,12 +117,23 @@ typedef struct {          /* UNISTR2 - unicode string size (in
                                  should include the NULL character */
 } UNISTR2;
 
-/* i think this is the same as a BUFFER5 used in the spoolss code --jerry */
-/* not sure about how the termination matches between the uint16 buffers thought */
-
-typedef struct {               /* UNISTR3 - XXXX not sure about this structure */
-       uint32 uni_str_len;
-       UNISTR str;
-} UNISTR3;
+/*
+ * I'm really wondering how many different time formats
+ * I will have to cope with
+ *
+ * JFM, 09/13/98 In a mad mood ;-(
+*/
+typedef struct systemtime
+{
+       uint16 year;
+       uint16 month;
+       uint16 dayofweek;
+       uint16 day;
+       uint16 hour;
+       uint16 minute;
+       uint16 second;
+       uint16 milliseconds;
+}
+SYSTEMTIME;
 
 #endif /* _RPC_MISC_H */
diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h
deleted file mode 100644 (file)
index 798bbf9..0000000
+++ /dev/null
@@ -1,1038 +0,0 @@
-/* 
-   Unix SMB/Netbios implementation.
-
-   Copyright (C) Andrew Tridgell              1992-2000,
-   Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
-   Copyright (C) Jean Francois Micouleau      1998-2000.
-   Copyright (C) Gerald Carter                2001-2006.
-   
-   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 "librpc/gen_ndr/spoolss.h"
-
-#ifndef _RPC_SPOOLSS_H         /* _RPC_SPOOLSS_H */
-#define _RPC_SPOOLSS_H
-
-/* spoolss pipe: this are the calls which are not implemented ...
-#define SPOOLSS_GETPRINTERDRIVER                       0x0b
-#define SPOOLSS_READPRINTER                            0x16
-#define SPOOLSS_WAITFORPRINTERCHANGE                   0x1c
-#define SPOOLSS_ADDPORT                                        0x25
-#define SPOOLSS_CONFIGUREPORT                          0x26
-#define SPOOLSS_DELETEPORT                             0x27
-#define SPOOLSS_CREATEPRINTERIC                                0x28
-#define SPOOLSS_PLAYGDISCRIPTONPRINTERIC               0x29
-#define SPOOLSS_DELETEPRINTERIC                                0x2a
-#define SPOOLSS_ADDPRINTERCONNECTION                   0x2b
-#define SPOOLSS_DELETEPRINTERCONNECTION                        0x2c
-#define SPOOLSS_PRINTERMESSAGEBOX                      0x2d
-#define SPOOLSS_ADDMONITOR                             0x2e
-#define SPOOLSS_DELETEMONITOR                          0x2f
-#define SPOOLSS_DELETEPRINTPROCESSOR                   0x30
-#define SPOOLSS_ADDPRINTPROVIDOR                       0x31
-#define SPOOLSS_DELETEPRINTPROVIDOR                    0x32
-#define SPOOLSS_FINDFIRSTPRINTERCHANGENOTIFICATION     0x36
-#define SPOOLSS_FINDNEXTPRINTERCHANGENOTIFICATION      0x37
-#define SPOOLSS_ROUTERFINDFIRSTPRINTERNOTIFICATIONOLD  0x39
-#define SPOOLSS_ADDPORTEX                              0x3d
-#define SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFICATION0x3e
-#define SPOOLSS_SPOOLERINIT                            0x3f
-#define SPOOLSS_RESETPRINTEREX                         0x40
-*/
-
-/* those are implemented */
-#define SPOOLSS_ENUMPRINTERS                           0x00
-#define SPOOLSS_OPENPRINTER                            0x01
-#define SPOOLSS_SETJOB                                 0x02
-#define SPOOLSS_GETJOB                                 0x03
-#define SPOOLSS_ENUMJOBS                               0x04
-#define SPOOLSS_ADDPRINTER                             0x05
-#define SPOOLSS_DELETEPRINTER                          0x06
-#define SPOOLSS_SETPRINTER                             0x07
-#define SPOOLSS_GETPRINTER                             0x08
-#define SPOOLSS_ADDPRINTERDRIVER                       0x09
-#define SPOOLSS_ENUMPRINTERDRIVERS                     0x0a
-#define SPOOLSS_GETPRINTERDRIVERDIRECTORY              0x0c
-#define SPOOLSS_DELETEPRINTERDRIVER                    0x0d
-#define SPOOLSS_ADDPRINTPROCESSOR                      0x0e
-#define SPOOLSS_ENUMPRINTPROCESSORS                    0x0f
-#define SPOOLSS_GETPRINTPROCESSORDIRECTORY             0x10
-#define SPOOLSS_STARTDOCPRINTER                                0x11
-#define SPOOLSS_STARTPAGEPRINTER                       0x12
-#define SPOOLSS_WRITEPRINTER                           0x13
-#define SPOOLSS_ENDPAGEPRINTER                         0x14
-#define SPOOLSS_ABORTPRINTER                           0x15
-#define SPOOLSS_ENDDOCPRINTER                          0x17
-#define SPOOLSS_ADDJOB                                 0x18
-#define SPOOLSS_SCHEDULEJOB                            0x19
-#define SPOOLSS_GETPRINTERDATA                         0x1a
-#define SPOOLSS_SETPRINTERDATA                         0x1b
-#define SPOOLSS_CLOSEPRINTER                           0x1d
-#define SPOOLSS_ADDFORM                                        0x1e
-#define SPOOLSS_DELETEFORM                             0x1f
-#define SPOOLSS_GETFORM                                        0x20
-#define SPOOLSS_SETFORM                                        0x21
-#define SPOOLSS_ENUMFORMS                              0x22
-#define SPOOLSS_ENUMPORTS                              0x23
-#define SPOOLSS_ENUMMONITORS                           0x24
-#define SPOOLSS_ENUMPRINTPROCDATATYPES                 0x33
-#define SPOOLSS_RESETPRINTER                           0x34
-#define SPOOLSS_GETPRINTERDRIVER2                      0x35
-#define SPOOLSS_FCPN                                   0x38    /* FindClosePrinterNotify */
-#define SPOOLSS_REPLYOPENPRINTER                       0x3a
-#define SPOOLSS_ROUTERREPLYPRINTER                     0x3b
-#define SPOOLSS_REPLYCLOSEPRINTER                      0x3c
-#define SPOOLSS_RFFPCNEX                               0x41    /* RemoteFindFirstPrinterChangeNotifyEx */
-#define SPOOLSS_RRPCN                                  0x42    /* RouteRefreshPrinterChangeNotification */
-#define SPOOLSS_RFNPCNEX                               0x43    /* RemoteFindNextPrinterChangeNotifyEx */
-#define SPOOLSS_OPENPRINTEREX                          0x45
-#define SPOOLSS_ADDPRINTEREX                           0x46
-#define SPOOLSS_ENUMPRINTERDATA                                0x48
-#define SPOOLSS_DELETEPRINTERDATA                      0x49
-#define SPOOLSS_SETPRINTERDATAEX                       0x4d
-#define SPOOLSS_GETPRINTERDATAEX                       0x4e
-#define SPOOLSS_ENUMPRINTERDATAEX                      0x4f
-#define SPOOLSS_ENUMPRINTERKEY                         0x50
-#define SPOOLSS_DELETEPRINTERDATAEX                    0x51
-#define SPOOLSS_DELETEPRINTERKEY                       0x52
-#define SPOOLSS_DELETEPRINTERDRIVEREX                  0x54
-#define SPOOLSS_XCVDATAPORT                            0x58
-#define SPOOLSS_ADDPRINTERDRIVEREX                     0x59
-
-/* 
- * Special strings for the OpenPrinter() call.  See the MSDN DDK
- * docs on the XcvDataPort() for more details.
- */
-
-#define SPL_LOCAL_PORT            "Local Port"
-#define SPL_TCPIP_PORT            "Standard TCP/IP Port"
-#define SPL_XCV_MONITOR_LOCALMON  ",XcvMonitor Local Port"
-#define SPL_XCV_MONITOR_TCPMON    ",XcvMonitor Standard TCP/IP Port"
-
-
-#define PRINTER_STATUS_OK               0x00000000
-
-/* Notify field types */
-
-#define PRINTER_NOTIFY_TYPE 0x00
-#define JOB_NOTIFY_TYPE     0x01
-
-#define PRINTER_NOTIFY_SERVER_NAME             0x00
-#define PRINTER_NOTIFY_PRINTER_NAME            0x01
-#define PRINTER_NOTIFY_SHARE_NAME              0x02
-#define PRINTER_NOTIFY_PORT_NAME               0x03
-#define PRINTER_NOTIFY_DRIVER_NAME             0x04
-#define PRINTER_NOTIFY_COMMENT                 0x05
-#define PRINTER_NOTIFY_LOCATION                        0x06
-#define PRINTER_NOTIFY_DEVMODE                 0x07
-#define PRINTER_NOTIFY_SEPFILE                 0x08
-#define PRINTER_NOTIFY_PRINT_PROCESSOR         0x09
-#define PRINTER_NOTIFY_PARAMETERS              0x0A
-#define PRINTER_NOTIFY_DATATYPE                        0x0B
-#define PRINTER_NOTIFY_SECURITY_DESCRIPTOR     0x0C
-#define PRINTER_NOTIFY_ATTRIBUTES              0x0D
-#define PRINTER_NOTIFY_PRIORITY                        0x0E
-#define PRINTER_NOTIFY_DEFAULT_PRIORITY                0x0F
-#define PRINTER_NOTIFY_START_TIME              0x10
-#define PRINTER_NOTIFY_UNTIL_TIME              0x11
-#define PRINTER_NOTIFY_STATUS                  0x12
-#define PRINTER_NOTIFY_STATUS_STRING           0x13
-#define PRINTER_NOTIFY_CJOBS                   0x14
-#define PRINTER_NOTIFY_AVERAGE_PPM             0x15
-#define PRINTER_NOTIFY_TOTAL_PAGES             0x16
-#define PRINTER_NOTIFY_PAGES_PRINTED           0x17
-#define PRINTER_NOTIFY_TOTAL_BYTES             0x18
-#define PRINTER_NOTIFY_BYTES_PRINTED           0x19
-
-#define JOB_NOTIFY_PRINTER_NAME                        0x00
-#define JOB_NOTIFY_MACHINE_NAME                        0x01
-#define JOB_NOTIFY_PORT_NAME                   0x02
-#define JOB_NOTIFY_USER_NAME                   0x03
-#define JOB_NOTIFY_NOTIFY_NAME                 0x04
-#define JOB_NOTIFY_DATATYPE                    0x05
-#define JOB_NOTIFY_PRINT_PROCESSOR             0x06
-#define JOB_NOTIFY_PARAMETERS                  0x07
-#define JOB_NOTIFY_DRIVER_NAME                 0x08
-#define JOB_NOTIFY_DEVMODE                     0x09
-#define JOB_NOTIFY_STATUS                      0x0A
-#define JOB_NOTIFY_STATUS_STRING               0x0B
-#define JOB_NOTIFY_SECURITY_DESCRIPTOR         0x0C
-#define JOB_NOTIFY_DOCUMENT                    0x0D
-#define JOB_NOTIFY_PRIORITY                    0x0E
-#define JOB_NOTIFY_POSITION                    0x0F
-#define JOB_NOTIFY_SUBMITTED                   0x10
-#define JOB_NOTIFY_START_TIME                  0x11
-#define JOB_NOTIFY_UNTIL_TIME                  0x12
-#define JOB_NOTIFY_TIME                                0x13
-#define JOB_NOTIFY_TOTAL_PAGES                 0x14
-#define JOB_NOTIFY_PAGES_PRINTED               0x15
-#define JOB_NOTIFY_TOTAL_BYTES                 0x16
-#define JOB_NOTIFY_BYTES_PRINTED               0x17
-
-/*
- * Set of macros for flagging what changed in the PRINTER_INFO_2 struct
- * when sending messages to other smbd's
- */
-#define PRINTER_MESSAGE_NULL            0x00000000
-#define PRINTER_MESSAGE_DRIVER         0x00000001
-#define PRINTER_MESSAGE_COMMENT                0x00000002
-#define PRINTER_MESSAGE_PRINTERNAME    0x00000004
-#define PRINTER_MESSAGE_LOCATION       0x00000008
-#define PRINTER_MESSAGE_DEVMODE                0x00000010      /* not curently supported */
-#define PRINTER_MESSAGE_SEPFILE                0x00000020
-#define PRINTER_MESSAGE_PRINTPROC      0x00000040
-#define PRINTER_MESSAGE_PARAMS         0x00000080
-#define PRINTER_MESSAGE_DATATYPE       0x00000100
-#define PRINTER_MESSAGE_SECDESC                0x00000200
-#define PRINTER_MESSAGE_CJOBS          0x00000400
-#define PRINTER_MESSAGE_PORT           0x00000800
-#define PRINTER_MESSAGE_SHARENAME      0x00001000
-#define PRINTER_MESSAGE_ATTRIBUTES     0x00002000
-
-typedef struct printer_message_info {
-       uint32 low;             /* PRINTER_CHANGE_XXX */
-       uint32 high;            /* PRINTER_CHANGE_XXX */
-       fstring printer_name;
-       uint32 flags;           /* PRINTER_MESSAGE_XXX */
-}
-PRINTER_MESSAGE_INFO;
-
-/*
- * The printer attributes.
- * I #defined all of them (grabbed form MSDN)
- * I'm only using:
- * ( SHARED | NETWORK | RAW_ONLY )
- * RAW_ONLY _MUST_ be present otherwise NT will send an EMF file
- */
-
-#define PRINTER_ATTRIBUTE_SAMBA                        (PRINTER_ATTRIBUTE_RAW_ONLY|\
-                                                PRINTER_ATTRIBUTE_SHARED|\
-                                                PRINTER_ATTRIBUTE_LOCAL)
-#define PRINTER_ATTRIBUTE_NOT_SAMBA            (PRINTER_ATTRIBUTE_NETWORK)
-
-#define NO_PRIORITY     0
-#define MAX_PRIORITY   99
-#define MIN_PRIORITY    1
-#define DEF_PRIORITY    1
-
-/* the flags of each printers */
-
-#define DRIVER_ANY_VERSION             0xffffffff
-#define DRIVER_MAX_VERSION             4
-
-
-/* 
- * Devicemode structure
- */
-
-typedef struct devicemode
-{
-       UNISTR devicename;
-       uint16 specversion;
-       uint16 driverversion;
-       uint16 size;
-       uint16 driverextra;
-       uint32 fields;
-       uint16 orientation;
-       uint16 papersize;
-       uint16 paperlength;
-       uint16 paperwidth;
-       uint16 scale;
-       uint16 copies;
-       uint16 defaultsource;
-       uint16 printquality;
-       uint16 color;
-       uint16 duplex;
-       uint16 yresolution;
-       uint16 ttoption;
-       uint16 collate;
-       UNISTR formname;
-       uint16 logpixels;
-       uint32 bitsperpel;
-       uint32 pelswidth;
-       uint32 pelsheight;
-       uint32 displayflags;
-       uint32 displayfrequency;
-       uint32 icmmethod;
-       uint32 icmintent;
-       uint32 mediatype;
-       uint32 dithertype;
-       uint32 reserved1;
-       uint32 reserved2;
-       uint32 panningwidth;
-       uint32 panningheight;
-       uint8 *dev_private;
-}
-DEVICEMODE;
-
-typedef struct _devmode_cont
-{
-       uint32 size;
-       uint32 devmode_ptr;
-       DEVICEMODE *devmode;
-}
-DEVMODE_CTR;
-
-typedef struct _printer_default
-{
-       uint32 datatype_ptr;
-       UNISTR2 datatype;
-       DEVMODE_CTR devmode_cont;
-       uint32 access_required;
-}
-PRINTER_DEFAULT;
-
-/********************************************/
-
-typedef struct spool_q_getprinterdata
-{
-       POLICY_HND handle;
-       UNISTR2 valuename;
-       uint32 size;
-}
-SPOOL_Q_GETPRINTERDATA;
-
-typedef struct spool_r_getprinterdata
-{
-       uint32 type;
-       uint32 size;
-       uint8 *data;
-       uint32 needed;
-       WERROR status;
-}
-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;
-       uint32 job_number;
-}
-ADD_JOBINFO_1;
-
-
-/*
- * I'm really wondering how many different time formats
- * I will have to cope with
- *
- * JFM, 09/13/98 In a mad mood ;-(
-*/
-typedef struct systemtime
-{
-       uint16 year;
-       uint16 month;
-       uint16 dayofweek;
-       uint16 day;
-       uint16 hour;
-       uint16 minute;
-       uint16 second;
-       uint16 milliseconds;
-}
-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 s_port_info_1
-{
-       UNISTR port_name;
-}
-PORT_INFO_1;
-
-typedef struct s_port_info_2
-{
-       UNISTR port_name;
-       UNISTR monitor_name;
-       UNISTR description;
-       uint32 port_type;
-       uint32 reserved;
-}
-PORT_INFO_2;
-
-/* Port Type bits */
-#define PORT_TYPE_WRITE         0x0001
-#define PORT_TYPE_READ          0x0002
-#define PORT_TYPE_REDIRECTED    0x0004
-#define PORT_TYPE_NET_ATTACHED  0x0008
-
-typedef struct spool_q_enumports
-{
-       uint32 name_ptr;
-       UNISTR2 name;
-       uint32 level;
-       RPC_BUFFER *buffer;
-       uint32 offered;
-}
-SPOOL_Q_ENUMPORTS;
-
-typedef struct port_info_ctr_info
-{
-       union
-       {
-               PORT_INFO_1 *info_1;
-               PORT_INFO_2 *info_2;
-       }
-       port;
-
-}
-PORT_INFO_CTR;
-
-typedef struct spool_r_enumports
-{
-       RPC_BUFFER *buffer;
-       uint32 needed;          /* bytes needed */
-       uint32 returned;        /* number of printers */
-       WERROR status;
-}
-SPOOL_R_ENUMPORTS;
-
-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;
-
-#define FORM_USER    0
-#define FORM_BUILTIN 1
-#define FORM_PRINTER 2
-
-typedef struct spool_form_1
-{
-       uint32 flag;
-       UNISTR name;
-       uint32 width;
-       uint32 length;
-       uint32 left;
-       uint32 top;
-       uint32 right;
-       uint32 bottom;
-}
-FORM_1;
-
-typedef struct spool_q_enumforms
-{
-       POLICY_HND handle;
-       uint32 level;
-       RPC_BUFFER *buffer;
-       uint32 offered;
-}
-SPOOL_Q_ENUMFORMS;
-
-typedef struct spool_r_enumforms
-{
-       RPC_BUFFER *buffer;
-       uint32 needed;
-       uint32 numofforms;
-       WERROR status;
-}
-SPOOL_R_ENUMFORMS;
-
-/********************************************/
-
-typedef struct spool_q_enumprintprocessors
-{
-       uint32 name_ptr;
-       UNISTR2 name;
-       uint32 environment_ptr;
-       UNISTR2 environment;
-       uint32 level;
-       RPC_BUFFER *buffer;
-       uint32 offered;
-}
-SPOOL_Q_ENUMPRINTPROCESSORS;
-
-typedef struct printprocessor_1
-{
-       UNISTR name;
-}
-PRINTPROCESSOR_1;
-
-typedef struct spool_r_enumprintprocessors
-{
-       RPC_BUFFER *buffer;
-       uint32 needed;
-       uint32 returned;
-       WERROR status;
-}
-SPOOL_R_ENUMPRINTPROCESSORS;
-
-typedef struct spool_q_enumprintprocdatatypes
-{
-       uint32 name_ptr;
-       UNISTR2 name;
-       uint32 processor_ptr;
-       UNISTR2 processor;
-       uint32 level;
-       RPC_BUFFER *buffer;
-       uint32 offered;
-}
-SPOOL_Q_ENUMPRINTPROCDATATYPES;
-
-typedef struct ppdatatype_1
-{
-       UNISTR name;
-}
-PRINTPROCDATATYPE_1;
-
-typedef struct spool_r_enumprintprocdatatypes
-{
-       RPC_BUFFER *buffer;
-       uint32 needed;
-       uint32 returned;
-       WERROR status;
-}
-SPOOL_R_ENUMPRINTPROCDATATYPES;
-
-typedef struct printmonitor_1
-{
-       UNISTR name;
-}
-PRINTMONITOR_1;
-
-typedef struct printmonitor_2
-{
-       UNISTR name;
-       UNISTR environment;
-       UNISTR dll_name;
-}
-PRINTMONITOR_2;
-
-typedef struct spool_q_enumprintmonitors
-{
-       uint32 name_ptr;
-       UNISTR2 name;
-       uint32 level;
-       RPC_BUFFER *buffer;
-       uint32 offered;
-}
-SPOOL_Q_ENUMPRINTMONITORS;
-
-typedef struct spool_r_enumprintmonitors
-{
-       RPC_BUFFER *buffer;
-       uint32 needed;
-       uint32 returned;
-       WERROR status;
-}
-SPOOL_R_ENUMPRINTMONITORS;
-
-
-typedef struct spool_q_enumprinterdata
-{
-       POLICY_HND handle;
-       uint32 index;
-       uint32 valuesize;
-       uint32 datasize;
-}
-SPOOL_Q_ENUMPRINTERDATA;
-
-typedef struct spool_r_enumprinterdata
-{
-       uint32 valuesize;
-       uint16 *value;
-       uint32 realvaluesize;
-       uint32 type;
-       uint32 datasize;
-       uint8 *data;
-       uint32 realdatasize;
-       WERROR status;
-}
-SPOOL_R_ENUMPRINTERDATA;
-
-typedef struct spool_q_setprinterdata
-{
-       POLICY_HND handle;
-       UNISTR2 value;
-       uint32 type;
-       uint32 max_len;
-       uint8 *data;
-       uint32 real_len;
-       uint32 numeric_data;
-}
-SPOOL_Q_SETPRINTERDATA;
-
-typedef struct spool_r_setprinterdata
-{
-       WERROR status;
-}
-SPOOL_R_SETPRINTERDATA;
-
-typedef struct _form
-{
-       uint32 flags;
-       uint32 name_ptr;
-       uint32 size_x;
-       uint32 size_y;
-       uint32 left;
-       uint32 top;
-       uint32 right;
-       uint32 bottom;
-       UNISTR2 name;
-}
-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;
-       UNISTR2 key;
-       uint32 size;
-}
-SPOOL_Q_ENUMPRINTERKEY;
-
-typedef struct spool_r_enumprinterkey
-{
-       BUFFER5 keys;
-       uint32 needed;  /* in bytes */
-       WERROR status;
-}
-SPOOL_R_ENUMPRINTERKEY;
-
-typedef struct printer_enum_values
-{
-       UNISTR valuename;
-       uint32 value_len;
-       uint32 type;
-       uint8  *data;
-       uint32 data_len; 
-       
-}
-PRINTER_ENUM_VALUES;
-
-typedef struct printer_enum_values_ctr
-{
-       uint32 size;
-       uint32 size_of_array;
-       PRINTER_ENUM_VALUES *values;
-}
-PRINTER_ENUM_VALUES_CTR;
-
-typedef struct spool_q_enumprinterdataex
-{
-       POLICY_HND handle;
-       UNISTR2 key;
-       uint32 size;
-}
-SPOOL_Q_ENUMPRINTERDATAEX;
-
-typedef struct spool_r_enumprinterdataex
-{
-       PRINTER_ENUM_VALUES_CTR ctr;
-       uint32 needed;
-       uint32 returned;
-       WERROR status;
-}
-SPOOL_R_ENUMPRINTERDATAEX;
-
-#endif /* _RPC_SPOOLSS_H */
-
index 59c3c32346de3ff5f71a7c101b7b1dce3274846d..281a218256f5d83fa1089cff2a0297e4b7dddd99 100644 (file)
@@ -573,6 +573,12 @@ typedef struct connection_struct {
         */
        struct auth_serversupplied_info *server_info;
 
+       /*
+        * If the "force group" parameter is set, this is the primary gid that
+        * may be used in the users token, depending on the vuid using this tid.
+        */
+       gid_t force_group_gid;
+
        char client_address[INET6_ADDRSTRLEN]; /* String version of client IP address. */
 
        uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */
@@ -1753,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 fd1bba16a7a319111699d981f5bffd7c5424be5d..22cfaaf58129a8d26223682b5ffb4ff699852ba2 100644 (file)
@@ -256,7 +256,9 @@ NULL returns on zero request. JRA.
 #define TALLOC_REALLOC(ctx, ptr, count) _talloc_realloc(ctx, ptr, count, __location__)
 #define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)_talloc_realloc_array(ctx, ptr, sizeof(type), count, #type)
 #define talloc_destroy(ctx) talloc_free(ctx)
+#ifndef TALLOC_FREE
 #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
+#endif
 
 /* only define PARANOID_MALLOC_CHECKER with --enable-developer */
 
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 7a8768029a09d793f73826be7b30b4c2ebd6c354..eaec0d11da6d6e1d6c925dcabf241d14b1231d2a 100644 (file)
 
 #include "nsswitch/libwbclient/wbclient.h"
 
-struct wb_context {
-       struct async_req_queue *queue;
-       int fd;
-       bool is_priv;
-};
+struct wb_context;
 
-struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
-                               struct wb_context *wb_ctx, bool need_priv,
-                               const struct winbindd_request *wb_req);
-wbcErr wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
+                                struct tevent_context *ev,
+                                struct wb_context *wb_ctx, bool need_priv,
+                                struct winbindd_request *wb_req);
+wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                     struct winbindd_response **presponse);
 struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx);
 
 /* Definitions from wb_reqtrans.c */
-bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err);
 wbcErr map_wbc_err_from_errno(int error);
-wbcErr async_req_simple_recv_wbcerr(struct async_req *req);
 
-struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
-                                  struct tevent_context *ev,
-                                  int fd, size_t max_extra_data);
+bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err);
+wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req);
 
-wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+struct tevent_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
+                                   struct tevent_context *ev,
+                                   int fd, size_t max_extra_data);
+wbcErr wb_req_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                        struct winbindd_request **preq);
 
-struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
-                                   struct tevent_context *ev, int fd,
-                                   struct winbindd_request *wb_req);
+struct tevent_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
+                                    struct tevent_context *ev,
+                                    struct tevent_queue *queue, int fd,
+                                    struct winbindd_request *wb_req);
+wbcErr wb_req_write_recv(struct tevent_req *req);
 
-wbcErr wb_req_write_recv(struct async_req *req);
-
-struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
-                                   struct tevent_context *ev, int fd);
-
-wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+struct tevent_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
+                                    struct tevent_context *ev, int fd);
+wbcErr wb_resp_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                         struct winbindd_response **presp);
 
-struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
-                                   struct tevent_context *ev, int fd,
-                                   struct winbindd_response *wb_resp);
-
-wbcErr wb_resp_write_recv(struct async_req *req);
+struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
+                                     struct tevent_context *ev,
+                                     struct tevent_queue *queue, int fd,
+                                     struct winbindd_response *wb_resp);
+wbcErr wb_resp_write_recv(struct tevent_req *req);
 
 #endif /*_WBC_ASYNC_H_*/
index 81cb9a50948d9c5337841a01f06a38bb8fd927a0..c3b345142f528804a42c28a9744700e1da205526 100644 (file)
@@ -763,7 +763,7 @@ bool convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
  * converted.
  */
 bool convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
-                          void const *src, size_t srclen, void **dst,
+                          void const *src, size_t srclen, void *dst,
                           size_t *converted_size, bool allow_bad_conv)
 {
        void **dest = (void **)dst;
index 03667ff3552d62a1e6b2c05f823910df13f07065..4a5bf6d81a793d8d3b46f3e31cc594b70f60553d 100644 (file)
@@ -121,9 +121,9 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx,
 {
        struct ctdb_rec_data *r;
        size_t m_size, r_size;
-       struct ctdb_marshall_buffer *m2;
+       struct ctdb_marshall_buffer *m2 = NULL;
 
-       r = db_ctdb_marshall_record(mem_ctx, reqid, key, header, data);
+       r = db_ctdb_marshall_record(talloc_tos(), reqid, key, header, data);
        if (r == NULL) {
                talloc_free(m);
                return NULL;
@@ -133,7 +133,7 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx,
                m = (struct ctdb_marshall_buffer *)talloc_zero_size(
                        mem_ctx, offsetof(struct ctdb_marshall_buffer, data));
                if (m == NULL) {
-                       return NULL;
+                       goto done;
                }
                m->db_id = db_id;
        }
@@ -145,15 +145,15 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx,
                mem_ctx, m,  m_size + r_size);
        if (m2 == NULL) {
                talloc_free(m);
-               return NULL;
+               goto done;
        }
 
        memcpy(m_size + (uint8_t *)m2, r, r_size);
 
-       talloc_free(r);
-
        m2->count++;
 
+done:
+       talloc_free(r);
        return m2;
 }
 
index 6e09627223c84a5b8726e8ca20b0a7a2e60af971..cf4faa25b97254bd978dc8183fdd0e28fa635caa 100644 (file)
@@ -131,12 +131,12 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
                 */
        }
 
-       node = (struct db_rbt_node *)SMB_MALLOC(
+       node = (struct db_rbt_node *)talloc_size(rec_priv->db_ctx,
                offsetof(struct db_rbt_node, data) + rec->key.dsize
                + data.dsize);
 
        if (node == NULL) {
-               SAFE_FREE(rec_priv->node);
+               TALLOC_FREE(rec_priv->node);
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -148,7 +148,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
        db_rbt_parse_node(node, &this_key, &this_val);
 
        memcpy(this_key.dptr, rec->key.dptr, node->keysize);
-       SAFE_FREE(rec_priv->node);
+       TALLOC_FREE(rec_priv->node);
 
        memcpy(this_val.dptr, data.dptr, node->valuesize);
 
@@ -194,7 +194,7 @@ static NTSTATUS db_rbt_delete(struct db_record *rec)
        }
 
        rb_erase(&rec_priv->node->rb_node, &rec_priv->db_ctx->tree);
-       SAFE_FREE(rec_priv->node);
+       TALLOC_FREE(rec_priv->node);
 
        return NT_STATUS_OK;
 }
index 9adb2370963e086b6b6a2d61c6322682bbeb4dba..bb09726ee085d82ea9ae2beb445b509ffcd83d83 100644 (file)
@@ -95,6 +95,9 @@ const struct unix_error_map unix_dos_nt_errmap[] = {
 #ifdef ENOATTR
        { ENOATTR, ERRDOS, ERRbadfile, NT_STATUS_NOT_FOUND },
 #endif
+#ifdef ECANCELED
+       { ECANCELED, ERRDOS, ERRbadfid, NT_STATUS_CANCELLED},
+#endif
 
        { 0, 0, 0, NT_STATUS_OK }
 };
index 9e81a4779611c01ba6fc66582ae919189b50b703..90d86c6c79feac40d34e38ee94259d0ef7b52360 100644 (file)
@@ -91,6 +91,11 @@ bool run_events(struct tevent_context *ev,
                return true;
        }
 
+       if (ev->immediate_events &&
+           tevent_common_loop_immediate(ev)) {
+               return true;
+       }
+
        GetTimeOfDay(&now);
 
        if ((ev->timer_events != NULL)
@@ -145,7 +150,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,17 +186,6 @@ static int s3_event_loop_once(struct tevent_context *ev)
        return 0;
 }
 
-static int s3_event_loop_wait(struct tevent_context *ev)
-{
-       int ret = 0;
-
-       while (ret == 0) {
-               ret = s3_event_loop_once(ev);
-       }
-
-       return ret;
-}
-
 void event_context_reinit(struct tevent_context *ev)
 {
        tevent_common_context_destructor(ev);
@@ -238,15 +232,16 @@ void dump_event_list(struct tevent_context *ev)
 }
 
 static const struct tevent_ops s3_event_ops = {
-       .context_init   = s3_event_context_init,
-       .add_fd         = tevent_common_add_fd,
-       .set_fd_close_fn= tevent_common_fd_set_close_fn,
-       .get_fd_flags   = tevent_common_fd_get_flags,
-       .set_fd_flags   = tevent_common_fd_set_flags,
-       .add_timer      = tevent_common_add_timer,
-       .add_signal     = tevent_common_add_signal,
-       .loop_once      = s3_event_loop_once,
-       .loop_wait      = s3_event_loop_wait,
+       .context_init           = s3_event_context_init,
+       .add_fd                 = tevent_common_add_fd,
+       .set_fd_close_fn        = tevent_common_fd_set_close_fn,
+       .get_fd_flags           = tevent_common_fd_get_flags,
+       .set_fd_flags           = tevent_common_fd_set_flags,
+       .add_timer              = tevent_common_add_timer,
+       .schedule_immediate     = tevent_common_schedule_immediate,
+       .add_signal             = tevent_common_add_signal,
+       .loop_once              = s3_event_loop_once,
+       .loop_wait              = tevent_common_loop_wait,
 };
 
 static bool s3_tevent_init(void)
@@ -286,8 +281,9 @@ static void s3_event_debug(void *context, enum tevent_debug_level level,
                break;
 
        };
-       vasprintf(&s, fmt, ap);
-       if (!s) return;
+       if (vasprintf(&s, fmt, ap) == -1) {
+               return;
+       }
        DEBUG(samba_level, ("s3_event: %s", s));
        free(s);
 }
index fa213a37c06beb94eccd73d82ff52d90264ca324..44500542f2baf8961217855a45a3922eacf610fc 100644 (file)
@@ -207,12 +207,12 @@ smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode)
        from = charsets;
        to = charsets;
 
-       ret = SMB_MALLOC_P(smb_iconv_t);
+       ret = SMB_MALLOC_P(struct smb_iconv_s);
        if (!ret) {
                errno = ENOMEM;
                return (smb_iconv_t)-1;
        }
-       memset(ret, 0, sizeof(smb_iconv_t));
+       memset(ret, 0, sizeof(struct smb_iconv_s));
 
        ret->from_name = SMB_STRDUP(fromcode);
        ret->to_name = SMB_STRDUP(tocode);
index 4567fe457b83b0cc083aa22006606dc4d513ff37..2535418d99a08a62351cc488dd69cacfdf3f54ec 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-
-/* working out the interfaces for a OS is an incredibly non-portable
-   thing. We have several possible implementations below, and autoconf
-   tries each of them to see what works
-
-   Note that this file does _not_ include includes.h. That is so this code
-   can be called directly from the autoconf tests. That also means
-   this code cannot use any of the normal Samba debug stuff or defines.
-   This is standalone code.
-
-*/
-
-#ifndef AUTOCONF_TEST
-#include "config.h"
-#endif
-
-#include <unistd.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <netdb.h>
-#include <sys/ioctl.h>
-#include <netdb.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#ifdef HAVE_IFADDRS_H
-#include <ifaddrs.h>
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#ifndef SIOCGIFCONF
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#ifdef __COMPAR_FN_T
-#define QSORT_CAST (__compar_fn_t)
-#endif
-
-#ifndef QSORT_CAST
-#define QSORT_CAST (int (*)(const void *, const void *))
-#endif
-
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-
-#define SOCKET_WRAPPER_NOT_REPLACE
-#include "interfaces.h"
-#include "../replace/replace.h"
-
-/****************************************************************************
- Utility functions.
-****************************************************************************/
+#include "includes.h"
 
 /****************************************************************************
  Create a struct sockaddr_storage with the netmask bits set to 1.
index e4b20c7493493bce097fd354c2fb76e6f26bb0b2..5e11dd4e25148b5bb29668f9aa627f0c1e3f4d7a 100644 (file)
@@ -286,7 +286,15 @@ NTSTATUS messaging_register(struct messaging_context *msg_ctx,
         */
 
        for (cb = msg_ctx->callbacks; cb != NULL; cb = cb->next) {
-               if (cb->msg_type == msg_type) {
+               /* we allow a second registration of the same message
+                  type if it has a different private pointer. This is
+                  needed in, for example, the internal notify code,
+                  which creates a new notify context for each tree
+                  connect, and expects to receive messages to each of
+                  them. */
+               if (cb->msg_type == msg_type && private_data == cb->private_data) {
+                       DEBUG(5,("Overriding messaging pointer for type %u - private_data=%p\n",
+                                 (unsigned)msg_type, private_data));
                        cb->fn = fn;
                        cb->private_data = private_data;
                        return NT_STATUS_OK;
@@ -317,6 +325,8 @@ void messaging_deregister(struct messaging_context *ctx, uint32_t msg_type,
                next = cb->next;
                if ((cb->msg_type == msg_type)
                    && (cb->private_data == private_data)) {
+                       DEBUG(5,("Deregistering messaging pointer for type %u - private_data=%p\n",
+                                 (unsigned)msg_type, private_data));
                        DLIST_REMOVE(ctx->callbacks, cb);
                        TALLOC_FREE(cb);
                }
@@ -362,7 +372,11 @@ void messaging_dispatch_rec(struct messaging_context *msg_ctx,
                if (cb->msg_type == rec->msg_type) {
                        cb->fn(msg_ctx, cb->private_data, rec->msg_type,
                               rec->src, &rec->buf);
-                       return;
+                       /* we continue looking for matching messages
+                          after finding one. This matters for
+                          subsystems like the internal notify code
+                          which register more than one handler for
+                          the same message type */
                }
        }
        return;
index 233255fed4fe8c075fab08203a5c22681697dff7..b676ae63dde08c6296b8b8349142be5886563dd9 100644 (file)
@@ -29,36 +29,36 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx,
                                            const char *server_name,
                                            struct cli_state **cli)
 {
+       struct user_auth_info *auth_info = NULL;
        struct cli_state *cli_ipc = NULL;
 
        if (!ctx || !cli || !server_name) {
                return WERR_INVALID_PARAM;
        }
 
-       cli_cm_set_signing_state(Undefined);
-
-       if (ctx->use_kerberos) {
-               cli_cm_set_use_kerberos();
-       }
-
-       if (ctx->password) {
-               cli_cm_set_password(ctx->password);
-       }
-       if (ctx->username) {
-               cli_cm_set_username(ctx->username);
+       auth_info = user_auth_info_init(NULL);
+       if (!auth_info) {
+               return WERR_NOMEM;
        }
+       auth_info->signing_state = Undefined;
+       set_cmdline_auth_info_use_kerberos(auth_info, ctx->use_kerberos);
+       set_cmdline_auth_info_password(auth_info, ctx->password);
+       set_cmdline_auth_info_username(auth_info, ctx->username);
 
        if (ctx->username && ctx->username[0] &&
            ctx->password && ctx->password[0] &&
            ctx->use_kerberos) {
-               cli_cm_set_fallback_after_kerberos();
+               set_cmdline_auth_info_fallback_after_kerberos(auth_info, true);
        }
 
        cli_ipc = cli_cm_open(ctx, NULL,
-                             server_name, "IPC$",
-                             false, false,
-                             PROTOCOL_NT1,
-                             0, 0x20);
+                               server_name, "IPC$",
+                               auth_info,
+                               false, false,
+                               PROTOCOL_NT1,
+                               0, 0x20);
+       TALLOC_FREE(auth_info);
+
        if (!cli_ipc) {
                libnetapi_set_error_string(ctx,
                        "Failed to connect to IPC$ share on %s", server_name);
@@ -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 617bde2c9ae4b078afbb7ca47d834872b3f9ed19..189902a78eda535a6629e4272f2f7e3ab3a26788 100644 (file)
@@ -33,7 +33,7 @@ WERROR NetGroupAdd_r(struct libnetapi_ctx *ctx,
        struct rpc_pipe_client *pipe_cli = NULL;
        NTSTATUS status;
        WERROR werr;
-       POLICY_HND connect_handle, domain_handle, group_handle;
+       struct policy_handle connect_handle, domain_handle, group_handle;
        struct lsa_String lsa_group_name;
        struct dom_sid2 *domain_sid = NULL;
        uint32_t rid = 0;
@@ -223,7 +223,7 @@ WERROR NetGroupDel_r(struct libnetapi_ctx *ctx,
        struct rpc_pipe_client *pipe_cli = NULL;
        NTSTATUS status;
        WERROR werr;
-       POLICY_HND connect_handle, domain_handle, group_handle;
+       struct policy_handle connect_handle, domain_handle, group_handle;
        struct lsa_String lsa_group_name;
        struct dom_sid2 *domain_sid = NULL;
        int i = 0;
@@ -384,7 +384,7 @@ WERROR NetGroupSetInfo_r(struct libnetapi_ctx *ctx,
        struct rpc_pipe_client *pipe_cli = NULL;
        NTSTATUS status;
        WERROR werr;
-       POLICY_HND connect_handle, domain_handle, group_handle;
+       struct policy_handle connect_handle, domain_handle, group_handle;
        struct lsa_String lsa_group_name;
        struct dom_sid2 *domain_sid = NULL;
 
@@ -624,7 +624,7 @@ WERROR NetGroupGetInfo_r(struct libnetapi_ctx *ctx,
        struct rpc_pipe_client *pipe_cli = NULL;
        NTSTATUS status;
        WERROR werr;
-       POLICY_HND connect_handle, domain_handle, group_handle;
+       struct policy_handle connect_handle, domain_handle, group_handle;
        struct lsa_String lsa_group_name;
        struct dom_sid2 *domain_sid = NULL;
 
@@ -742,7 +742,7 @@ WERROR NetGroupAddUser_r(struct libnetapi_ctx *ctx,
        struct rpc_pipe_client *pipe_cli = NULL;
        NTSTATUS status;
        WERROR werr;
-       POLICY_HND connect_handle, domain_handle, group_handle;
+       struct policy_handle connect_handle, domain_handle, group_handle;
        struct lsa_String lsa_group_name, lsa_user_name;
        struct dom_sid2 *domain_sid = NULL;
 
@@ -863,7 +863,7 @@ WERROR NetGroupDelUser_r(struct libnetapi_ctx *ctx,
        struct rpc_pipe_client *pipe_cli = NULL;
        NTSTATUS status;
        WERROR werr;
-       POLICY_HND connect_handle, domain_handle, group_handle;
+       struct policy_handle connect_handle, domain_handle, group_handle;
        struct lsa_String lsa_group_name, lsa_user_name;
        struct dom_sid2 *domain_sid = NULL;
 
index 9d7f299f59bae03b0ae66b19355dad8b43da8112..8cc65a6e9eb0a1e622995ac3f1a8da16441c4887 100644 (file)
@@ -352,7 +352,7 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
        struct rpc_pipe_client *pipe_cli = NULL;
        NTSTATUS status;
        WERROR werr;
-       POLICY_HND connect_handle, domain_handle, user_handle;
+       struct policy_handle connect_handle, domain_handle, user_handle;
        struct lsa_String lsa_account_name;
        struct dom_sid2 *domain_sid = NULL;
        union samr_UserInfo *user_info = NULL;
@@ -496,7 +496,7 @@ WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
        struct rpc_pipe_client *pipe_cli = NULL;
        NTSTATUS status;
        WERROR werr;
-       POLICY_HND connect_handle, builtin_handle, domain_handle, user_handle;
+       struct policy_handle connect_handle, builtin_handle, domain_handle, user_handle;
        struct lsa_String lsa_account_name;
        struct samr_Ids user_rids, name_types;
        struct dom_sid2 *domain_sid = NULL;
index 5a5c0ead654516414db37f6ad1bd3de31f78784a..ae6a41151d5c779adcfa9f4fac4f753bc4a87c8f 100644 (file)
@@ -80,12 +80,20 @@ static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx,
                                           uint32 desired_access,
                                           struct registry_key **key)
 {
+       WERROR werr;
+
        if (servicename == NULL) {
                *key = rpd(ctx)->base_key;
                return WERR_OK;
        }
-       return reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename,
+       werr = reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename,
                           desired_access, key);
+
+       if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
+               werr = WERR_NO_SUCH_SERVICE;
+       }
+
+       return werr;
 }
 
 /**
@@ -828,9 +836,6 @@ static WERROR smbconf_reg_get_share(struct smbconf_ctx *ctx,
        werr = smbconf_reg_open_service_key(tmp_ctx, ctx, servicename,
                                            REG_KEY_READ, &key);
        if (!W_ERROR_IS_OK(werr)) {
-               if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
-                       werr = WERR_NO_SUCH_SERVICE;
-               }
                goto done;
        }
 
index b31dec0438dced9dd720e1b77d7814ea684a45e5..c83eeb805de506ce1359892956a4db665ce0a4ce 100644 (file)
@@ -214,7 +214,7 @@ static bool torture_smbconf_txt(void)
        printf("TEST: init\n");
        werr = smbconf_init_txt(mem_ctx, &conf_ctx, filename);
        if (!W_ERROR_IS_OK(werr)) {
-               printf("FAIL: text backend\[ failed: %s\n", win_errstr(werr));
+               printf("FAIL: text backend failed: %s\n", win_errstr(werr));
                ret = false;
                goto done;
        }
index 89f7be8e6ce3e48b463b9b3fecd90f4d948b1c1b..75fd82709a881a3b98983f50d708ef88093e9036 100644 (file)
@@ -290,7 +290,7 @@ struct user_auth_info *user_auth_info_init(TALLOC_CTX *mem_ctx)
        return result;
 }
 
-const char *get_cmdline_auth_info_username(struct user_auth_info *auth_info)
+const char *get_cmdline_auth_info_username(const struct user_auth_info *auth_info)
 {
        if (!auth_info->username) {
                return "";
@@ -308,7 +308,7 @@ void set_cmdline_auth_info_username(struct user_auth_info *auth_info,
        }
 }
 
-const char *get_cmdline_auth_info_password(struct user_auth_info *auth_info)
+const char *get_cmdline_auth_info_password(const struct user_auth_info *auth_info)
 {
        if (!auth_info->password) {
                return "";
@@ -320,6 +320,9 @@ void set_cmdline_auth_info_password(struct user_auth_info *auth_info,
                                    const char *password)
 {
        TALLOC_FREE(auth_info->password);
+       if (password == NULL) {
+               password = "";
+       }
        auth_info->password = talloc_strdup(auth_info, password);
        if (!auth_info->password) {
                exit(ENOMEM);
@@ -346,7 +349,7 @@ bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info,
        return true;
 }
 
-int get_cmdline_auth_info_signing_state(struct user_auth_info *auth_info)
+int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info)
 {
        return auth_info->signing_state;
 }
@@ -357,11 +360,22 @@ void set_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info,
         auth_info->use_kerberos = b;
 }
 
-bool get_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info)
+bool get_cmdline_auth_info_use_kerberos(const struct user_auth_info *auth_info)
 {
        return auth_info->use_kerberos;
 }
 
+void set_cmdline_auth_info_fallback_after_kerberos(struct user_auth_info *auth_info,
+                                       bool b)
+{
+       auth_info->fallback_after_kerberos = b;
+}
+
+bool get_cmdline_auth_info_fallback_after_kerberos(const struct user_auth_info *auth_info)
+{
+       return auth_info->fallback_after_kerberos;
+}
+
 /* This should only be used by lib/popt_common.c JRA */
 void set_cmdline_auth_info_use_krb5_ticket(struct user_auth_info *auth_info)
 {
@@ -380,23 +394,23 @@ void set_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info)
        auth_info->use_machine_account = true;
 }
 
-bool get_cmdline_auth_info_got_pass(struct user_auth_info *auth_info)
+bool get_cmdline_auth_info_got_pass(const struct user_auth_info *auth_info)
 {
        return auth_info->got_pass;
 }
 
-bool get_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info)
+bool get_cmdline_auth_info_smb_encrypt(const struct user_auth_info *auth_info)
 {
        return auth_info->smb_encrypt;
 }
 
-bool get_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info)
+bool get_cmdline_auth_info_use_machine_account(const struct user_auth_info *auth_info)
 {
        return auth_info->use_machine_account;
 }
 
 struct user_auth_info *get_cmdline_auth_info_copy(TALLOC_CTX *mem_ctx,
-                                                 struct user_auth_info *src)
+                                                 const struct user_auth_info *src)
 {
        struct user_auth_info *result;
 
@@ -455,6 +469,32 @@ bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info *auth_inf
        return true;
 }
 
+/****************************************************************************
+ Ensure we have a password if one not given.
+****************************************************************************/
+
+void set_cmdline_auth_info_getpass(struct user_auth_info *auth_info)
+{
+       char *label = NULL;
+       char *pass;
+       TALLOC_CTX *frame;
+
+       if (get_cmdline_auth_info_got_pass(auth_info) ||
+                       get_cmdline_auth_info_use_kerberos(auth_info)) {
+               /* Already got one... */
+               return;
+       }
+
+       frame = talloc_stackframe();
+       label = talloc_asprintf(frame, "Enter %s's password: ",
+                       get_cmdline_auth_info_username(auth_info));
+       pass = getpass(label);
+       if (pass) {
+               set_cmdline_auth_info_password(auth_info, pass);
+       }
+       TALLOC_FREE(frame);
+}
+
 /****************************************************************************
  Add a gid to an array of gids if it's not already there.
 ****************************************************************************/
@@ -899,13 +939,6 @@ bool reinit_after_fork(struct messaging_context *msg_ctx,
         * numbers as each other */
        set_need_random_reseed();
 
-#ifdef WITH_MADVISE_PROTECTED
-       /* Protect parent process from being killed by kernel when system
-        * memory is low.  Child processes can still be killed */
-       if(!parent_longlived)
-               madvise(NULL,0,MADV_PROTECT);
-#endif
-
        /* tdb needs special fork handling */
        if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
                DEBUG(0,("tdb_reopen_all failed.\n"));
@@ -3109,9 +3142,9 @@ NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
        return NT_STATUS_OK;
 }
 
-bool is_valid_policy_hnd(const POLICY_HND *hnd)
+bool is_valid_policy_hnd(const struct policy_handle *hnd)
 {
-       POLICY_HND tmp;
+       struct policy_handle tmp;
        ZERO_STRUCT(tmp);
        return (memcmp(&tmp, hnd, sizeof(tmp)) != 0);
 }
index 6e75a67a85b41ac8f3a6c9f055aa80d19a62cdf2..a0dbca1a001ed01046b287bb91c2d7f5107d6fa7 100644 (file)
@@ -519,7 +519,7 @@ NTSTATUS read_socket_with_timeout(int fd, char *buf,
                }
 
                while (nread < mincnt) {
-                       readret = sys_read(fd, buf + nread, maxcnt - nread);
+                       readret = sys_recv(fd, buf + nread, maxcnt - nread, 0);
 
                        if (readret == 0) {
                                DEBUG(5,("read_socket_with_timeout: "
@@ -588,7 +588,7 @@ NTSTATUS read_socket_with_timeout(int fd, char *buf,
                        return NT_STATUS_IO_TIMEOUT;
                }
 
-               readret = sys_read(fd, buf+nread, maxcnt-nread);
+               readret = sys_recv(fd, buf+nread, maxcnt-nread, 0);
 
                if (readret == 0) {
                        /* we got EOF on the file descriptor */
@@ -1033,8 +1033,7 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
                    timeval_current_ofs(0, state->wait_nsec))) {
                goto fail;
        }
-       subreq->async.fn = open_socket_out_connected;
-       subreq->async.private_data = result;
+       tevent_req_set_callback(subreq, open_socket_out_connected, result);
        return result;
 
  post_status:
@@ -1047,10 +1046,10 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
 
 static void open_socket_out_connected(struct tevent_req *subreq)
 {
-       struct tevent_req *req = talloc_get_type_abort(
-               subreq->async.private_data, struct tevent_req);
-       struct open_socket_out_state *state = talloc_get_type_abort(
-               req->private_state, struct open_socket_out_state);
+       struct tevent_req *req =
+               tevent_req_callback_data(subreq, struct tevent_req);
+       struct open_socket_out_state *state =
+               tevent_req_data(req, struct open_socket_out_state);
        int ret;
        int sys_errno;
 
@@ -1089,8 +1088,7 @@ static void open_socket_out_connected(struct tevent_req *subreq)
                        tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
                        return;
                }
-               subreq->async.fn = open_socket_out_connected;
-               subreq->async.private_data = req;
+               tevent_req_set_callback(subreq, open_socket_out_connected, req);
                return;
        }
 
@@ -1107,8 +1105,8 @@ static void open_socket_out_connected(struct tevent_req *subreq)
 
 NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd)
 {
-       struct open_socket_out_state *state = talloc_get_type_abort(
-               req->private_state, struct open_socket_out_state);
+       struct open_socket_out_state *state =
+               tevent_req_data(req, struct open_socket_out_state);
        NTSTATUS status;
 
        if (tevent_req_is_nterror(req, &status)) {
@@ -1154,22 +1152,22 @@ struct open_socket_out_defer_state {
        int fd;
 };
 
-static void open_socket_out_defer_waited(struct async_req *subreq);
+static void open_socket_out_defer_waited(struct tevent_req *subreq);
 static void open_socket_out_defer_connected(struct tevent_req *subreq);
 
-struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
-                                            struct event_context *ev,
-                                            struct timeval wait_time,
-                                            const struct sockaddr_storage *pss,
-                                            uint16_t port,
-                                            int timeout)
+struct tevent_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
+                                             struct event_context *ev,
+                                             struct timeval wait_time,
+                                             const struct sockaddr_storage *pss,
+                                             uint16_t port,
+                                             int timeout)
 {
-       struct async_req *result, *subreq;
+       struct tevent_req *req, *subreq;
        struct open_socket_out_defer_state *state;
-       NTSTATUS status;
 
-       if (!async_req_setup(mem_ctx, &result, &state,
-                            struct open_socket_out_defer_state)) {
+       req = tevent_req_create(mem_ctx, &state,
+                               struct open_socket_out_defer_state);
+       if (req == NULL) {
                return NULL;
        }
        state->ev = ev;
@@ -1177,74 +1175,66 @@ struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
        state->port = port;
        state->timeout = timeout;
 
-       subreq = async_wait_send(state, ev, wait_time);
+       subreq = tevent_wakeup_send(
+               state, ev,
+               timeval_current_ofs(wait_time.tv_sec, wait_time.tv_usec));
        if (subreq == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto post_status;
-       }
-       subreq->async.fn = open_socket_out_defer_waited;
-       subreq->async.priv = result;
-       return result;
-
- post_status:
-       if (!async_post_ntstatus(result, ev, status)) {
                goto fail;
        }
-       return result;
+       tevent_req_set_callback(subreq, open_socket_out_defer_waited, req);
+       return req;
  fail:
-       TALLOC_FREE(result);
+       TALLOC_FREE(req);
        return NULL;
 }
 
-static void open_socket_out_defer_waited(struct async_req *subreq)
+static void open_socket_out_defer_waited(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       struct open_socket_out_defer_state *state = talloc_get_type_abort(
-               req->private_data, struct open_socket_out_defer_state);
-       struct tevent_req *subreq2;
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct open_socket_out_defer_state *state = tevent_req_data(
+               req, struct open_socket_out_defer_state);
        bool ret;
 
-       ret = async_wait_recv(subreq);
+       ret = tevent_wakeup_recv(subreq);
        TALLOC_FREE(subreq);
        if (!ret) {
-               async_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+               tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
                return;
        }
 
-       subreq2 = open_socket_out_send(state, state->ev, &state->ss,
-                                      state->port, state->timeout);
-       if (async_req_nomem(subreq2, req)) {
+       subreq = open_socket_out_send(state, state->ev, &state->ss,
+                                     state->port, state->timeout);
+       if (tevent_req_nomem(subreq, req)) {
                return;
        }
-       subreq2->async.fn = open_socket_out_defer_connected;
-       subreq2->async.private_data = req;
+       tevent_req_set_callback(subreq, open_socket_out_defer_connected, req);
 }
 
 static void open_socket_out_defer_connected(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.private_data, struct async_req);
-       struct open_socket_out_defer_state *state = talloc_get_type_abort(
-               req->private_data, struct open_socket_out_defer_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct open_socket_out_defer_state *state = tevent_req_data(
+               req, struct open_socket_out_defer_state);
        NTSTATUS status;
 
        status = open_socket_out_recv(subreq, &state->fd);
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
-               async_req_nterror(req, status);
+               tevent_req_nterror(req, status);
                return;
        }
-       async_req_done(req);
+       tevent_req_done(req);
 }
 
-NTSTATUS open_socket_out_defer_recv(struct async_req *req, int *pfd)
+NTSTATUS open_socket_out_defer_recv(struct tevent_req *req, int *pfd)
 {
-       struct open_socket_out_defer_state *state = talloc_get_type_abort(
-               req->private_data, struct open_socket_out_defer_state);
+       struct open_socket_out_defer_state *state = tevent_req_data(
+               req, struct open_socket_out_defer_state);
        NTSTATUS status;
 
-       if (async_req_is_nterror(req, &status)) {
+       if (tevent_req_is_nterror(req, &status)) {
                return status;
        }
        *pfd = state->fd;
index 4e78d1b0642e55134d4f79eba57021b59f04ba6a..840e8e06da7670f7e12868bc34f4bc64470f6984 100644 (file)
@@ -383,22 +383,6 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
        pull_ucs2(NULL, dest, str->buffer, maxlen, str->uni_str_len*2, STR_NOALIGN);
 }
 
-#if 0
-/*******************************************************************
- Convert a (little-endian) UNISTR3 structure to an ASCII string.
-********************************************************************/
-
-void unistr3_to_ascii(char *dest, const UNISTR3 *str, size_t maxlen)
-{
-       if ((str == NULL) || (str->uni_str_len == 0)) {
-               *dest='\0';
-               return;
-       }
-       pull_ucs2(NULL, dest, str->str.buffer, maxlen, str->uni_str_len*2,
-                 STR_NOALIGN);
-}
-#endif
-
 /*******************************************************************
  Duplicate a UNISTR2 string into a null terminated char*
  using a talloc context.
diff --git a/source3/lib/version_test.c b/source3/lib/version_test.c
new file mode 100644 (file)
index 0000000..880cfeb
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  version_test - test program for samba_version_strion()
+ *  Copyright (C) Michael Adam 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
+ *  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"
+
+int main(void)
+{
+       printf("%s\n", samba_version_string());
+       return 0;
+}
index 65906dcb91b52fefb9a8a7fe41f967f07586ca7e..dbea8b6686df30f2d2810783ad370c69799f38a8 100644 (file)
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
-struct req_read_state {
-       struct winbindd_request *wb_req;
-       size_t max_extra_data;
-};
+wbcErr map_wbc_err_from_errno(int error)
+{
+       switch(error) {
+       case EPERM:
+       case EACCES:
+               return WBC_ERR_AUTH_ERROR;
+       case ENOMEM:
+               return WBC_ERR_NO_MEMORY;
+       case EIO:
+       default:
+               return WBC_ERR_UNKNOWN_FAILURE;
+       }
+}
 
-bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err)
+bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err)
 {
-       enum async_req_state state;
+       enum tevent_req_state state;
        uint64_t error;
-       if (!async_req_is_error(req, &state, &error)) {
+       if (!tevent_req_is_error(req, &state, &error)) {
                *pwbc_err = WBC_ERR_SUCCESS;
                return false;
        }
 
        switch (state) {
-       case ASYNC_REQ_USER_ERROR:
+       case TEVENT_REQ_USER_ERROR:
                *pwbc_err = error;
                break;
-       case ASYNC_REQ_TIMED_OUT:
+       case TEVENT_REQ_TIMED_OUT:
                *pwbc_err = WBC_ERR_UNKNOWN_FAILURE;
                break;
-       case ASYNC_REQ_NO_MEMORY:
+       case TEVENT_REQ_NO_MEMORY:
                *pwbc_err = WBC_ERR_NO_MEMORY;
                break;
        default:
@@ -56,44 +65,34 @@ bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err)
        return true;
 }
 
-wbcErr map_wbc_err_from_errno(int error)
-{
-       switch(error) {
-       case EPERM:
-       case EACCES:
-               return WBC_ERR_AUTH_ERROR;
-       case ENOMEM:
-               return WBC_ERR_NO_MEMORY;
-       case EIO:
-       default:
-               return WBC_ERR_UNKNOWN_FAILURE;
-       }
-}
-
-wbcErr async_req_simple_recv_wbcerr(struct async_req *req)
+wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req)
 {
        wbcErr wbc_err;
 
-       if (async_req_is_wbcerr(req, &wbc_err)) {
+       if (tevent_req_is_wbcerr(req, &wbc_err)) {
                return wbc_err;
        }
 
        return WBC_ERR_SUCCESS;
 }
 
+struct req_read_state {
+       struct winbindd_request *wb_req;
+       size_t max_extra_data;
+};
+
 static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data);
 static void wb_req_read_done(struct tevent_req *subreq);
 
-struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
-                                  struct tevent_context *ev,
-                                  int fd, size_t max_extra_data)
+struct tevent_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
+                                   struct tevent_context *ev,
+                                   int fd, size_t max_extra_data)
 {
-       struct async_req *result;
-       struct tevent_req *subreq;
+       struct tevent_req *result, *subreq;
        struct req_read_state *state;
 
-       if (!async_req_setup(mem_ctx, &result, &state,
-                            struct req_read_state)) {
+       result = tevent_req_create(mem_ctx, &state, struct req_read_state);
+       if (result == NULL) {
                return NULL;
        }
        state->max_extra_data = max_extra_data;
@@ -103,8 +102,7 @@ struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
                goto nomem;
        }
 
-       subreq->async.fn = wb_req_read_done;
-       subreq->async.private_data = result;
+       tevent_req_set_callback(subreq, wb_req_read_done, result);
        return result;
  nomem:
        TALLOC_FREE(result);
@@ -140,10 +138,10 @@ static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data)
 
 static void wb_req_read_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.private_data, struct async_req);
-       struct req_read_state *state = talloc_get_type_abort(
-               req->private_data, struct req_read_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct req_read_state *state = tevent_req_data(
+               req, struct req_read_state);
        int err;
        ssize_t ret;
        uint8_t *buf;
@@ -151,7 +149,7 @@ static void wb_req_read_done(struct tevent_req *subreq)
        ret = read_packet_recv(subreq, state, &buf, &err);
        TALLOC_FREE(subreq);
        if (ret == -1) {
-               async_req_error(req, map_wbc_err_from_errno(err));
+               tevent_req_error(req, map_wbc_err_from_errno(err));
                return;
        }
 
@@ -163,17 +161,17 @@ static void wb_req_read_done(struct tevent_req *subreq)
        } else {
                state->wb_req->extra_data.data = NULL;
        }
-       async_req_done(req);
+       tevent_req_done(req);
 }
 
-wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+wbcErr wb_req_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                        struct winbindd_request **preq)
 {
-       struct req_read_state *state = talloc_get_type_abort(
-               req->private_data, struct req_read_state);
+       struct req_read_state *state = tevent_req_data(
+               req, struct req_read_state);
        wbcErr wbc_err;
 
-       if (async_req_is_wbcerr(req, &wbc_err)) {
+       if (tevent_req_is_wbcerr(req, &wbc_err)) {
                return wbc_err;
        }
        *preq = talloc_move(mem_ctx, &state->wb_req);
@@ -186,17 +184,17 @@ struct req_write_state {
 
 static void wb_req_write_done(struct tevent_req *subreq);
 
-struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
-                                   struct tevent_context *ev, int fd,
-                                   struct winbindd_request *wb_req)
+struct tevent_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
+                                    struct tevent_context *ev,
+                                    struct tevent_queue *queue, int fd,
+                                    struct winbindd_request *wb_req)
 {
-       struct async_req *result;
-       struct tevent_req *subreq;
+       struct tevent_req *result, *subreq;
        struct req_write_state *state;
        int count = 1;
 
-       if (!async_req_setup(mem_ctx, &result, &state,
-                            struct req_write_state)) {
+       result = tevent_req_create(mem_ctx, &state, struct req_write_state);
+       if (result == NULL) {
                return NULL;
        }
 
@@ -209,12 +207,11 @@ struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
                count = 2;
        }
 
-       subreq = writev_send(state, ev, fd, state->iov, count);
+       subreq = writev_send(state, ev, queue, fd, state->iov, count);
        if (subreq == NULL) {
                goto fail;
        }
-       subreq->async.fn = wb_req_write_done;
-       subreq->async.private_data = result;
+       tevent_req_set_callback(subreq, wb_req_write_done, result);
        return result;
 
  fail:
@@ -224,23 +221,23 @@ struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
 
 static void wb_req_write_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.private_data, struct async_req);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
        int err;
        ssize_t ret;
 
        ret = writev_recv(subreq, &err);
        TALLOC_FREE(subreq);
        if (ret < 0) {
-               async_req_error(req, map_wbc_err_from_errno(err));
+               tevent_req_error(req, map_wbc_err_from_errno(err));
                return;
        }
-       async_req_done(req);
+       tevent_req_done(req);
 }
 
-wbcErr wb_req_write_recv(struct async_req *req)
+wbcErr wb_req_write_recv(struct tevent_req *req)
 {
-       return async_req_simple_recv_wbcerr(req);
+       return tevent_req_simple_recv_wbcerr(req);
 }
 
 struct resp_read_state {
@@ -250,15 +247,14 @@ struct resp_read_state {
 static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data);
 static void wb_resp_read_done(struct tevent_req *subreq);
 
-struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
-                                   struct tevent_context *ev, int fd)
+struct tevent_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
+                                    struct tevent_context *ev, int fd)
 {
-       struct async_req *result;
-       struct tevent_req *subreq;
+       struct tevent_req *result, *subreq;
        struct resp_read_state *state;
 
-       if (!async_req_setup(mem_ctx, &result, &state,
-                            struct resp_read_state)) {
+       result = tevent_req_create(mem_ctx, &state, struct resp_read_state);
+       if (result == NULL) {
                return NULL;
        }
 
@@ -266,8 +262,7 @@ struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
        if (subreq == NULL) {
                goto nomem;
        }
-       subreq->async.fn = wb_resp_read_done;
-       subreq->async.private_data = result;
+       tevent_req_set_callback(subreq, wb_resp_read_done, result);
        return result;
 
  nomem:
@@ -293,10 +288,10 @@ static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data)
 
 static void wb_resp_read_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.private_data, struct async_req);
-       struct resp_read_state *state = talloc_get_type_abort(
-               req->private_data, struct resp_read_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct resp_read_state *state = tevent_req_data(
+               req, struct resp_read_state);
        uint8_t *buf;
        int err;
        ssize_t ret;
@@ -304,7 +299,7 @@ static void wb_resp_read_done(struct tevent_req *subreq)
        ret = read_packet_recv(subreq, state, &buf, &err);
        TALLOC_FREE(subreq);
        if (ret == -1) {
-               async_req_error(req, map_wbc_err_from_errno(err));
+               tevent_req_error(req, map_wbc_err_from_errno(err));
                return;
        }
 
@@ -316,17 +311,17 @@ static void wb_resp_read_done(struct tevent_req *subreq)
        } else {
                state->wb_resp->extra_data.data = NULL;
        }
-       async_req_done(req);
+       tevent_req_done(req);
 }
 
-wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+wbcErr wb_resp_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                         struct winbindd_response **presp)
 {
-       struct resp_read_state *state = talloc_get_type_abort(
-               req->private_data, struct resp_read_state);
+       struct resp_read_state *state = tevent_req_data(
+               req, struct resp_read_state);
        wbcErr wbc_err;
 
-       if (async_req_is_wbcerr(req, &wbc_err)) {
+       if (tevent_req_is_wbcerr(req, &wbc_err)) {
                return wbc_err;
        }
        *presp = talloc_move(mem_ctx, &state->wb_resp);
@@ -339,17 +334,17 @@ struct resp_write_state {
 
 static void wb_resp_write_done(struct tevent_req *subreq);
 
-struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
-                                   struct tevent_context *ev, int fd,
-                                   struct winbindd_response *wb_resp)
+struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
+                                     struct tevent_context *ev,
+                                     struct tevent_queue *queue, int fd,
+                                     struct winbindd_response *wb_resp)
 {
-       struct async_req *result;
-       struct tevent_req *subreq;
+       struct tevent_req *result, *subreq;
        struct resp_write_state *state;
        int count = 1;
 
-       if (!async_req_setup(mem_ctx, &result, &state,
-                            struct resp_write_state)) {
+       result = tevent_req_create(mem_ctx, &state, struct resp_write_state);
+       if (result == NULL) {
                return NULL;
        }
 
@@ -363,12 +358,11 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
                count = 2;
        }
 
-       subreq = writev_send(state, ev, fd, state->iov, count);
+       subreq = writev_send(state, ev, queue, fd, state->iov, count);
        if (subreq == NULL) {
                goto fail;
        }
-       subreq->async.fn = wb_resp_write_done;
-       subreq->async.private_data = result;
+       tevent_req_set_callback(subreq, wb_resp_write_done, result);
        return result;
 
  fail:
@@ -378,21 +372,21 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
 
 static void wb_resp_write_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.private_data, struct async_req);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
        int err;
        ssize_t ret;
 
        ret = writev_recv(subreq, &err);
        TALLOC_FREE(subreq);
        if (ret < 0) {
-               async_req_error(req, map_wbc_err_from_errno(err));
+               tevent_req_error(req, map_wbc_err_from_errno(err));
                return;
        }
-       async_req_done(req);
+       tevent_req_done(req);
 }
 
-wbcErr wb_resp_write_recv(struct async_req *req)
+wbcErr wb_resp_write_recv(struct tevent_req *req)
 {
-       return async_req_simple_recv_wbcerr(req);
+       return tevent_req_simple_recv_wbcerr(req);
 }
index b8d55a944a479edf92aaf295c8c02fff2a892be5..3cf992c7de9a8ec95208bcbbf5b84086c679b359 100644 (file)
 #include "includes.h"
 #include "wbc_async.h"
 
+struct wb_context {
+       struct tevent_queue *queue;
+       int fd;
+       bool is_priv;
+};
+
 static int make_nonstd_fd(int fd)
 {
        int i;
@@ -138,7 +144,7 @@ struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
        if (result == NULL) {
                return NULL;
        }
-       result->queue = async_req_queue_init(result);
+       result->queue = tevent_queue_create(result, "wb_trans");
        if (result->queue == NULL) {
                TALLOC_FREE(result);
                return NULL;
@@ -153,21 +159,20 @@ struct wb_connect_state {
 
 static void wbc_connect_connected(struct tevent_req *subreq);
 
-static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
+static struct tevent_req *wb_connect_send(TALLOC_CTX *mem_ctx,
                                          struct tevent_context *ev,
                                          struct wb_context *wb_ctx,
                                          const char *dir)
 {
-       struct async_req *result;
-       struct tevent_req *subreq;
+       struct tevent_req *result, *subreq;
        struct wb_connect_state *state;
        struct sockaddr_un sunaddr;
        struct stat st;
        char *path = NULL;
        wbcErr wbc_err;
 
-       if (!async_req_setup(mem_ctx, &result, &state,
-                            struct wb_connect_state)) {
+       result = tevent_req_create(mem_ctx, &state, struct wb_connect_state);
+       if (result == NULL) {
                return NULL;
        }
 
@@ -224,8 +229,7 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
        if (subreq == NULL) {
                goto nomem;
        }
-       subreq->async.fn = wbc_connect_connected;
-       subreq->async.private_data = result;
+       tevent_req_set_callback(subreq, wbc_connect_connected, result);
 
        if (!tevent_req_set_endtime(subreq, ev, timeval_current_ofs(30, 0))) {
                goto nomem;
@@ -233,59 +237,32 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
 
        return result;
 
- nomem:
-       wbc_err = WBC_ERR_NO_MEMORY;
  post_status:
-       if (async_post_error(result, ev, wbc_err)) {
-               return result;
-       }
+       tevent_req_error(result, wbc_err);
+       return tevent_req_post(result, ev);
+ nomem:
        TALLOC_FREE(result);
        return NULL;
 }
 
 static void wbc_connect_connected(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.private_data, struct async_req);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
        int res, err;
 
        res = async_connect_recv(subreq, &err);
        TALLOC_FREE(subreq);
        if (res == -1) {
-               async_req_error(req, map_wbc_err_from_errno(err));
+               tevent_req_error(req, map_wbc_err_from_errno(err));
                return;
        }
-       async_req_done(req);
+       tevent_req_done(req);
 }
 
-static wbcErr wb_connect_recv(struct async_req *req)
+static wbcErr wb_connect_recv(struct tevent_req *req)
 {
-       return async_req_simple_recv_wbcerr(req);
-}
-
-static struct winbindd_request *winbindd_request_copy(
-       TALLOC_CTX *mem_ctx,
-       const struct winbindd_request *req)
-{
-       struct winbindd_request *result;
-
-       result = (struct winbindd_request *)TALLOC_MEMDUP(
-               mem_ctx, req, sizeof(struct winbindd_request));
-       if (result == NULL) {
-               return NULL;
-       }
-
-       if (result->extra_len == 0) {
-               return result;
-       }
-
-       result->extra_data.data = (char *)TALLOC_MEMDUP(
-               result, result->extra_data.data, result->extra_len);
-       if (result->extra_data.data == NULL) {
-               TALLOC_FREE(result);
-               return NULL;
-       }
-       return result;
+       return tevent_req_simple_recv_wbcerr(req);
 }
 
 struct wb_int_trans_state {
@@ -295,43 +272,40 @@ struct wb_int_trans_state {
        struct winbindd_response *wb_resp;
 };
 
-static void wb_int_trans_write_done(struct async_req *subreq);
-static void wb_int_trans_read_done(struct async_req *subreq);
+static void wb_int_trans_write_done(struct tevent_req *subreq);
+static void wb_int_trans_read_done(struct tevent_req *subreq);
 
-static struct async_req *wb_int_trans_send(TALLOC_CTX *mem_ctx,
-                                          struct tevent_context *ev, int fd,
-                                          struct winbindd_request *wb_req)
+static struct tevent_req *wb_int_trans_send(TALLOC_CTX *mem_ctx,
+                                           struct tevent_context *ev,
+                                           struct tevent_queue *queue, int fd,
+                                           struct winbindd_request *wb_req)
 {
-       struct async_req *result;
-       struct async_req *subreq;
+       struct tevent_req *result, *subreq;
        struct wb_int_trans_state *state;
 
-       if (!async_req_setup(mem_ctx, &result, &state,
-                            struct wb_int_trans_state)) {
+       result = tevent_req_create(mem_ctx, &state,
+                                  struct wb_int_trans_state);
+       if (result == NULL) {
                return NULL;
        }
 
        if (winbind_closed_fd(fd)) {
-               if (!async_post_error(result, ev,
-                                     WBC_ERR_WINBIND_NOT_AVAILABLE)) {
-                       goto fail;
-               }
-               return result;
+               tevent_req_error(result, WBC_ERR_WINBIND_NOT_AVAILABLE);
+               return tevent_req_post(result, ev);
        }
 
        state->ev = ev;
        state->fd = fd;
        state->wb_req = wb_req;
-
        state->wb_req->length = sizeof(struct winbindd_request);
        state->wb_req->pid = getpid();
 
-       subreq = wb_req_write_send(state, state->ev, state->fd, state->wb_req);
+       subreq = wb_req_write_send(state, state->ev, queue, state->fd,
+                                  state->wb_req);
        if (subreq == NULL) {
                goto fail;
        }
-       subreq->async.fn = wb_int_trans_write_done;
-       subreq->async.priv = result;
+       tevent_req_set_callback(subreq, wb_int_trans_write_done, result);
 
        return result;
 
@@ -340,56 +314,55 @@ static struct async_req *wb_int_trans_send(TALLOC_CTX *mem_ctx,
        return NULL;
 }
 
-static void wb_int_trans_write_done(struct async_req *subreq)
+static void wb_int_trans_write_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       struct wb_int_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_int_trans_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct wb_int_trans_state *state = tevent_req_data(
+               req, struct wb_int_trans_state);
        wbcErr wbc_err;
 
        wbc_err = wb_req_write_recv(subreq);
        TALLOC_FREE(subreq);
        if (!WBC_ERROR_IS_OK(wbc_err)) {
-               async_req_error(req, wbc_err);
+               tevent_req_error(req, wbc_err);
                return;
        }
 
        subreq = wb_resp_read_send(state, state->ev, state->fd);
-       if (subreq == NULL) {
-               async_req_error(req, WBC_ERR_NO_MEMORY);
+       if (tevent_req_nomem(subreq, req)) {
+               return;
        }
-       subreq->async.fn = wb_int_trans_read_done;
-       subreq->async.priv = req;
+       tevent_req_set_callback(subreq, wb_int_trans_read_done, req);
 }
 
-static void wb_int_trans_read_done(struct async_req *subreq)
+static void wb_int_trans_read_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       struct wb_int_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_int_trans_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct wb_int_trans_state *state = tevent_req_data(
+               req, struct wb_int_trans_state);
        wbcErr wbc_err;
 
        wbc_err = wb_resp_read_recv(subreq, state, &state->wb_resp);
        TALLOC_FREE(subreq);
        if (!WBC_ERROR_IS_OK(wbc_err)) {
-               async_req_error(req, wbc_err);
+               tevent_req_error(req, wbc_err);
                return;
        }
 
-       async_req_done(req);
+       tevent_req_done(req);
 }
 
-static wbcErr wb_int_trans_recv(struct async_req *req,
+static wbcErr wb_int_trans_recv(struct tevent_req *req,
                                TALLOC_CTX *mem_ctx,
                                struct winbindd_response **presponse)
 {
-       struct wb_int_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_int_trans_state);
+       struct wb_int_trans_state *state = tevent_req_data(
+               req, struct wb_int_trans_state);
        wbcErr wbc_err;
 
-       if (async_req_is_wbcerr(req, &wbc_err)) {
+       if (tevent_req_is_wbcerr(req, &wbc_err)) {
                return wbc_err;
        }
 
@@ -418,22 +391,21 @@ struct wb_open_pipe_state {
        struct winbindd_request wb_req;
 };
 
-static void wb_open_pipe_connect_nonpriv_done(struct async_req *subreq);
-static void wb_open_pipe_ping_done(struct async_req *subreq);
-static void wb_open_pipe_getpriv_done(struct async_req *subreq);
-static void wb_open_pipe_connect_priv_done(struct async_req *subreq);
+static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq);
+static void wb_open_pipe_ping_done(struct tevent_req *subreq);
+static void wb_open_pipe_getpriv_done(struct tevent_req *subreq);
+static void wb_open_pipe_connect_priv_done(struct tevent_req *subreq);
 
-static struct async_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx,
-                                          struct tevent_context *ev,
-                                          struct wb_context *wb_ctx,
-                                          bool need_priv)
+static struct tevent_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx,
+                                           struct tevent_context *ev,
+                                           struct wb_context *wb_ctx,
+                                           bool need_priv)
 {
-       struct async_req *result;
-       struct async_req *subreq;
+       struct tevent_req *result, *subreq;
        struct wb_open_pipe_state *state;
 
-       if (!async_req_setup(mem_ctx, &result, &state,
-                            struct wb_open_pipe_state)) {
+       result = tevent_req_create(mem_ctx, &state, struct wb_open_pipe_state);
+       if (result == NULL) {
                return NULL;
        }
        state->wb_ctx = wb_ctx;
@@ -449,9 +421,8 @@ static struct async_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx,
        if (subreq == NULL) {
                goto fail;
        }
-
-       subreq->async.fn = wb_open_pipe_connect_nonpriv_done;
-       subreq->async.priv = result;
+       tevent_req_set_callback(subreq, wb_open_pipe_connect_nonpriv_done,
+                               result);
        return result;
 
  fail:
@@ -459,81 +430,77 @@ static struct async_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx,
        return NULL;
 }
 
-static void wb_open_pipe_connect_nonpriv_done(struct async_req *subreq)
+static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       struct wb_open_pipe_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_open_pipe_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct wb_open_pipe_state *state = tevent_req_data(
+               req, struct wb_open_pipe_state);
        wbcErr wbc_err;
 
        wbc_err = wb_connect_recv(subreq);
        TALLOC_FREE(subreq);
        if (!WBC_ERROR_IS_OK(wbc_err)) {
                state->wb_ctx->is_priv = true;
-               async_req_error(req, wbc_err);
+               tevent_req_error(req, wbc_err);
                return;
        }
 
        ZERO_STRUCT(state->wb_req);
        state->wb_req.cmd = WINBINDD_INTERFACE_VERSION;
 
-       subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
+       subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd,
                                   &state->wb_req);
-       if (async_req_nomem(subreq, req)) {
+       if (tevent_req_nomem(subreq, req)) {
                return;
        }
-
-       subreq->async.fn = wb_open_pipe_ping_done;
-       subreq->async.priv = req;
+       tevent_req_set_callback(subreq, wb_open_pipe_ping_done, req);
 }
 
-static void wb_open_pipe_ping_done(struct async_req *subreq)
+static void wb_open_pipe_ping_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       struct wb_open_pipe_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_open_pipe_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct wb_open_pipe_state *state = tevent_req_data(
+               req, struct wb_open_pipe_state);
        struct winbindd_response *wb_resp;
        wbcErr wbc_err;
 
        wbc_err = wb_int_trans_recv(subreq, state, &wb_resp);
        TALLOC_FREE(subreq);
        if (!WBC_ERROR_IS_OK(wbc_err)) {
-               async_req_error(req, wbc_err);
+               tevent_req_error(req, wbc_err);
                return;
        }
 
        if (!state->need_priv) {
-               async_req_done(req);
+               tevent_req_done(req);
                return;
        }
 
        state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR;
 
-       subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
+       subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd,
                                   &state->wb_req);
-       if (async_req_nomem(subreq, req)) {
+       if (tevent_req_nomem(subreq, req)) {
                return;
        }
-
-       subreq->async.fn = wb_open_pipe_getpriv_done;
-       subreq->async.priv = req;
+       tevent_req_set_callback(subreq, wb_open_pipe_getpriv_done, req);
 }
 
-static void wb_open_pipe_getpriv_done(struct async_req *subreq)
+static void wb_open_pipe_getpriv_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       struct wb_open_pipe_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_open_pipe_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct wb_open_pipe_state *state = tevent_req_data(
+               req, struct wb_open_pipe_state);
        struct winbindd_response *wb_resp = NULL;
        wbcErr wbc_err;
 
        wbc_err = wb_int_trans_recv(subreq, state, &wb_resp);
        TALLOC_FREE(subreq);
        if (!WBC_ERROR_IS_OK(wbc_err)) {
-               async_req_error(req, wbc_err);
+               tevent_req_error(req, wbc_err);
                return;
        }
 
@@ -541,37 +508,35 @@ static void wb_open_pipe_getpriv_done(struct async_req *subreq)
        state->wb_ctx->fd = -1;
 
        subreq = wb_connect_send(state, state->ev, state->wb_ctx,
-                                (char *)wb_resp->extra_data.data);
+                                 (char *)wb_resp->extra_data.data);
        TALLOC_FREE(wb_resp);
-       if (async_req_nomem(subreq, req)) {
+       if (tevent_req_nomem(subreq, req)) {
                return;
        }
-
-       subreq->async.fn = wb_open_pipe_connect_priv_done;
-       subreq->async.priv = req;
+       tevent_req_set_callback(subreq, wb_open_pipe_connect_priv_done, req);
 }
 
-static void wb_open_pipe_connect_priv_done(struct async_req *subreq)
+static void wb_open_pipe_connect_priv_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       struct wb_open_pipe_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_open_pipe_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct wb_open_pipe_state *state = tevent_req_data(
+               req, struct wb_open_pipe_state);
        wbcErr wbc_err;
 
        wbc_err = wb_connect_recv(subreq);
        TALLOC_FREE(subreq);
        if (!WBC_ERROR_IS_OK(wbc_err)) {
-               async_req_error(req, wbc_err);
+               tevent_req_error(req, wbc_err);
                return;
        }
        state->wb_ctx->is_priv = true;
-       async_req_done(req);
+       tevent_req_done(req);
 }
 
-static wbcErr wb_open_pipe_recv(struct async_req *req)
+static wbcErr wb_open_pipe_recv(struct tevent_req *req)
 {
-       return async_req_simple_recv_wbcerr(req);
+       return tevent_req_simple_recv_wbcerr(req);
 }
 
 struct wb_trans_state {
@@ -584,73 +549,54 @@ struct wb_trans_state {
        bool need_priv;
 };
 
-static void wb_trans_connect_done(struct async_req *subreq);
-static void wb_trans_done(struct async_req *subreq);
-static void wb_trans_retry_wait_done(struct async_req *subreq);
-
-static void wb_trigger_trans(struct async_req *req)
-{
-       struct wb_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_trans_state);
-       struct async_req *subreq;
-
-       if ((state->wb_ctx->fd == -1)
-           || (state->need_priv && !state->wb_ctx->is_priv)) {
-
-               subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
-                                          state->need_priv);
-               if (async_req_nomem(subreq, req)) {
-                       return;
-               }
-               subreq->async.fn = wb_trans_connect_done;
-               subreq->async.priv = req;
-               return;
-       }
-
-       subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
-                                  state->wb_req);
-       if (async_req_nomem(subreq, req)) {
-               return;
-       }
-       subreq->async.fn = wb_trans_done;
-       subreq->async.priv = req;
-}
+static void wb_trans_connect_done(struct tevent_req *subreq);
+static void wb_trans_done(struct tevent_req *subreq);
+static void wb_trans_retry_wait_done(struct tevent_req *subreq);
 
-struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
-                               struct wb_context *wb_ctx, bool need_priv,
-                               const struct winbindd_request *wb_req)
+struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
+                                struct tevent_context *ev,
+                                struct wb_context *wb_ctx, bool need_priv,
+                                struct winbindd_request *wb_req)
 {
-       struct async_req *result;
+       struct tevent_req *req, *subreq;
        struct wb_trans_state *state;
 
-       if (!async_req_setup(mem_ctx, &result, &state,
-                            struct wb_trans_state)) {
+       req = tevent_req_create(mem_ctx, &state, struct wb_trans_state);
+       if (req == NULL) {
                return NULL;
        }
        state->wb_ctx = wb_ctx;
        state->ev = ev;
-       state->wb_req = winbindd_request_copy(state, wb_req);
-       if (state->wb_req == NULL) {
-               goto fail;
-       }
+       state->wb_req = wb_req;
        state->num_retries = 10;
        state->need_priv = need_priv;
 
-       if (!async_req_enqueue(wb_ctx->queue, ev, result, wb_trigger_trans)) {
-               goto fail;
+       if ((wb_ctx->fd == -1) || (need_priv && !wb_ctx->is_priv)) {
+               subreq = wb_open_pipe_send(state, ev, wb_ctx, need_priv);
+               if (subreq == NULL) {
+                       goto fail;
+               }
+               tevent_req_set_callback(subreq, wb_trans_connect_done, req);
+               return req;
        }
-       return result;
 
+       subreq = wb_int_trans_send(state, ev, wb_ctx->queue, wb_ctx->fd,
+                                  wb_req);
+       if (subreq == NULL) {
+               goto fail;
+       }
+       tevent_req_set_callback(subreq, wb_trans_done, req);
+       return req;
  fail:
-       TALLOC_FREE(result);
+       TALLOC_FREE(req);
        return NULL;
 }
 
-static bool wb_trans_retry(struct async_req *req,
+static bool wb_trans_retry(struct tevent_req *req,
                           struct wb_trans_state *state,
                           wbcErr wbc_err)
 {
-       struct async_req *subreq;
+       struct tevent_req *subreq;
 
        if (WBC_ERROR_IS_OK(wbc_err)) {
                return false;
@@ -661,13 +607,13 @@ static bool wb_trans_retry(struct async_req *req,
                 * Winbind not around or we can't connect to the pipe. Fail
                 * immediately.
                 */
-               async_req_error(req, wbc_err);
+               tevent_req_error(req, wbc_err);
                return true;
        }
 
        state->num_retries -= 1;
        if (state->num_retries == 0) {
-               async_req_error(req, wbc_err);
+               tevent_req_error(req, wbc_err);
                return true;
        }
 
@@ -680,46 +626,44 @@ static bool wb_trans_retry(struct async_req *req,
                state->wb_ctx->fd = -1;
        }
 
-       subreq = async_wait_send(state, state->ev, timeval_set(1, 0));
-       if (async_req_nomem(subreq, req)) {
+       subreq = tevent_wakeup_send(state, state->ev,
+                                   timeval_current_ofs(1, 0));
+       if (tevent_req_nomem(subreq, req)) {
                return true;
        }
-
-       subreq->async.fn = wb_trans_retry_wait_done;
-       subreq->async.priv = req;
+       tevent_req_set_callback(subreq, wb_trans_retry_wait_done, req);
        return true;
 }
 
-static void wb_trans_retry_wait_done(struct async_req *subreq)
+static void wb_trans_retry_wait_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       struct wb_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_trans_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct wb_trans_state *state = tevent_req_data(
+               req, struct wb_trans_state);
        bool ret;
 
-       ret = async_wait_recv(subreq);
+       ret = tevent_wakeup_recv(subreq);
        TALLOC_FREE(subreq);
-       if (ret) {
-               async_req_error(req, WBC_ERR_UNKNOWN_FAILURE);
+       if (!ret) {
+               tevent_req_error(req, WBC_ERR_UNKNOWN_FAILURE);
                return;
        }
 
        subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
                                   state->need_priv);
-       if (async_req_nomem(subreq, req)) {
+       if (tevent_req_nomem(subreq, req)) {
                return;
        }
-       subreq->async.fn = wb_trans_connect_done;
-       subreq->async.priv = req;
+       tevent_req_set_callback(subreq, wb_trans_connect_done, req);
 }
 
-static void wb_trans_connect_done(struct async_req *subreq)
+static void wb_trans_connect_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       struct wb_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_trans_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct wb_trans_state *state = tevent_req_data(
+               req, struct wb_trans_state);
        wbcErr wbc_err;
 
        wbc_err = wb_open_pipe_recv(subreq);
@@ -729,22 +673,20 @@ static void wb_trans_connect_done(struct async_req *subreq)
                return;
        }
 
-       subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
+       subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd,
                                   state->wb_req);
-       if (async_req_nomem(subreq, req)) {
+       if (tevent_req_nomem(subreq, req)) {
                return;
        }
-
-       subreq->async.fn = wb_trans_done;
-       subreq->async.priv = req;
+       tevent_req_set_callback(subreq, wb_trans_done, req);
 }
 
-static void wb_trans_done(struct async_req *subreq)
+static void wb_trans_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       struct wb_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_trans_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct wb_trans_state *state = tevent_req_data(
+               req, struct wb_trans_state);
        wbcErr wbc_err;
 
        wbc_err = wb_int_trans_recv(subreq, state, &state->wb_resp);
@@ -754,17 +696,17 @@ static void wb_trans_done(struct async_req *subreq)
                return;
        }
 
-       async_req_done(req);
+       tevent_req_done(req);
 }
 
-wbcErr wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                     struct winbindd_response **presponse)
 {
-       struct wb_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_trans_state);
+       struct wb_trans_state *state = tevent_req_data(
+               req, struct wb_trans_state);
        wbcErr wbc_err;
 
-       if (async_req_is_wbcerr(req, &wbc_err)) {
+       if (tevent_req_is_wbcerr(req, &wbc_err)) {
                return wbc_err;
        }
 
index 64f5fb421a9a6df59b3799455b4c5cf479f12dd5..df095b9e91c1b84c81953f95255c446110f29f38 100644 (file)
@@ -322,7 +322,6 @@ bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx,
                               &rids,
                               &num_rids);
        if (ret != WBC_ERR_SUCCESS) {
-               wbcFreeMemory(rids);
                return false;
        }
 
index 57a9b6a0020d6c74ef4690c64b1ccb26a2300d2a..a04a13bfd96a7027257970b2368555f8a1575ce4 100644 (file)
@@ -133,7 +133,9 @@ void *talloc_zeronull(const void *context, size_t size, const char *name);
 #define TALLOC_REALLOC(ctx, ptr, count) _talloc_realloc(ctx, ptr, count, __location__)
 #define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)_talloc_realloc_array(ctx, ptr, sizeof(type), count, #type)
 #define talloc_destroy(ctx) talloc_free(ctx)
+#ifndef TALLOC_FREE
 #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
+#endif
 
 /*******************************************************************
    Type definitions for int16, int32, uint16 and uint32.  Needed
index d66e35cacb89a4eca68430a8ee6677b2ce14f7e3..d941ba60cd628d702790c8ef4989879802189df5 100644 (file)
@@ -4,6 +4,7 @@
    Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
    Copyright (C) 2003 Jim McDonough (jmcd@us.ibm.com)
    Copyright (C) 2008 Guenther Deschner (gd@samba.org)
+   Copyright (C) 2009 Stefan Metzmacher (metze@samba.org)
 
    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
 */
 
 #include "includes.h"
-
-/*
-  do a cldap netlogon query
-*/
-static int send_cldap_netlogon(TALLOC_CTX *mem_ctx, int sock, const char *domain,
-                              const char *hostname, unsigned ntversion)
-{
-       ASN1_DATA *data;
-       char ntver[4];
-#ifdef CLDAP_USER_QUERY
-       char aac[4];
-
-       SIVAL(aac, 0, 0x00000180);
-#endif
-       SIVAL(ntver, 0, ntversion);
-
-       data = asn1_init(mem_ctx);
-       if (data == NULL) {
-               return -1;
-       }
-
-       asn1_push_tag(data,ASN1_SEQUENCE(0));
-       asn1_write_Integer(data, 4);
-       asn1_push_tag(data, ASN1_APPLICATION(3));
-       asn1_write_OctetString(data, NULL, 0);
-       asn1_write_enumerated(data, 0);
-       asn1_write_enumerated(data, 0);
-       asn1_write_Integer(data, 0);
-       asn1_write_Integer(data, 0);
-       asn1_write_BOOLEAN(data, False);
-       asn1_push_tag(data, ASN1_CONTEXT(0));
-
-       if (domain) {
-               asn1_push_tag(data, ASN1_CONTEXT(3));
-               asn1_write_OctetString(data, "DnsDomain", 9);
-               asn1_write_OctetString(data, domain, strlen(domain));
-               asn1_pop_tag(data);
-       }
-
-       asn1_push_tag(data, ASN1_CONTEXT(3));
-       asn1_write_OctetString(data, "Host", 4);
-       asn1_write_OctetString(data, hostname, strlen(hostname));
-       asn1_pop_tag(data);
-
-#ifdef CLDAP_USER_QUERY
-       asn1_push_tag(data, ASN1_CONTEXT(3));
-       asn1_write_OctetString(data, "User", 4);
-       asn1_write_OctetString(data, "SAMBA$", 6);
-       asn1_pop_tag(data);
-
-       asn1_push_tag(data, ASN1_CONTEXT(3));
-       asn1_write_OctetString(data, "AAC", 4);
-       asn1_write_OctetString(data, aac, 4);
-       asn1_pop_tag(data);
-#endif
-
-       asn1_push_tag(data, ASN1_CONTEXT(3));
-       asn1_write_OctetString(data, "NtVer", 5);
-       asn1_write_OctetString(data, ntver, 4);
-       asn1_pop_tag(data);
-
-       asn1_pop_tag(data);
-
-       asn1_push_tag(data,ASN1_SEQUENCE(0));
-       asn1_write_OctetString(data, "NetLogon", 8);
-       asn1_pop_tag(data);
-       asn1_pop_tag(data);
-       asn1_pop_tag(data);
-
-       if (data->has_error) {
-               DEBUG(2,("Failed to build cldap netlogon at offset %d\n", (int)data->ofs));
-               asn1_free(data);
-               return -1;
-       }
-
-       if (write(sock, data->data, data->length) != (ssize_t)data->length) {
-               DEBUG(2,("failed to send cldap query (%s)\n", strerror(errno)));
-               asn1_free(data);
-               return -1;
-       }
-
-       asn1_free(data);
-
-       return 0;
-}
-
-/*
-  receive a cldap netlogon reply
-*/
-static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx,
-                              int sock,
-                              uint32_t nt_version,
-                              struct netlogon_samlogon_response **reply)
-{
-       int ret;
-       ASN1_DATA *data;
-       DATA_BLOB blob = data_blob_null;
-       DATA_BLOB os1 = data_blob_null;
-       DATA_BLOB os2 = data_blob_null;
-       DATA_BLOB os3 = data_blob_null;
-       int i1;
-       struct netlogon_samlogon_response *r = NULL;
-       NTSTATUS status;
-
-       fd_set r_fds;
-       struct timeval timeout;
-
-       blob = data_blob(NULL, 8192);
-       if (blob.data == NULL) {
-               DEBUG(1, ("data_blob failed\n"));
-               errno = ENOMEM;
-               return -1;
-       }
-
-       FD_ZERO(&r_fds);
-       FD_SET(sock, &r_fds);
-
-       /*
-        * half the time of a regular ldap timeout, not less than 3 seconds.
-        */
-       timeout.tv_sec = MAX(3,lp_ldap_timeout()/2);
-       timeout.tv_usec = 0;
-
-       ret = sys_select(sock+1, &r_fds, NULL, NULL, &timeout);
-       if (ret == -1) {
-               DEBUG(10, ("select failed: %s\n", strerror(errno)));
-               data_blob_free(&blob);
-               return -1;
-       }
-
-       if (ret == 0) {
-               DEBUG(1,("no reply received to cldap netlogon\n"));
-               data_blob_free(&blob);
-               return -1;
-       }
-
-       ret = read(sock, blob.data, blob.length);
-       if (ret <= 0) {
-               DEBUG(1,("no reply received to cldap netlogon\n"));
-               data_blob_free(&blob);
-               return -1;
-       }
-       blob.length = ret;
-
-       data = asn1_init(mem_ctx);
-       if (data == NULL) {
-               data_blob_free(&blob);
-               return -1;
-       }
-
-       asn1_load(data, blob);
-       asn1_start_tag(data, ASN1_SEQUENCE(0));
-       asn1_read_Integer(data, &i1);
-       asn1_start_tag(data, ASN1_APPLICATION(4));
-       asn1_read_OctetString(data, NULL, &os1);
-       asn1_start_tag(data, ASN1_SEQUENCE(0));
-       asn1_start_tag(data, ASN1_SEQUENCE(0));
-       asn1_read_OctetString(data, NULL, &os2);
-       asn1_start_tag(data, ASN1_SET);
-       asn1_read_OctetString(data, NULL, &os3);
-       asn1_end_tag(data);
-       asn1_end_tag(data);
-       asn1_end_tag(data);
-       asn1_end_tag(data);
-       asn1_end_tag(data);
-
-       if (data->has_error) {
-               data_blob_free(&blob);
-               data_blob_free(&os1);
-               data_blob_free(&os2);
-               data_blob_free(&os3);
-               asn1_free(data);
-               DEBUG(1,("Failed to parse cldap reply\n"));
-               return -1;
-       }
-
-       r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response);
-       if (!r) {
-               errno = ENOMEM;
-               data_blob_free(&os1);
-               data_blob_free(&os2);
-               data_blob_free(&os3);
-               data_blob_free(&blob);
-               asn1_free(data);
-               return -1;
-       }
-
-       status = pull_netlogon_samlogon_response(&os3, mem_ctx, NULL, r);
-       if (!NT_STATUS_IS_OK(status)) {
-               data_blob_free(&os1);
-               data_blob_free(&os2);
-               data_blob_free(&os3);
-               data_blob_free(&blob);
-               asn1_free(data);
-               TALLOC_FREE(r);
-               return -1;
-       }
-
-       map_netlogon_samlogon_response(r);
-
-       data_blob_free(&os1);
-       data_blob_free(&os2);
-       data_blob_free(&os3);
-       data_blob_free(&blob);
-
-       asn1_free(data);
-
-       if (reply) {
-               *reply = r;
-       } else {
-               TALLOC_FREE(r);
-       }
-
-       return 0;
-}
+#include "../libcli/cldap/cldap.h"
+#include "../lib/tsocket/tsocket.h"
 
 /*******************************************************************
   do a cldap netlogon query.  Always 389/udp
@@ -244,31 +32,81 @@ bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx,
                        const char *server,
                        const char *realm,
                        uint32_t nt_version,
-                       struct netlogon_samlogon_response **reply)
+                       struct netlogon_samlogon_response **_reply)
 {
-       int sock;
+       struct cldap_socket *cldap;
+       struct cldap_netlogon io;
+       struct netlogon_samlogon_response *reply;
+       NTSTATUS status;
+       struct in_addr addr;
+       char addrstr[INET_ADDRSTRLEN];
+       const char *dest_str;
        int ret;
+       struct tsocket_address *dest_addr;
 
-       sock = open_udp_socket(server, LDAP_PORT );
-       if (sock == -1) {
-               DEBUG(2,("ads_cldap_netlogon: Failed to open udp socket to %s\n", 
+       addr = interpret_addr2(server);
+       dest_str = inet_ntop(AF_INET, &addr,
+                            addrstr, sizeof(addrstr));
+       if (!dest_str) {
+               DEBUG(2,("Failed to resolve[%s] into an address for cldap\n",
                         server));
-               return False;
+               return false;
        }
 
-       ret = send_cldap_netlogon(mem_ctx, sock, realm, global_myname(), nt_version);
+       ret = tsocket_address_inet_from_strings(mem_ctx, "ipv4",
+                                               dest_str, LDAP_PORT,
+                                               &dest_addr);
        if (ret != 0) {
-               close(sock);
-               return False;
+               status = map_nt_error_from_unix(errno);
+               DEBUG(2,("Failed to create cldap tsocket_address for %s - %s\n",
+                        dest_str, nt_errstr(status)));
+               return false;
+       }
+
+       /*
+        * as we use a connected udp socket
+        */
+       status = cldap_socket_init(mem_ctx, NULL, NULL, dest_addr, &cldap);
+       TALLOC_FREE(dest_addr);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(2,("Failed to create cldap socket to %s: %s\n",
+                        dest_str, nt_errstr(status)));
+               return false;
        }
-       ret = recv_cldap_netlogon(mem_ctx, sock, nt_version, reply);
-       close(sock);
 
-       if (ret == -1) {
-               return False;
+       reply = talloc(cldap, struct netlogon_samlogon_response);
+       if (!reply) {
+               goto failed;
        }
 
-       return True;
+       /*
+        * as we use a connected socket, so we don't need to specify the
+        * destination
+        */
+       io.in.dest_address      = NULL;
+       io.in.dest_port         = 0;
+       io.in.realm             = realm;
+       io.in.host              = NULL;
+       io.in.user              = NULL;
+       io.in.domain_guid       = NULL;
+       io.in.domain_sid        = NULL;
+       io.in.acct_control      = 0;
+       io.in.version           = nt_version;
+       io.in.map_response      = false;
+
+       status = cldap_netlogon(cldap, NULL, reply, &io);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(2,("cldap_netlogon() failed: %s\n", nt_errstr(status)));
+               goto failed;
+       }
+
+       *reply = io.out.netlogon;
+       *_reply = talloc_move(mem_ctx, &reply);
+       TALLOC_FREE(cldap);
+       return true;
+failed:
+       TALLOC_FREE(cldap);
+       return false;
 }
 
 /*******************************************************************
index 53023cc75a5c7b6553937c420963402bfc18fce2..0e03ebb90ddff83ee4847dd45e8888b8d610c81c 100644 (file)
@@ -30,12 +30,10 @@ static const struct {
        {KRB5KDC_ERR_CLIENT_REVOKED, NT_STATUS_ACCESS_DENIED},
        {KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, NT_STATUS_INVALID_ACCOUNT_NAME},
        {KRB5KDC_ERR_ETYPE_NOSUPP, NT_STATUS_LOGON_FAILURE},
-#if defined(KRB5KDC_ERR_KEY_EXPIRED) /* Heimdal */
-       {KRB5KDC_ERR_KEY_EXPIRED, NT_STATUS_PASSWORD_EXPIRED},
-#elif defined(KRB5KDC_ERR_KEY_EXP) /* MIT */
+#if defined(KRB5KDC_ERR_KEY_EXP) /* MIT */
        {KRB5KDC_ERR_KEY_EXP, NT_STATUS_PASSWORD_EXPIRED},
-#else 
-#error Neither KRB5KDC_ERR_KEY_EXPIRED nor KRB5KDC_ERR_KEY_EXP available
+#else /* old Heimdal releases have it with different name only in an enum: */
+       {KRB5KDC_ERR_KEY_EXPIRED, NT_STATUS_PASSWORD_EXPIRED},
 #endif
        {25, NT_STATUS_PASSWORD_EXPIRED}, /* FIXME: bug in heimdal 0.7 krb5_get_init_creds_password (Inappropriate ioctl for device (25)) */
        {KRB5KDC_ERR_NULL_KEY, NT_STATUS_LOGON_FAILURE},
index a61df3c9bd3ad2e53f189c0b1bebb05377d1727d..9be366dc29d599334c443a6da3b6935984325b6e 100644 (file)
@@ -311,9 +311,10 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli,
 {
        WERROR result;
        char *printername;
-       REGVAL_CTR *dsdriver_ctr, *dsspooler_ctr;
+       struct spoolss_PrinterEnumValues *info;
+       uint32_t count;
        uint32 i;
-       POLICY_HND pol;
+       struct policy_handle pol;
 
        if ((asprintf(&printername, "%s\\%s", cli->srv_name_slash, printer) == -1)) {
                DEBUG(3, ("Insufficient memory\n"));
@@ -330,48 +331,64 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli,
                SAFE_FREE(printername);
                return result;
        }
-       
-       if ( !(dsdriver_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )  {
-               SAFE_FREE(printername);
-               return WERR_NOMEM;
-       }
 
-       result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr);
+       result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol,
+                                                 SPOOL_DSDRIVER_KEY,
+                                                 0,
+                                                 &count,
+                                                 &info);
 
        if (!W_ERROR_IS_OK(result)) {
                DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
                          printername, win_errstr(result)));
        } else {
-               uint32 num_values = regval_ctr_numvals( dsdriver_ctr );
-
                /* Have the data we need now, so start building */
-               for (i=0; i < num_values; i++) {
-                       map_regval_to_ads(mem_ctx, mods, dsdriver_ctr->values[i]);
+               for (i=0; i < count; i++) {
+                       REGISTRY_VALUE v;
+                       DATA_BLOB blob;
+
+                       result = push_spoolss_PrinterData(mem_ctx, &blob,
+                                                         info[i].type,
+                                                         info[i].data);
+                       if (W_ERROR_IS_OK(result)) {
+                               fstrcpy(v.valuename, info[i].value_name);
+                               v.type = info[i].type;
+                               v.data_p = blob.data;
+                               v.size = blob.length;
+
+                               map_regval_to_ads(mem_ctx, mods, &v);
+                       }
                }
        }
-       
-       if ( !(dsspooler_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) {
-               SAFE_FREE(printername);
-               return WERR_NOMEM;
-       }
-
-       result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr);
 
+       result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol,
+                                                 SPOOL_DSSPOOLER_KEY,
+                                                 0,
+                                                 &count,
+                                                 &info);
        if (!W_ERROR_IS_OK(result)) {
                DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
                          printername, win_errstr(result)));
        } else {
-               uint32 num_values = regval_ctr_numvals( dsspooler_ctr );
-
-               for (i=0; i<num_values; i++) {
-                       map_regval_to_ads(mem_ctx, mods, dsspooler_ctr->values[i]);
+               for (i=0; i < count; i++) {
+                       REGISTRY_VALUE v;
+                       DATA_BLOB blob;
+
+                       result = push_spoolss_PrinterData(mem_ctx, &blob,
+                                                         info[i].type,
+                                                         info[i].data);
+                       if (W_ERROR_IS_OK(result)) {
+                               fstrcpy(v.valuename, info[i].value_name);
+                               v.type = info[i].type;
+                               v.data_p = blob.data;
+                               v.size = blob.length;
+
+                               map_regval_to_ads(mem_ctx, mods, &v);
+                       }
                }
        }
-       
-       ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
 
-       TALLOC_FREE( dsdriver_ctr );
-       TALLOC_FREE( dsspooler_ctr );
+       ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
 
        rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
        SAFE_FREE(printername);
index 117178f3766812d7526bd25c46dbb3470d059c59..ccfd943a8de1c61aa4b3dab2ab8fff15570dfb04 100644 (file)
@@ -680,7 +680,7 @@ static NTSTATUS libnet_join_lookup_dc_rpc(TALLOC_CTX *mem_ctx,
                                          struct cli_state **cli)
 {
        struct rpc_pipe_client *pipe_hnd = NULL;
-       POLICY_HND lsa_pol;
+       struct policy_handle lsa_pol;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
        union lsa_PolicyInformation *info = NULL;
 
@@ -750,7 +750,7 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
                                           struct cli_state *cli)
 {
        struct rpc_pipe_client *pipe_hnd = NULL;
-       POLICY_HND sam_pol, domain_pol, user_pol;
+       struct policy_handle sam_pol, domain_pol, user_pol;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
        char *acct_name;
        struct lsa_String lsa_acct_name;
@@ -1132,7 +1132,7 @@ static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx,
 {
        struct cli_state *cli = NULL;
        struct rpc_pipe_client *pipe_hnd = NULL;
-       POLICY_HND sam_pol, domain_pol, user_pol;
+       struct policy_handle sam_pol, domain_pol, user_pol;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
        char *acct_name;
        uint32_t user_rid;
index ad11ee0ed411fe6dabfe57e4df4b514679f845c4..ebb01c44a6aefd812c89e8648df2a542c456735c 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;
        }
@@ -379,6 +389,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
        DATA_BLOB session_key = data_blob_null;
        NTSTATUS result;
        char *p;
+       bool ok;
 
        if (passlen == 0) {
                /* do nothing - guest login */
@@ -436,11 +447,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
                        SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
 #endif
                }
-#ifdef LANMAN_ONLY
-               cli_simple_set_signing(cli, session_key, lm_response); 
-#else
-               cli_simple_set_signing(cli, session_key, nt_response); 
-#endif
+               cli_temp_set_signing(cli);
        } else {
                /* pre-encrypted password supplied.  Only used for 
                   security=server, can't do
@@ -492,6 +499,22 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
                goto end;
        }
 
+#ifdef LANMAN_ONLY
+       ok = cli_simple_set_signing(cli, session_key, lm_response);
+#else
+       ok = cli_simple_set_signing(cli, session_key, nt_response);
+#endif
+       if (ok) {
+               /* 'resign' the last message, so we get the right sequence numbers
+                  for checking the first reply from the server */
+               cli_calculate_sign_mac(cli, cli->outbuf);
+
+               if (!cli_check_sign_mac(cli, cli->inbuf)) {
+                       result = NT_STATUS_ACCESS_DENIED;
+                       goto end;
+               }
+       }
+
        /* use the returned vuid from now on */
        cli->vuid = SVAL(cli->inbuf,smb_uid);
        
@@ -507,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 */
@@ -885,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));
 
@@ -923,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
@@ -1284,10 +1314,17 @@ struct async_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
        return result;
 
  access_denied:
-       result = async_req_new(mem_ctx);
-       if (async_post_ntstatus(result, ev, NT_STATUS_ACCESS_DENIED)) {
-               return result;
+       {
+               struct cli_request *state;
+               if (!async_req_setup(mem_ctx, &result, &state,
+                                    struct cli_request)) {
+                       goto fail;
+               }
+               if (async_post_ntstatus(result, ev, NT_STATUS_ACCESS_DENIED)) {
+                       return result;
+               }
        }
+ fail:
        TALLOC_FREE(result);
        return NULL;
 }
@@ -1748,15 +1785,20 @@ bool cli_session_request(struct cli_state *cli,
        return(True);
 }
 
-static void smb_sock_connected(struct async_req *req)
+struct fd_struct {
+       int fd;
+};
+
+static void smb_sock_connected(struct tevent_req *req)
 {
-       int *pfd = (int *)req->async.priv;
+       struct fd_struct *pfd = tevent_req_callback_data(
+               req, struct fd_struct);
        int fd;
        NTSTATUS status;
 
        status = open_socket_out_defer_recv(req, &fd);
        if (NT_STATUS_IS_OK(status)) {
-               *pfd = fd;
+               pfd->fd = fd;
        }
 }
 
@@ -1764,10 +1806,9 @@ static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
                                uint16_t *port, int timeout, int *pfd)
 {
        struct event_context *ev;
-       struct async_req *r139, *r445;
-       int fd139 = -1;
-       int fd445 = -1;
-       NTSTATUS status;
+       struct tevent_req *r139, *r445;
+       struct fd_struct *fd139, *fd445;
+       NTSTATUS status = NT_STATUS_NO_MEMORY;
 
        if (*port != 0) {
                return open_socket_out(pss, *port, timeout, pfd);
@@ -1778,43 +1819,54 @@ static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
                return NT_STATUS_NO_MEMORY;
        }
 
+       fd139 = talloc(ev, struct fd_struct);
+       if (fd139 == NULL) {
+               goto done;
+       }
+       fd139->fd = -1;
+
+       fd445 = talloc(ev, struct fd_struct);
+       if (fd445 == NULL) {
+               goto done;
+       }
+       fd445->fd = -1;
+
        r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
                                          pss, 445, timeout);
        r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
                                          pss, 139, timeout);
        if ((r445 == NULL) || (r139 == NULL)) {
-               status = NT_STATUS_NO_MEMORY;
                goto done;
        }
-       r445->async.fn = smb_sock_connected;
-       r445->async.priv = &fd445;
-       r139->async.fn = smb_sock_connected;
-       r139->async.priv = &fd139;
+       tevent_req_set_callback(r445, smb_sock_connected, fd445);
+       tevent_req_set_callback(r139, smb_sock_connected, fd139);
 
-       while ((fd139 == -1) && (r139->state < ASYNC_REQ_DONE)
-              && (fd445 == -1) && (r445->state < ASYNC_REQ_DONE)) {
+       while ((fd139->fd == -1)
+              && tevent_req_is_in_progress(r139)
+              && (fd445->fd == -1)
+              && tevent_req_is_in_progress(r445)) {
                event_loop_once(ev);
        }
 
-       if ((fd139 != -1) && (fd445 != -1)) {
-               close(fd139);
-               fd139 = -1;
+       if ((fd139->fd != -1) && (fd445->fd != -1)) {
+               close(fd139->fd);
+               fd139->fd = -1;
        }
 
-       if (fd445 != -1) {
+       if (fd445->fd != -1) {
                *port = 445;
-               *pfd = fd445;
+               *pfd = fd445->fd;
                status = NT_STATUS_OK;
                goto done;
        }
-       if (fd139 != -1) {
+       if (fd139->fd != -1) {
                *port = 139;
-               *pfd = fd139;
+               *pfd = fd139->fd;
                status = NT_STATUS_OK;
                goto done;
        }
 
-       status = open_socket_out_defer_recv(r445, &fd445);
+       status = open_socket_out_defer_recv(r445, &fd445->fd);
  done:
        TALLOC_FREE(ev);
        return status;
@@ -1936,7 +1988,7 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli,
        if (!my_name) 
                my_name = global_myname();
 
-       if (!(cli = cli_initialise())) {
+       if (!(cli = cli_initialise_ex(signing_state))) {
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -1984,8 +2036,6 @@ again:
                return NT_STATUS_BAD_NETWORK_NAME;
        }
 
-       cli_setup_signing_state(cli, signing_state);
-
        if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
                cli->use_spnego = False;
        else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
@@ -2083,7 +2133,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 e642f169f974eebf442d2adf3b2efd8504c9594a..430807eb7f319db765cc2449aec568e355b697de 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;
-       bool got_pass;
-       bool use_kerberos;
-       bool fallback_after_kerberos;
-       int signing_state;
-} cm_creds;
-
-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 +77,7 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c,
 
        return status;
 }
-       
+
 /********************************************************************
  Return a connection to a server.
 ********************************************************************/
@@ -104,6 +85,7 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c,
 static struct cli_state *do_connect(TALLOC_CTX *ctx,
                                        const char *server,
                                        const char *share,
+                                       const struct user_auth_info *auth_info,
                                        bool show_sessetup,
                                        bool force_encrypt,
                                        int max_protocol,
@@ -151,7 +133,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
        zero_sockaddr(&ss);
 
        /* have to open a new connection */
-       if (!(c=cli_initialise())) {
+       if (!(c=cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)))) {
                d_printf("Connection to %s failed\n", server_n);
                if (c) {
                        cli_shutdown(c);
@@ -175,9 +157,9 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
                max_protocol = PROTOCOL_NT1;
        }
        c->protocol = max_protocol;
-       c->use_kerberos = cm_creds.use_kerberos;
-       c->fallback_after_kerberos = cm_creds.fallback_after_kerberos;
-       cli_setup_signing_state(c, cm_creds.signing_state);
+       c->use_kerberos = get_cmdline_auth_info_use_kerberos(auth_info);
+       c->fallback_after_kerberos =
+               get_cmdline_auth_info_fallback_after_kerberos(auth_info);
 
        if (!cli_session_request(c, &calling, &called)) {
                char *p;
@@ -207,20 +189,8 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
                return NULL;
        }
 
-       if (!cm_creds.got_pass && !cm_creds.use_kerberos) {
-               char *label = NULL;
-               char *pass;
-               label = talloc_asprintf(ctx, "Enter %s's password: ",
-                       cm_creds.username);
-               pass = getpass(label);
-               if (pass) {
-                       cm_set_password(pass);
-               }
-               TALLOC_FREE(label);
-       }
-
-       username = cm_creds.username ? cm_creds.username : "";
-       password = cm_creds.password ? cm_creds.password : "";
+       username = get_cmdline_auth_info_username(auth_info);
+       password = get_cmdline_auth_info_password(auth_info);
 
        if (!NT_STATUS_IS_OK(cli_session_setup(c, username,
                                               password, strlen(password),
@@ -228,8 +198,9 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
                                               lp_workgroup()))) {
                /* If a password was not supplied then
                 * try again with a null username. */
-               if (password[0] || !username[0] || cm_creds.use_kerberos ||
-                   !NT_STATUS_IS_OK(cli_session_setup(c, "",
+               if (password[0] || !username[0] ||
+                       get_cmdline_auth_info_use_kerberos(auth_info) ||
+                       !NT_STATUS_IS_OK(cli_session_setup(c, "",
                                                "", 0,
                                                "", 0,
                                               lp_workgroup()))) {
@@ -268,7 +239,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
                                lp_workgroup())) {
                cli_shutdown(c);
                return do_connect(ctx, newserver,
-                               newshare, false,
+                               newshare, auth_info, false,
                                force_encrypt, max_protocol,
                                port, name_type);
        }
@@ -302,111 +273,90 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
 /****************************************************************************
 ****************************************************************************/
 
-static void cli_cm_set_mntpoint(struct cli_state *c, const char *mnt)
+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) {
-               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)
-{
-       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,
                                        struct cli_state *referring_cli,
                                        const char *server,
                                        const char *share,
+                                       const struct user_auth_info *auth_info,
                                        bool show_hdr,
                                        bool force_encrypt,
                                        int max_protocol,
                                        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,
+                               auth_info,
                                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;
                }
        }
 
@@ -414,82 +364,68 @@ 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,
                                struct cli_state *referring_cli,
                                const char *server,
                                const char *share,
+                               const struct user_auth_info *auth_info,
                                bool show_hdr,
                                bool force_encrypt,
                                int max_protocol,
                                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 */
-
-       c = cli_cm_find(server, share);
-       if (!c) {
-               c = cli_cm_connect(ctx, referring_cli,
-                               server, share, show_hdr, force_encrypt,
-                               max_protocol, port, name_type);
+       if (c) {
+               return c;
        }
 
-       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);
+       if (auth_info == NULL) {
+               /* Can't do a new connection
+                * without auth info. */
+               d_printf("cli_cm_open() Unable to open connection [\\%s\\%s] "
+                       "without auth info\n",
+                       server, share );
+               return NULL;
        }
 
-       connections = NULL;
-       return;
+       return cli_cm_connect(ctx,
+                               referring_cli,
+                               server,
+                               share,
+                               auth_info,
+                               show_hdr,
+                               force_encrypt,
+                               max_protocol,
+                               port,
+                               name_type);
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-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 );
        }
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static void cm_set_password(const char *newpass)
-{
-       SAFE_FREE(cm_creds.password);
-       cm_creds.password = SMB_STRDUP(newpass);
-       if (cm_creds.password) {
-               cm_creds.got_pass = true;
-       }
-}
-
 /****************************************************************************
 ****************************************************************************/
 
+#if 0
 void cli_cm_set_credentials(struct user_auth_info *auth_info)
 {
        SAFE_FREE(cm_creds.username);
@@ -504,51 +440,7 @@ void cli_cm_set_credentials(struct user_auth_info *auth_info)
        cm_creds.fallback_after_kerberos = false;
        cm_creds.signing_state = get_cmdline_auth_info_signing_state(auth_info);
 }
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_signing_state(int state)
-{
-       cm_creds.signing_state = state;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_username(const char *username)
-{
-       SAFE_FREE(cm_creds.username);
-       cm_creds.username = SMB_STRDUP(username);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_password(const char *newpass)
-{
-       SAFE_FREE(cm_creds.password);
-       cm_creds.password = SMB_STRDUP(newpass);
-       if (cm_creds.password) {
-               cm_creds.got_pass = true;
-       }
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_use_kerberos(void)
-{
-       cm_creds.use_kerberos = true;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_fallback_after_kerberos(void)
-{
-       cm_creds.fallback_after_kerberos = true;
-}
+#endif
 
 /**********************************************************************
  split a dfs path into the server, share name, and extrapath components
@@ -659,13 +551,23 @@ static char *cli_dfs_make_full_path(TALLOC_CTX *ctx,
                                        struct cli_state *cli,
                                        const char *dir)
 {
+       char path_sep = '\\';
+
        /* Ensure the extrapath doesn't start with a separator. */
        while (IS_DIRECTORY_SEP(*dir)) {
                dir++;
        }
 
-       return talloc_asprintf(ctx, "\\%s\\%s\\%s",
-                       cli->desthost, cli->share, dir);
+       if (cli->posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
+               path_sep = '/';
+       }
+       return talloc_asprintf(ctx, "%c%s%c%s%c%s",
+                       path_sep,
+                       cli->desthost,
+                       path_sep,
+                       cli->share,
+                       path_sep,
+                       dir);
 }
 
 /********************************************************************
@@ -818,6 +720,7 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx,
 
 bool cli_resolve_path(TALLOC_CTX *ctx,
                        const char *mountpt,
+                       const struct user_auth_info *dfs_auth_info,
                        struct cli_state *rootcli,
                        const char *path,
                        struct cli_state **targetcli,
@@ -898,13 +801,16 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
 
        /* Check for the referral. */
 
-       if (!(cli_ipc = cli_cm_open(ctx, rootcli,
-                                       rootcli->desthost,
-                                       "IPC$", false,
-                                       (rootcli->trans_enc_state != NULL),
-                                       rootcli->protocol,
-                                       0,
-                                       0x20))) {
+       if (!(cli_ipc = cli_cm_open(ctx,
+                               rootcli,
+                               rootcli->desthost,
+                               "IPC$",
+                               dfs_auth_info,
+                               false,
+                               (rootcli->trans_enc_state != NULL),
+                               rootcli->protocol,
+                               0,
+                               0x20))) {
                return false;
        }
 
@@ -948,6 +854,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
        if ((*targetcli = cli_cm_open(ctx, rootcli,
                                        server,
                                        share,
+                                       dfs_auth_info,
                                        false,
                                        (rootcli->trans_enc_state != NULL),
                                        rootcli->protocol,
@@ -999,7 +906,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. */
@@ -1007,6 +914,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
        if (!strequal(*pp_targetpath, "\\") && !strequal(*pp_targetpath, "/")) {
                if (cli_resolve_path(ctx,
                                        newmount,
+                                       dfs_auth_info,
                                        *targetcli,
                                        *pp_targetpath,
                                        &newcli,
index 0382ef5fae7223dd19d11d740ede61356357e3ab..c1ba4e5c4f6909f325a10d73048573a3c06877c0 100644 (file)
@@ -409,49 +409,76 @@ void cli_setup_bcc(struct cli_state *cli, void *p)
 }
 
 /****************************************************************************
- Initialise credentials of a client structure.
+ Initialize Domain, user or password.
 ****************************************************************************/
 
-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)
 {
-       fstrcpy(cli->domain, domain);
-       fstrcpy(cli->user_name, username);
-       pwd_set_cleartext(&cli->pwd, password);
-       if (!*username) {
-               cli->pwd.null_pwd = true;
+       TALLOC_FREE(cli->domain);
+       cli->domain = talloc_strdup(cli, domain ? domain : "");
+       if (cli->domain == NULL) {
+               return NT_STATUS_NO_MEMORY;
        }
+       return NT_STATUS_OK;
+}
 
-        DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain));
+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;
 }
 
 /****************************************************************************
Set the signing state (used from the command line).
Initialise credentials of a client structure.
 ****************************************************************************/
 
-void cli_setup_signing_state(struct cli_state *cli, int signing_state)
+NTSTATUS cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password)
 {
-       if (signing_state == Undefined)
-               return;
-
-       if (signing_state == false) {
-               cli->sign_info.allow_smb_signing = false;
-               cli->sign_info.mandatory_signing = false;
-               return;
+       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));
 
-       cli->sign_info.allow_smb_signing = true;
-
-       if (signing_state == Required) 
-               cli->sign_info.mandatory_signing = true;
+       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).
 ****************************************************************************/
 
-struct cli_state *cli_initialise(void)
+struct cli_state *cli_initialise_ex(int signing_state)
 {
        struct cli_state *cli = NULL;
+       bool allow_smb_signing = false;
+       bool mandatory_signing = false;
 
        /* Check the effective uid - make sure we are not setuid */
        if (is_setuid_root()) {
@@ -464,6 +491,10 @@ struct cli_state *cli_initialise(void)
                return NULL;
        }
 
+       cli->dfs_mountpoint = talloc_strdup(cli, "");
+       if (!cli->dfs_mountpoint) {
+               goto error;
+       }
        cli->port = 0;
        cli->fd = -1;
        cli->cnum = -1;
@@ -490,12 +521,27 @@ struct cli_state *cli_initialise(void)
        if (getenv("CLI_FORCE_DOSERR"))
                cli->force_dos_errors = true;
 
-       if (lp_client_signing()) 
-               cli->sign_info.allow_smb_signing = true;
+       if (lp_client_signing()) {
+               allow_smb_signing = true;
+       }
+
+       if (lp_client_signing() == Required) {
+               mandatory_signing = true;
+       }
+
+       if (signing_state != Undefined) {
+               allow_smb_signing = true;
+       }
+
+       if (signing_state == false) {
+               allow_smb_signing = false;
+               mandatory_signing = false;
+       }
+
+       if (signing_state == Required) {
+               mandatory_signing = true;
+       }
 
-       if (lp_client_signing() == Required) 
-               cli->sign_info.mandatory_signing = true;
-                                   
        if (!cli->outbuf || !cli->inbuf)
                 goto error;
 
@@ -510,6 +556,8 @@ struct cli_state *cli_initialise(void)
 #endif
 
        /* initialise signing */
+       cli->sign_info.allow_smb_signing = allow_smb_signing;
+       cli->sign_info.mandatory_signing = mandatory_signing;
        cli_null_set_signing(cli);
 
        cli->initialised = 1;
@@ -522,10 +570,15 @@ struct cli_state *cli_initialise(void)
 
         SAFE_FREE(cli->inbuf);
         SAFE_FREE(cli->outbuf);
-       SAFE_FREE(cli);
+       TALLOC_FREE(cli);
         return NULL;
 }
 
+struct cli_state *cli_initialise(void)
+{
+       return cli_initialise_ex(Undefined);
+}
+
 /****************************************************************************
  Close all pipes open on this session.
 ****************************************************************************/
@@ -546,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 9d17ff86a5eba9f39a45b08412264bf4d3751990..f2f447b4c95661f7d87190473afd6f4b200cc073 100644 (file)
@@ -915,9 +915,15 @@ static NTSTATUS cli_writeall_recv(struct async_req *req)
        return async_req_simple_recv_ntstatus(req);
 }
 
-struct cli_push_state {
-       struct async_req *req;
+struct cli_push_write_state {
+       struct async_req *req;/* This is the main request! Not the subreq */
+       uint32_t idx;
+       off_t ofs;
+       uint8_t *buf;
+       size_t size;
+};
 
+struct cli_push_state {
        struct event_context *ev;
        struct cli_state *cli;
        uint16_t fnum;
@@ -928,24 +934,70 @@ struct cli_push_state {
        size_t (*source)(uint8_t *buf, size_t n, void *priv);
        void *priv;
 
-       size_t chunk_size;
-
-       size_t sent;
        bool eof;
 
+       size_t chunk_size;
+       off_t next_offset;
+
        /*
         * Outstanding requests
         */
-       int num_reqs;
-       struct async_req **reqs;
-
-       int pending;
-
-       uint8_t *buf;
+       uint32_t pending;
+       uint32_t num_reqs;
+       struct cli_push_write_state **reqs;
 };
 
 static void cli_push_written(struct async_req *req);
 
+static bool cli_push_write_setup(struct async_req *req,
+                                struct cli_push_state *state,
+                                uint32_t idx)
+{
+       struct cli_push_write_state *substate;
+       struct async_req *subreq;
+
+       substate = talloc(state->reqs, struct cli_push_write_state);
+       if (!substate) {
+               return false;
+       }
+       substate->req = req;
+       substate->idx = idx;
+       substate->ofs = state->next_offset;
+       substate->buf = talloc_array(substate, uint8_t, state->chunk_size);
+       if (!substate->buf) {
+               talloc_free(substate);
+               return false;
+       }
+       substate->size = state->source(substate->buf,
+                                      state->chunk_size,
+                                      state->priv);
+       if (substate->size == 0) {
+               state->eof = true;
+               /* nothing to send */
+               talloc_free(substate);
+               return true;
+       }
+
+       subreq = cli_writeall_send(substate,
+                                  state->ev, state->cli,
+                                  state->fnum, state->mode,
+                                  substate->buf,
+                                  substate->ofs,
+                                  substate->size);
+       if (!subreq) {
+               talloc_free(substate);
+               return false;
+       }
+       subreq->async.fn = cli_push_written;
+       subreq->async.priv = substate;
+
+       state->reqs[idx] = substate;
+       state->pending += 1;
+       state->next_offset += substate->size;
+
+       return true;
+}
+
 struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
                                struct cli_state *cli,
                                uint16_t fnum, uint16_t mode,
@@ -954,16 +1006,14 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
                                                 void *priv),
                                void *priv)
 {
-       struct async_req *result;
+       struct async_req *req;
        struct cli_push_state *state;
-       int i;
+       uint32_t i;
 
-       if (!async_req_setup(mem_ctx, &result, &state,
+       if (!async_req_setup(mem_ctx, &req, &state,
                             struct cli_push_state)) {
                return NULL;
        }
-       state->req = result;
-
        state->cli = cli;
        state->ev = ev;
        state->fnum = fnum;
@@ -972,124 +1022,83 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
        state->source = source;
        state->priv = priv;
        state->eof = false;
-       state->sent = 0;
        state->pending = 0;
+       state->next_offset = start_offset;
 
        state->chunk_size = cli_write_max_bufsize(cli, mode);
 
-       state->num_reqs = MAX(window_size/state->chunk_size, 1);
+       if (window_size == 0) {
+               window_size = cli->max_mux * state->chunk_size;
+       }
+       state->num_reqs = window_size/state->chunk_size;
+       if ((window_size % state->chunk_size) > 0) {
+               state->num_reqs += 1;
+       }
        state->num_reqs = MIN(state->num_reqs, cli->max_mux);
+       state->num_reqs = MAX(state->num_reqs, 1);
 
-       state->reqs = TALLOC_ZERO_ARRAY(state, struct async_req *,
+       state->reqs = TALLOC_ZERO_ARRAY(state, struct cli_push_write_state *,
                                        state->num_reqs);
        if (state->reqs == NULL) {
                goto failed;
        }
 
-       state->buf = TALLOC_ARRAY(
-               state, uint8_t, state->chunk_size * state->num_reqs);
-       if (state->buf == NULL) {
-               goto failed;
-       }
-
        for (i=0; i<state->num_reqs; i++) {
-               size_t to_write;
-               uint8_t *buf = state->buf + i*state->chunk_size;
-
-               to_write = state->source(buf, state->chunk_size, state->priv);
-               if (to_write == 0) {
-                       state->eof = true;
-                       break;
-               }
-
-               state->reqs[i] = cli_writeall_send(
-                       state->reqs, state->ev, state->cli, state->fnum,
-                       state->mode, buf, state->start_offset + state->sent,
-                       to_write);
-               if (state->reqs[i] == NULL) {
+               if (!cli_push_write_setup(req, state, i)) {
                        goto failed;
                }
 
-               state->reqs[i]->async.fn = cli_push_written;
-               state->reqs[i]->async.priv = state;
-
-               state->sent += to_write;
-               state->pending += 1;
+               if (state->eof) {
+                       break;
+               }
        }
 
-       if (i == 0) {
-               if (!async_post_ntstatus(result, ev, NT_STATUS_OK)) {
+       if (state->pending == 0) {
+               if (!async_post_ntstatus(req, ev, NT_STATUS_OK)) {
                        goto failed;
                }
-               return result;
+               return req;
        }
 
-       return result;
+       return req;
 
  failed:
-       TALLOC_FREE(result);
+       TALLOC_FREE(req);
        return NULL;
 }
 
-static void cli_push_written(struct async_req *req)
+static void cli_push_written(struct async_req *subreq)
 {
+       struct cli_push_write_state *substate = talloc_get_type_abort(
+               subreq->async.priv, struct cli_push_write_state);
+       struct async_req *req = substate->req;
        struct cli_push_state *state = talloc_get_type_abort(
-               req->async.priv, struct cli_push_state);
+               req->private_data, struct cli_push_state);
        NTSTATUS status;
-       int i;
-       uint8_t *buf;
-       size_t to_write;
-
-       for (i=0; i<state->num_reqs; i++) {
-               if (state->reqs[i] == req) {
-                       break;
-               }
-       }
-
-       if (i == state->num_reqs) {
-               async_req_nterror(state->req, NT_STATUS_INTERNAL_ERROR);
-               return;
-       }
-
-       status = cli_writeall_recv(req);
-       TALLOC_FREE(state->reqs[i]);
-       req = NULL;
-       if (!NT_STATUS_IS_OK(status)) {
-               async_req_nterror(state->req, status);
-               return;
-       }
+       uint32_t idx = substate->idx;
 
+       state->reqs[idx] = NULL;
        state->pending -= 1;
-       if (state->pending == 0) {
-               async_req_done(state->req);
-               return;
-       }
 
-       if (state->eof) {
+       status = cli_writeall_recv(subreq);
+       TALLOC_FREE(subreq);
+       TALLOC_FREE(substate);
+       if (!NT_STATUS_IS_OK(status)) {
+               async_req_nterror(req, status);
                return;
        }
 
-       buf = state->buf + i * state->chunk_size;
-
-       to_write = state->source(buf, state->chunk_size, state->priv);
-       if (to_write == 0) {
-               state->eof = true;
-               return;
+       if (!state->eof) {
+               if (!cli_push_write_setup(req, state, idx)) {
+                       async_req_nomem(NULL, req);
+                       return;
+               }
        }
 
-       state->reqs[i] = cli_writeall_send(
-               state->reqs, state->ev, state->cli, state->fnum,
-               state->mode, buf, state->start_offset + state->sent, to_write);
-       if (state->reqs[i] == NULL) {
-               async_req_nterror(state->req, NT_STATUS_NO_MEMORY);
+       if (state->pending == 0) {
+               async_req_done(req);
                return;
        }
-
-       state->reqs[i]->async.fn = cli_push_written;
-       state->reqs[i]->async.priv = state;
-
-       state->sent += to_write;
-       state->pending += 1;
 }
 
 NTSTATUS cli_push_recv(struct async_req *req)
index 69e2be3af7f3f74884a2e890fc79da4abd1229e8..0266c0307e5a296139cd58b5fcb1f7007a11f0b0 100644 (file)
@@ -112,9 +112,6 @@ bool cli_send_trans(struct cli_state *cli, int trans,
                        this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */
                        this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam));
 
-                       client_set_trans_sign_state_off(cli, mid);
-                       client_set_trans_sign_state_on(cli, mid);
-
                        cli_set_message(cli->outbuf,trans==SMBtrans?8:9,0,True);
                        SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2));
 
@@ -138,20 +135,14 @@ bool cli_send_trans(struct cli_state *cli, int trans,
                                memcpy(outdata,data+tot_data,this_ldata);
                        cli_setup_bcc(cli, outdata+this_ldata);
 
-                       /*
-                        * Save the mid we're using. We need this for finding
-                        * signing replies.
-                        */
-                       mid = cli->mid;
-
                        show_msg(cli->outbuf);
+
+                       client_set_trans_sign_state_off(cli, mid);
+                       cli->mid = mid;
                        if (!cli_send_smb(cli)) {
-                               client_set_trans_sign_state_off(cli, mid);
                                return False;
                        }
-
-                       /* Ensure we use the same mid for the secondaries. */
-                       cli->mid = mid;
+                       client_set_trans_sign_state_on(cli, mid);
 
                        tot_data += this_ldata;
                        tot_param += this_lparam;
@@ -461,21 +452,14 @@ bool cli_send_nt_trans(struct cli_state *cli,
                                memcpy(outdata,data+tot_data,this_ldata);
                        cli_setup_bcc(cli, outdata+this_ldata);
 
-                       /*
-                        * Save the mid we're using. We need this for finding
-                        * signing replies.
-                        */
-                       mid = cli->mid;
-
                        show_msg(cli->outbuf);
 
+                       client_set_trans_sign_state_off(cli, mid);
+                       cli->mid = mid;
                        if (!cli_send_smb(cli)) {
-                               client_set_trans_sign_state_off(cli, mid);
                                return False;
                        }
-
-                       /* Ensure we use the same mid for the secondaries. */
-                       cli->mid = mid;
+                       client_set_trans_sign_state_on(cli, mid);
 
                        tot_data += this_ldata;
                        tot_param += this_lparam;
@@ -747,6 +731,7 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx,
        uint16_t this_data = 0;
        uint32_t useable_space;
        uint8_t cmd;
+       uint8_t pad[3];
 
        frame = talloc_stackframe();
 
@@ -759,9 +744,16 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx,
 
        param_offset = smb_size - 4;
 
+       bytes = TALLOC_ARRAY(talloc_tos(), uint8_t, 0); /* padding */
+       if (bytes == NULL) {
+               goto fail;
+       }
+
        switch (cmd) {
        case SMBtrans:
-               bytes = TALLOC_ZERO_P(talloc_tos(), uint8_t); /* padding */
+               pad[0] = 0;
+               bytes = (uint8_t *)talloc_append_blob(talloc_tos(), bytes,
+                                               data_blob_const(pad, 1));
                if (bytes == NULL) {
                        goto fail;
                }
@@ -775,13 +767,14 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx,
                param_offset += talloc_get_size(bytes);
                break;
        case SMBtrans2:
-               bytes = TALLOC_ARRAY(talloc_tos(), uint8_t, 3); /* padding */
+               pad[0] = 0;
+               pad[1] = 'D'; /* Copy this from "old" 3.0 behaviour */
+               pad[2] = ' ';
+               bytes = (uint8_t *)talloc_append_blob(talloc_tos(), bytes,
+                                               data_blob_const(pad, 3));
                if (bytes == NULL) {
                        goto fail;
                }
-               bytes[0] = 0;
-               bytes[1] = 'D'; /* Copy this from "old" 3.0 behaviour */
-               bytes[2] = ' ';
                wct = 14 + state->num_setup;
                param_offset += talloc_get_size(bytes);
                break;
index 4c12d18ab7b62a7dca92a2f22e671f6a9e27ab61..f09e9c6287f65b513316050bb043cc2222013084 100644 (file)
@@ -203,6 +203,9 @@ smbc_free_context(SMBCCTX *context,
         
         DEBUG(3, ("Context %p successfully freed\n", context));
 
+       /* Free any DFS auth context. */
+       TALLOC_FREE(context->internal->auth_info);
+
        SAFE_FREE(context->internal);
         SAFE_FREE(context);
 
@@ -625,32 +628,20 @@ smbc_version(void)
         return samba_version_string();
 }
 
-
 /*
  * Set the credentials so DFS will work when following referrals.
+ * This function is broken and must be removed. No SMBCCTX arg...
+ * JRA.
  */
+
 void
 smbc_set_credentials(const char *workgroup,
-                     const char *user,
-                     const char *password,
-                     smbc_bool use_kerberos,
-                     const char *signing_state)
+                       const char *user,
+                       const char *password,
+                       smbc_bool use_kerberos,
+                       const char *signing_state)
 {
-        struct user_auth_info *auth_info;
-
-       auth_info = user_auth_info_init(talloc_tos());
-       if (auth_info == NULL) {
-               return;
-       }
-        set_cmdline_auth_info_username(auth_info, user);
-        set_cmdline_auth_info_password(auth_info, password);
-        set_cmdline_auth_info_use_kerberos(auth_info, use_kerberos);
-        if (! set_cmdline_auth_info_signing_state(auth_info, signing_state)) {
-                DEBUG(0, ("Invalid signing state: %s", signing_state));
-        }
-        set_global_myworkgroup(workgroup);
-        cli_cm_set_credentials(auth_info);
-       TALLOC_FREE(auth_info);
+       d_printf("smbc_set_credentials is obsolete. Replace with smbc_set_credentials_with_fallback().\n");
 }
 
 void smbc_set_credentials_with_fallback(SMBCCTX *context,
@@ -660,7 +651,11 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context,
 {
        smbc_bool use_kerberos = false;
        const char *signing_state = "off";
-       
+       struct user_auth_info *auth_info = user_auth_info_init(NULL);
+
+       if (auth_info) {
+       }
+
        if (! context ||
            ! workgroup || ! *workgroup ||
            ! user || ! *user ||
@@ -669,6 +664,13 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context,
                return;
        }
 
+       auth_info = user_auth_info_init(NULL);
+
+       if (auth_info) {
+               DEBUG(0, ("smbc_set_credentials_with_fallback: allocation fail\n"));
+               return;
+       }
+
        if (smbc_getOptionUseKerberos(context)) {
                use_kerberos = True;
        }
@@ -681,10 +683,15 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context,
                signing_state = "force";
        }
 
-       smbc_set_credentials(workgroup, user, password,
-                             use_kerberos, signing_state);
+        set_cmdline_auth_info_username(auth_info, user);
+        set_cmdline_auth_info_password(auth_info, password);
+        set_cmdline_auth_info_use_kerberos(auth_info, use_kerberos);
+        set_cmdline_auth_info_signing_state(auth_info, signing_state);
+       set_cmdline_auth_info_fallback_after_kerberos(auth_info,
+               smbc_getOptionFallbackAfterKerberos(context));
+        set_global_myworkgroup(workgroup);
 
-       if (smbc_getOptionFallbackAfterKerberos(context)) {
-               cli_cm_set_fallback_after_kerberos();
-       }
+       TALLOC_FREE(context->internal->auth_info);
+
+        context->internal->auth_info = auth_info;
 }
index 56661af70b02b37493b3f3c96077829c43106218..2255db66170fe872886d0ec9e57658fc4ef74fe2 100644 (file)
@@ -770,8 +770,9 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                return NULL;
                        }
 
-                       if (!cli_resolve_path(frame, "", srv->cli, path,
-                                              &targetcli, &targetpath)) {
+                       if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                                               srv->cli, path,
+                                               &targetcli, &targetpath)) {
                                d_printf("Could not resolve %s\n", path);
                                if (dir) {
                                        SAFE_FREE(dir->fname);
@@ -1166,8 +1167,9 @@ SMBC_mkdir_ctx(SMBCCTX *context,
        }
 
        /*d_printf(">>>mkdir: resolving %s\n", path);*/
-       if (!cli_resolve_path(frame, "", srv->cli, path,
-                              &targetcli, &targetpath)) {
+       if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                               srv->cli, path,
+                               &targetcli, &targetpath)) {
                d_printf("Could not resolve %s\n", path);
                TALLOC_FREE(frame);
                return -1;
@@ -1272,8 +1274,9 @@ SMBC_rmdir_ctx(SMBCCTX *context,
        }
 
        /*d_printf(">>>rmdir: resolving %s\n", path);*/
-       if (!cli_resolve_path(frame, "", srv->cli, path,
-                              &targetcli, &targetpath)) {
+       if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                               srv->cli, path,
+                               &targetcli, &targetpath)) {
                d_printf("Could not resolve %s\n", path);
                TALLOC_FREE(frame);
                return -1;
@@ -1554,8 +1557,9 @@ SMBC_chmod_ctx(SMBCCTX *context,
        }
        
        /*d_printf(">>>unlink: resolving %s\n", path);*/
-       if (!cli_resolve_path(frame, "", srv->cli, path,
-                              &targetcli, &targetpath)) {
+       if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                               srv->cli, path,
+                               &targetcli, &targetpath)) {
                d_printf("Could not resolve %s\n", path);
                TALLOC_FREE(frame);
                return -1;
@@ -1745,8 +1749,9 @@ SMBC_unlink_ctx(SMBCCTX *context,
        }
 
        /*d_printf(">>>unlink: resolving %s\n", path);*/
-       if (!cli_resolve_path(frame, "", srv->cli, path,
-                              &targetcli, &targetpath)) {
+       if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                               srv->cli, path,
+                               &targetcli, &targetpath)) {
                d_printf("Could not resolve %s\n", path);
                TALLOC_FREE(frame);
                return -1;
@@ -1917,8 +1922,10 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
                                           password1);
 
        /*d_printf(">>>rename: resolving %s\n", path1);*/
-       if (!cli_resolve_path(frame, "", srv->cli, path1,
-                              &targetcli1, &targetpath1)) {
+       if (!cli_resolve_path(frame, "", ocontext->internal->auth_info,
+                               srv->cli,
+                               path1,
+                               &targetcli1, &targetpath1)) {
                d_printf("Could not resolve %s\n", path1);
                TALLOC_FREE(frame);
                return -1;
@@ -1932,8 +1939,10 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
        
        /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/
        /*d_printf(">>>rename: resolving %s\n", path2);*/
-       if (!cli_resolve_path(frame, "", srv->cli, path2,
-                              &targetcli2, &targetpath2)) {
+       if (!cli_resolve_path(frame, "", ncontext->internal->auth_info,
+                               srv->cli, 
+                               path2,
+                               &targetcli2, &targetpath2)) {
                d_printf("Could not resolve %s\n", path2);
                TALLOC_FREE(frame);
                return -1;
index 28256bb24133467f7aa3baf6fefed453ec3a8b61..06e41ad21eda75b8cd6f2a2b96e35b3cfad65c2b 100644 (file)
@@ -115,8 +115,9 @@ SMBC_open_ctx(SMBCCTX *context,
                ZERO_STRUCTP(file);
                 
                /*d_printf(">>>open: resolving %s\n", path);*/
-               if (!cli_resolve_path(frame, "", srv->cli, path,
-                                      &targetcli, &targetpath)) {
+               if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                               srv->cli, path,
+                               &targetcli, &targetpath)) {
                        d_printf("Could not resolve %s\n", path);
                        SAFE_FREE(file);
                        TALLOC_FREE(frame);
@@ -295,8 +296,9 @@ SMBC_read_ctx(SMBCCTX *context,
         }
         
        /*d_printf(">>>read: resolving %s\n", path);*/
-       if (!cli_resolve_path(frame, "", file->srv->cli, path,
-                              &targetcli, &targetpath)) {
+       if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                       file->srv->cli, path,
+                       &targetcli, &targetpath)) {
                d_printf("Could not resolve %s\n", path);
                TALLOC_FREE(frame);
                return -1;
@@ -384,8 +386,9 @@ SMBC_write_ctx(SMBCCTX *context,
         }
 
        /*d_printf(">>>write: resolving %s\n", path);*/
-       if (!cli_resolve_path(frame, "", file->srv->cli, path,
-                              &targetcli, &targetpath)) {
+       if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                       file->srv->cli, path,
+                       &targetcli, &targetpath)) {
                d_printf("Could not resolve %s\n", path);
                TALLOC_FREE(frame);
                return -1;
@@ -459,8 +462,9 @@ SMBC_close_ctx(SMBCCTX *context,
         }
         
        /*d_printf(">>>close: resolving %s\n", path);*/
-       if (!cli_resolve_path(frame, "", file->srv->cli, path,
-                              &targetcli, &targetpath)) {
+       if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                       file->srv->cli, path,
+                       &targetcli, &targetpath)) {
                d_printf("Could not resolve %s\n", path);
                TALLOC_FREE(frame);
                return -1;
@@ -541,8 +545,9 @@ SMBC_getatr(SMBCCTX * context,
        }
        DEBUG(4,("SMBC_getatr: sending qpathinfo\n"));
         
-       if (!cli_resolve_path(frame, "", srv->cli, fixedpath,
-                              &targetcli, &targetpath)) {
+       if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                       srv->cli, fixedpath,
+                       &targetcli, &targetpath)) {
                d_printf("Couldn't resolve %s\n", path);
                TALLOC_FREE(frame);
                return False;
@@ -753,8 +758,9 @@ SMBC_lseek_ctx(SMBCCTX *context,
                }
                 
                /*d_printf(">>>lseek: resolving %s\n", path);*/
-               if (!cli_resolve_path(frame, "", file->srv->cli, path,
-                                      &targetcli, &targetpath)) {
+               if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                               file->srv->cli, path,
+                               &targetcli, &targetpath)) {
                        d_printf("Could not resolve %s\n", path);
                        TALLOC_FREE(frame);
                        return -1;
@@ -844,8 +850,9 @@ SMBC_ftruncate_ctx(SMBCCTX *context,
         }
         
        /*d_printf(">>>fstat: resolving %s\n", path);*/
-       if (!cli_resolve_path(frame, "", file->srv->cli, path,
-                              &targetcli, &targetpath)) {
+       if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                       file->srv->cli, path,
+                       &targetcli, &targetpath)) {
                d_printf("Could not resolve %s\n", path);
                TALLOC_FREE(frame);
                return -1;
index f8571ff11083deaf558d855e5e04b3f4d71c85c2..dc904d2753892a15e52d5a7a83fe1cc4e374cf16 100644 (file)
@@ -257,8 +257,9 @@ SMBC_fstat_ctx(SMBCCTX *context,
         }
         
        /*d_printf(">>>fstat: resolving %s\n", path);*/
-       if (!cli_resolve_path(frame, "", file->srv->cli, path,
-                              &targetcli, &targetpath)) {
+       if (!cli_resolve_path(frame, "", context->internal->auth_info,
+                       file->srv->cli, path,
+                       &targetcli, &targetpath)) {
                d_printf("Could not resolve %s\n", path);
                TALLOC_FREE(frame);
                return -1;
index 70fbc2788349475836e30ef328d354f187348ed1..e4a0a0558638b272aac39e517fee1c3e26e63556 100644 (file)
@@ -166,7 +166,7 @@ sort_acl(SEC_ACL *the_acl)
 /* convert a SID to a string, either numeric or username/group */
 static void
 convert_sid_to_string(struct cli_state *ipc_cli,
-                      POLICY_HND *pol,
+                      struct policy_handle *pol,
                       fstring str,
                       bool numeric,
                       DOM_SID *sid)
@@ -211,7 +211,7 @@ convert_sid_to_string(struct cli_state *ipc_cli,
 /* convert a string to a SID, either numeric or username/group */
 static bool
 convert_string_to_sid(struct cli_state *ipc_cli,
-                      POLICY_HND *pol,
+                      struct policy_handle *pol,
                       bool numeric,
                       DOM_SID *sid,
                       const char *str)
@@ -255,7 +255,7 @@ done:
 /* parse an ACE in the same format as print_ace() */
 static bool
 parse_ace(struct cli_state *ipc_cli,
-          POLICY_HND *pol,
+          struct policy_handle *pol,
           SEC_ACE *ace,
           bool numeric,
           char *str)
@@ -422,7 +422,7 @@ add_ace(SEC_ACL **the_acl,
 static SEC_DESC *
 sec_desc_parse(TALLOC_CTX *ctx,
                struct cli_state *ipc_cli,
-               POLICY_HND *pol,
+               struct policy_handle *pol,
                bool numeric,
                const char *str)
 {
@@ -702,7 +702,7 @@ cacl_get(SMBCCTX *context,
          TALLOC_CTX *ctx,
          SMBCSRV *srv,
          struct cli_state *ipc_cli,
-         POLICY_HND *pol,
+         struct policy_handle *pol,
          char *filename,
          char *attr_name,
          char *buf,
@@ -891,7 +891,8 @@ cacl_get(SMBCCTX *context,
                 /* Point to the portion after "system.nt_sec_desc." */
                 name += 19;     /* if (all) this will be invalid but unused */
 
-               if (!cli_resolve_path(ctx, "", cli, filename,
+               if (!cli_resolve_path(ctx, "", context->internal->auth_info,
+                               cli, filename,
                                &targetcli, &targetpath)) {
                        DEBUG(5, ("cacl_get Could not resolve %s\n",
                                filename));
@@ -1496,14 +1497,15 @@ cacl_get(SMBCCTX *context,
 set the ACLs on a file given an ascii description
 *******************************************************/
 static int
-cacl_set(TALLOC_CTX *ctx,
-         struct cli_state *cli,
-         struct cli_state *ipc_cli,
-         POLICY_HND *pol,
-         const char *filename,
-         char *the_acl,
-         int mode,
-         int flags)
+cacl_set(SMBCCTX *context,
+       TALLOC_CTX *ctx,
+       struct cli_state *cli,
+       struct cli_state *ipc_cli,
+       struct policy_handle *pol,
+       const char *filename,
+       char *the_acl,
+       int mode,
+       int flags)
 {
        int fnum;
         int err = 0;
@@ -1547,8 +1549,9 @@ cacl_set(TALLOC_CTX *ctx,
                return -1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, filename,
-                               &targetcli, &targetpath)) {
+       if (!cli_resolve_path(ctx, "", context->internal->auth_info,
+                       cli, filename,
+                       &targetcli, &targetpath)) {
                DEBUG(5,("cacl_set: Could not resolve %s\n", filename));
                errno = ENOENT;
                return -1;
@@ -1793,7 +1796,7 @@ SMBC_setxattr_ctx(SMBCCTX *context,
                 }
                 
                 if (ipc_srv) {
-                        ret = cacl_set(talloc_tos(), srv->cli,
+                        ret = cacl_set(context, talloc_tos(), srv->cli,
                                        ipc_srv->cli, &ipc_srv->pol, path,
                                        namevalue,
                                        (*namevalue == '*'
@@ -1857,7 +1860,7 @@ SMBC_setxattr_ctx(SMBCCTX *context,
                         errno = ENOMEM;
                         ret = -1;
                 } else {
-                        ret = cacl_set(talloc_tos(), srv->cli,
+                        ret = cacl_set(context, talloc_tos(), srv->cli,
                                        ipc_srv->cli, &ipc_srv->pol, path,
                                        namevalue,
                                        (*namevalue == '*'
@@ -1887,7 +1890,7 @@ SMBC_setxattr_ctx(SMBCCTX *context,
                         errno = ENOMEM;
                         ret = -1;
                 } else {
-                        ret = cacl_set(talloc_tos(), srv->cli,
+                        ret = cacl_set(context, talloc_tos(), srv->cli,
                                        ipc_srv->cli, &ipc_srv->pol, path,
                                        namevalue, SMBC_XATTR_MODE_CHOWN, 0);
                 }
@@ -1914,7 +1917,7 @@ SMBC_setxattr_ctx(SMBCCTX *context,
                         errno = ENOMEM;
                         ret = -1;
                 } else {
-                        ret = cacl_set(talloc_tos(), srv->cli,
+                        ret = cacl_set(context, talloc_tos(), srv->cli,
                                        ipc_srv->cli, &ipc_srv->pol, path,
                                        namevalue, SMBC_XATTR_MODE_CHGRP, 0);
                 }
@@ -2216,7 +2219,7 @@ SMBC_removexattr_ctx(SMBCCTX *context,
             StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) {
                 
                 /* Yup. */
-                ret = cacl_set(talloc_tos(), srv->cli,
+                ret = cacl_set(context, talloc_tos(), srv->cli,
                                ipc_srv->cli, &ipc_srv->pol, path,
                                NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0);
                TALLOC_FREE(frame);
@@ -2236,7 +2239,7 @@ SMBC_removexattr_ctx(SMBCCTX *context,
             StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
                 
                 /* Yup. */
-                ret = cacl_set(talloc_tos(), srv->cli,
+                ret = cacl_set(context, talloc_tos(), srv->cli,
                                ipc_srv->cli, &ipc_srv->pol, path,
                                CONST_DISCARD(char *, name) + 19,
                                SMBC_XATTR_MODE_REMOVE, 0);
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 ea1eb05cfb1324d705e33b6e56ebc1b62ced3d91..a3ed0e75729523619d259c6990b3545a37433b0b 100644 (file)
@@ -3,17 +3,17 @@
    SMB Signing Code
    Copyright (C) Jeremy Allison 2003.
    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
-   
+
    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/>.
 */
@@ -119,14 +119,14 @@ static bool cli_set_smb_signing_common(struct cli_state *cli)
        if (cli->sign_info.doing_signing) {
                return False;
        }
-       
+
        if (cli->sign_info.free_signing_context)
                cli->sign_info.free_signing_context(&cli->sign_info);
 
        /* These calls are INCOMPATIBLE with SMB signing */
        cli->readbraw_supported = False;
        cli->writebraw_supported = False;
-       
+
        return True;
 }
 
@@ -196,7 +196,7 @@ static void null_free_signing_context(struct smb_sign_info *si)
 static bool null_set_signing(struct smb_sign_info *si)
 {
        si->signing_context = NULL;
-       
+
        si->sign_outgoing_message = null_sign_outgoing_message;
        si->check_incoming_message = null_check_incoming_message;
        si->free_signing_context = null_free_signing_context;
@@ -207,7 +207,7 @@ static bool null_set_signing(struct smb_sign_info *si)
 /**
  * Free the signing context
  */
+
 static void free_signing_context(struct smb_sign_info *si)
 {
        if (si->free_signing_context) {
@@ -227,7 +227,7 @@ static bool signing_good(const char *inbuf, struct smb_sign_info *si,
                if (!si->doing_signing) {
                        si->doing_signing = True;
                }
-               
+
                if (!si->seen_valid) {
                        si->seen_valid = True;
                }
@@ -289,7 +289,7 @@ static void simple_packet_signature(struct smb_basic_signing_context *data,
 
        /* Calculate the 16 byte MAC - but don't alter the data in the
           incoming packet.
-          
+
           This makes for a bit of fussing about, but it's not too bad.
        */
        MD5Init(&md5_ctx);
@@ -368,7 +368,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
           I can isolate the fix here rather than re-adding the trans
           signing on/off calls in libsmb/clitrans2.c JRA.
         */
-       
+
        if (store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num + 1)) {
                data->send_seq_num += 2;
        }
@@ -409,11 +409,11 @@ static bool client_check_incoming_message(const char *inbuf,
 
        server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
        good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
-       
+
        if (!good) {
                DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
                dump_data(5, calc_md5_mac, 8);
-               
+
                DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
                dump_data(5, server_sent_mac, 8);
 #if 1 /* JRATEST */
@@ -447,7 +447,7 @@ static void simple_free_signing_context(struct smb_sign_info *si)
                (struct smb_basic_signing_context *)si->signing_context;
        struct outstanding_packet_lookup *list;
        struct outstanding_packet_lookup *next;
-       
+
        for (list = data->outstanding_packet_list; list; list = next) {
                next = list->next;
                DLIST_REMOVE(data->outstanding_packet_list, list);
@@ -486,7 +486,7 @@ bool cli_simple_set_signing(struct cli_state *cli,
        memset(data, '\0', sizeof(*data));
 
        cli->sign_info.signing_context = data;
-       
+
        data->mac_key = data_blob(NULL, response.length + user_session_key.length);
 
        memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
@@ -571,7 +571,7 @@ bool cli_temp_set_signing(struct cli_state *cli)
        }
 
        cli->sign_info.signing_context = NULL;
-       
+
        cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message;
        cli->sign_info.check_incoming_message = temp_check_incoming_message;
        cli->sign_info.free_signing_context = temp_free_signing_context;
@@ -587,7 +587,7 @@ void cli_free_signing_context(struct cli_state *cli)
 /**
  * Sign a packet with the current mechanism
  */
+
 void cli_calculate_sign_mac(struct cli_state *cli, char *buf)
 {
        cli->sign_info.sign_outgoing_message(buf, &cli->sign_info);
@@ -598,7 +598,7 @@ void cli_calculate_sign_mac(struct cli_state *cli, char *buf)
  * @return False if we had an established signing connection
  *         which had a bad checksum, True otherwise.
  */
+
 bool cli_check_sign_mac(struct cli_state *cli, char *buf)
 {
        if (!cli->sign_info.check_incoming_message(buf, &cli->sign_info, True)) {
@@ -746,7 +746,7 @@ static bool srv_check_incoming_message(const char *inbuf,
 
        server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
        good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
-       
+
        if (!good) {
 
                if (saved_seq) {
@@ -758,7 +758,7 @@ static bool srv_check_incoming_message(const char *inbuf,
                                                (unsigned int)reply_seq_number));
                        dump_data(5, server_sent_mac, 8);
                }
-               
+
 #if 1 /* JRATEST */
                {
                        int i;
@@ -865,7 +865,7 @@ void srv_defer_sign_response(uint16 mid)
  cancelled by mid. This should never find one....
 ************************************************************/
 
-void srv_cancel_sign_response(uint16 mid)
+void srv_cancel_sign_response(uint16 mid, bool cancel)
 {
        struct smb_basic_signing_context *data;
        uint32 dummy_seq;
@@ -884,7 +884,9 @@ void srv_cancel_sign_response(uint16 mid)
                ;
 
        /* cancel doesn't send a reply so doesn't burn a sequence number. */
-       data->send_seq_num -= 1;
+       if (cancel) {
+               data->send_seq_num -= 1;
+       }
 }
 
 /***********************************************************
@@ -969,17 +971,17 @@ void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response)
        if (srv_sign_info.doing_signing) {
                return;
        }
-       
+
        if (srv_sign_info.free_signing_context)
                srv_sign_info.free_signing_context(&srv_sign_info);
-       
+
        srv_sign_info.doing_signing = True;
 
        data = SMB_XMALLOC_P(struct smb_basic_signing_context);
        memset(data, '\0', sizeof(*data));
 
        srv_sign_info.signing_context = data;
-       
+
        data->mac_key = data_blob(NULL, response.length + user_session_key.length);
 
        memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
index f0595695d2279920c04497f3a46941fea6fcca4c..5b6bc00c579a99149b6b9b6e396a52c48f2ba33d 100644 (file)
@@ -99,7 +99,7 @@ bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
                                      char ***domain_names, uint32 *num_domains,
                                     DOM_SID **sids )
 {
-       POLICY_HND      pol;
+       struct policy_handle    pol;
        NTSTATUS        result = NT_STATUS_UNSUCCESSFUL;
        fstring         dc_name;
        struct sockaddr_storage dc_ss;
index 1737eab1c6f32df43ac205b09d98002d3455fcba..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.
 ****************************************************************************/
@@ -1295,7 +1315,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close,
  (Should this be in locking.c.... ?).
 *************************************************************************/
 
-static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok)
+static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, const UNIX_USER_TOKEN *tok)
 {
        UNIX_USER_TOKEN *cpy;
 
@@ -1326,7 +1346,7 @@ static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok)
  Replace the delete on close token.
 ****************************************************************************/
 
-void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok)
+void set_delete_on_close_token(struct share_mode_lock *lck, const UNIX_USER_TOKEN *tok)
 {
        TALLOC_FREE(lck->delete_token); /* Also deletes groups... */
 
@@ -1346,7 +1366,7 @@ void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok
  lck entry. This function is used when the lock is already granted.
 ****************************************************************************/
 
-void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, UNIX_USER_TOKEN *tok)
+void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, const UNIX_USER_TOKEN *tok)
 {
        if (lck->delete_on_close != delete_on_close) {
                set_delete_on_close_token(lck, tok);
@@ -1358,8 +1378,9 @@ void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close,
        }
 }
 
-bool set_delete_on_close(files_struct *fsp, bool delete_on_close, UNIX_USER_TOKEN *tok)
+bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USER_TOKEN *tok)
 {
+       UNIX_USER_TOKEN *tok_copy = NULL;
        struct share_mode_lock *lck;
        
        DEBUG(10,("set_delete_on_close: %s delete on close flag for "
@@ -1373,6 +1394,16 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, UNIX_USER_TOKE
                return False;
        }
 
+       if (fsp->conn->admin_user) {
+               tok_copy = copy_unix_token(lck, tok);
+               tok_copy->uid = (uid_t)0;
+               if (tok_copy == NULL) {
+                       TALLOC_FREE(lck);
+                       return false;
+               }
+               tok = tok_copy;
+       }
+
        set_delete_on_close_lck(lck, delete_on_close, tok);
 
        if (fsp->is_directory) {
index aae729c82572b09a1c16c60905cb3f841079c5c0..dff4970b2cbe76788d42567625bffc3a590e42d4 100644 (file)
@@ -386,11 +386,17 @@ AC_DEFUN(LIB_REMOVE_USR_LIB,[
     case [$]l[$]i in
     -L/usr/lib) ;;
     -L/usr/lib/) ;;
-    -Wl,-rpath,/usr/lib) ;;
-    -Wl,-rpath,/usr/lib/) ;;
+    -L/usr/lib64) ;;
+    -L/usr/lib64/) ;;
+    -Wl,-rpath,/usr/lib) l="";;
+    -Wl,-rpath,/usr/lib/) l="";;
+    -Wl,-rpath,/usr/lib64) l="";;
+    -Wl,-rpath,/usr/lib64/) l="";;
     -Wl,-rpath) l=[$]i;;
     -Wl,-rpath-Wl,/usr/lib) l="";;
     -Wl,-rpath-Wl,/usr/lib/) l="";;
+    -Wl,-rpath-Wl,/usr/lib64) l="";;
+    -Wl,-rpath-Wl,/usr/lib64/) l="";;
     *)
        s=" "
         if test x"[$]ac_new_flags" = x""; then
index 16599005b93082e4e3ed71dbfb5d8aad1a0e3bbb..9fc4524654b3263c0605496e30a4ee1cbbc9ec62 100644 (file)
@@ -26,6 +26,7 @@
 
 static bool gpfs_share_modes;
 static bool gpfs_leases;
+static bool gpfs_getrealfilename;
 
 static int (*gpfs_set_share_fn)(int fd, unsigned int allow, unsigned int deny);
 static int (*gpfs_set_lease_fn)(int fd, unsigned int leaseType);
@@ -139,7 +140,8 @@ int smbd_gpfs_putacl(char *pathname, int flags, void *acl)
 int smbd_gpfs_get_realfilename_path(char *pathname, char *filenamep,
                                    int *buflen)
 {
-       if (gpfs_get_realfilename_path_fn == NULL) {
+       if ((!gpfs_getrealfilename)
+           || (gpfs_get_realfilename_path_fn == NULL)) {
                errno = ENOSYS;
                return -1;
        }
@@ -208,6 +210,8 @@ void init_gpfs(void)
 
        gpfs_share_modes = lp_parm_bool(-1, "gpfs", "sharemodes", True);
        gpfs_leases      = lp_parm_bool(-1, "gpfs", "leases", True);
+       gpfs_getrealfilename = lp_parm_bool(-1, "gpfs", "getrealfilename",
+                                           True);
 
        return;
 }
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 27cbb0ad74acb7473601de965dcf93829903a85c..f0f48e63794efcf959b20544ad701ed9bf07ec2c 100644 (file)
@@ -64,6 +64,8 @@ enum onefs_acl_wire_format
 #define PARM_DOT_SNAP_TILDE_DEFAULT true
 #define PARM_IGNORE_SACLS "ignore sacls"
 #define PARM_IGNORE_SACLS_DEFAULT false
+#define PARM_IGNORE_STREAMS "ignore streams"
+#define PARM_IGNORE_STREAMS_DEFAULT false
 #define PARM_MTIME_NOW         "mtime now files"
 #define PARM_MTIME_NOW_DEFAULT NULL
 #define PARM_MTIME_STATIC      "mtime static files"
index 9043be8e19bf64993e18c6ad0170ebb38f0ef5b6..c5030f4ab85dddc067fe2d1ba3f616246e812ed9 100644 (file)
@@ -196,7 +196,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
                                                      &base, &stream);
        }
        /* It's a stream, so pass in the base_fd */
-       if (stream != NULL) {
+       if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && stream != NULL) {
                SMB_ASSERT(fsp->base_fsp);
 
                /*
@@ -1648,119 +1648,6 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
        return NT_STATUS_OK;
 }
 
-/*
- * If a main file is opened for delete, all streams need to be checked for
- * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
- * If that works, delete them all by setting the delete on close and close.
- */
-
-static NTSTATUS open_streams_for_delete(connection_struct *conn,
-                                       const char *fname)
-{
-       struct stream_struct *stream_info;
-       files_struct **streams;
-       int i;
-       unsigned int num_streams;
-       TALLOC_CTX *frame = talloc_stackframe();
-       NTSTATUS status;
-
-       status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
-                                   &num_streams, &stream_info);
-
-       if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
-           || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-               DEBUG(10, ("no streams around\n"));
-               TALLOC_FREE(frame);
-               return NT_STATUS_OK;
-       }
-
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
-                          nt_errstr(status)));
-               goto fail;
-       }
-
-       DEBUG(10, ("open_streams_for_delete found %d streams\n",
-                  num_streams));
-
-       if (num_streams == 0) {
-               TALLOC_FREE(frame);
-               return NT_STATUS_OK;
-       }
-
-       streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
-       if (streams == NULL) {
-               DEBUG(0, ("talloc failed\n"));
-               status = NT_STATUS_NO_MEMORY;
-               goto fail;
-       }
-
-       /* Open the base file */
-
-       for (i=0; i<num_streams; i++) {
-               char *streamname;
-
-               if (strequal(stream_info[i].name, "::$DATA")) {
-                       streams[i] = NULL;
-                       continue;
-               }
-
-               streamname = talloc_asprintf(talloc_tos(), "%s%s", fname,
-                                            stream_info[i].name);
-
-               if (streamname == NULL) {
-                       DEBUG(0, ("talloc_aprintf failed\n"));
-                       status = NT_STATUS_NO_MEMORY;
-                       goto fail;
-               }
-
-               status = onefs_create_file_unixpath
-                       (conn,                  /* conn */
-                        NULL,                  /* req */
-                        streamname,            /* fname */
-                        DELETE_ACCESS,         /* access_mask */
-                        FILE_SHARE_READ | FILE_SHARE_WRITE
-                        | FILE_SHARE_DELETE,   /* share_access */
-                        FILE_OPEN,             /* create_disposition*/
-                        NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
-                        FILE_ATTRIBUTE_NORMAL, /* file_attributes */
-                        0,                     /* oplock_request */
-                        0,                     /* allocation_size */
-                        NULL,                  /* sd */
-                        NULL,                  /* ea_list */
-                        &streams[i],           /* result */
-                        NULL,                  /* pinfo */
-                        NULL,                  /* fsp_data */
-                        NULL);                 /* psbuf */
-
-               TALLOC_FREE(streamname);
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(10, ("Could not open stream %s: %s\n",
-                                  streamname, nt_errstr(status)));
-                       break;
-               }
-       }
-
-       /*
-        * don't touch the variable "status" beyond this point :-)
-        */
-
-       for (i -= 1 ; i >= 0; i--) {
-               if (streams[i] == NULL) {
-                       continue;
-               }
-
-               DEBUG(10, ("Closing stream # %d, %s\n", i,
-                          streams[i]->fsp_name));
-               close_file(NULL, streams[i], NORMAL_CLOSE);
-       }
-
- fail:
-       TALLOC_FREE(frame);
-       return status;
-}
-
 /*
  * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
  */
index 9f5d5e22843a6289905bd46d0e430684c4e696b2..05b36d7d3c5366fd1215f28bdf47a129b01c603a 100644 (file)
@@ -671,6 +671,11 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
        state.streams = NULL;
        state.num_streams = 0;
 
+       if (lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE,
+               PARM_IGNORE_STREAMS, PARM_IGNORE_STREAMS_DEFAULT)) {
+               goto out;
+       }
+
        /* Add the default stream. */
        if (S_ISREG(sbuf.st_mode)) {
                if (!add_one_stream(mem_ctx,
@@ -702,7 +707,7 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
                        return state.status;
                }
        }
-
+ out:
        *num_streams = state.num_streams;
        *streams = state.streams;
        return NT_STATUS_OK;
index b8b059bce9504737ae36924c6337ab21294ea92a..46f38265b1689de34f9c84e802c7f3bdcc2b740b 100644 (file)
@@ -591,8 +591,8 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset,
         */
        while (total_rbytes < count) {
 
-               DEBUG(0, ("shallow recvfile, reading %llu\n",
-                         count - total_rbytes));
+               DEBUG(0, ("shallow recvfile (%s), reading %llu\n",
+                         strerror(errno), count - total_rbytes));
 
                /*
                 * Read the remaining data into the spill buffer.  recvfile
@@ -603,9 +603,13 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset,
                               spill_buffer + (total_rbytes - total_wbytes),
                               count - total_rbytes);
 
-               if (ret == -1) {
-                       DEBUG(0, ("shallow recvfile read failed: %s\n",
-                                 strerror(errno)));
+               if (ret <= 0) {
+                       if (ret == 0) {
+                               DEBUG(0, ("shallow recvfile read: EOF\n"));
+                       } else {
+                               DEBUG(0, ("shallow recvfile read failed: %s\n",
+                                         strerror(errno)));
+                       }
                        /* Socket is dead, so treat as if it were drained. */
                        socket_drained = true;
                        goto out;
index 73dbca4809b00f25e714f2448f5203e75b99b2a4..a77f6d60f40a0b4f5a5bad63266a5352956d32a9 100644 (file)
@@ -195,7 +195,7 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
        if (fsp && fsp->fh->fd != -1) {
                ret = SMB_VFS_FSTAT(fsp, &sbuf);
        } else {
-               if (fsp->posix_open) {
+               if (fsp && fsp->posix_open) {
                        ret = SMB_VFS_LSTAT(handle->conn, name, &sbuf);
                } else {
                        ret = SMB_VFS_STAT(handle->conn, name, &sbuf);
@@ -513,7 +513,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
                if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
                        ret = SMB_VFS_FSTAT(fsp, &sbuf);
                } else {
-                       if (fsp->posix_open) {
+                       if (fsp && fsp->posix_open) {
                                ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf);
                        } else {
                                ret = SMB_VFS_STAT(handle->conn,fname, &sbuf);
index 039e469426bdc5801248f1dbf66d403cfe7caabd..49e48998790872fa146188f36476c252fa3140ce 100644 (file)
@@ -381,7 +381,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
                if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
                        ret = SMB_VFS_FSTAT(fsp, &sbuf);
                } else {
-                       if (fsp->posix_open) {
+                       if (fsp && fsp->posix_open) {
                                ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf);
                        } else {
                                ret = SMB_VFS_STAT(handle->conn,fname, &sbuf);
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 1d7cdba01412c975a8635c176bdce0da0b146a92..3c061ece79ce965aeba93ce3c141c2d00f822f25 100644 (file)
@@ -96,6 +96,11 @@ static int vfs_gpfs_get_real_filename(struct vfs_handle_struct *handle,
 
        TALLOC_FREE(full_path);
 
+       if ((result == -1) && (errno == ENOSYS)) {
+               return SMB_VFS_NEXT_GET_REAL_FILENAME(
+                       handle, path, name, mem_ctx, found_name);
+       }
+
        if (result == -1) {
                DEBUG(10, ("smbd_gpfs_get_realfilename_path returned %s\n",
                           strerror(errno)));
index f277245bdc040feaaebd5352a09a8e3353e19794..ad59c2b32db22abf98afa365683074cb550e48c7 100644 (file)
@@ -222,7 +222,14 @@ static int onefs_ntimes(vfs_handle_struct *handle, const char *fname,
 
 static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle)
 {
-       return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS;
+       uint32_t result = 0;
+
+       if (!lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE,
+               PARM_IGNORE_STREAMS, PARM_IGNORE_STREAMS_DEFAULT)) {
+               result |= FILE_NAMED_STREAMS;
+       }
+
+       return result | SMB_VFS_NEXT_FS_CAPABILITIES(handle);
 }
 
 static vfs_op_tuple onefs_ops[] = {
@@ -282,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 89c706d874683e91fee681d74e1b4b5abd0ba48c..f49a1bc4c948311dc507a378628ad48353974496 100644 (file)
@@ -4668,7 +4668,9 @@ static int max_open_files(void)
 
 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
        {
-               struct rlimit rl = {};
+               struct rlimit rl;
+
+               ZERO_STRUCT(rl);
 
                if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
                        rlimit_max = rl.rlim_cur;
index 53845117e200cfe3aef03037bb9cfeead5dbca93..9c20042a6282ae7fb06410db05c92ec25052d53b 100644 (file)
@@ -1308,13 +1308,20 @@ void uid_to_sid(DOM_SID *psid, uid_t uid)
        if (!ret || expired) {
                /* Not in cache. Ask winbindd. */
                if (!winbind_uid_to_sid(psid, uid)) {
-                       if (!winbind_ping()) {
-                               legacy_uid_to_sid(psid, uid);
-                               return;
-                       }
+                       /*
+                        * We shouldn't return the NULL SID
+                        * here if winbind was running and
+                        * couldn't map, as winbind will have
+                        * added a negative entry that will
+                        * cause us to go though the
+                        * legacy_uid_to_sid()
+                        * function anyway in the case above
+                        * the next time we ask.
+                        */
+                       DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
+                                 "for uid %u\n", uid));
 
-                       DEBUG(5, ("uid_to_sid: winbind failed to find a sid for uid %u\n",
-                               uid));
+                       legacy_uid_to_sid(psid, uid);
                        return;
                }
        }
@@ -1354,13 +1361,20 @@ void gid_to_sid(DOM_SID *psid, gid_t gid)
        if (!ret || expired) {
                /* Not in cache. Ask winbindd. */
                if (!winbind_gid_to_sid(psid, gid)) {
-                       if (!winbind_ping()) {
-                               legacy_gid_to_sid(psid, gid);
-                               return;
-                       }
+                       /*
+                        * We shouldn't return the NULL SID
+                        * here if winbind was running and
+                        * couldn't map, as winbind will have
+                        * added a negative entry that will
+                        * cause us to go though the
+                        * legacy_gid_to_sid()
+                        * function anyway in the case above
+                        * the next time we ask.
+                        */
+                       DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
+                                 "for gid %u\n", gid));
 
-                       DEBUG(5, ("gid_to_sid: winbind failed to find a sid for gid %u\n",
-                               gid));
+                       legacy_gid_to_sid(psid, gid);
                        return;
                }
        }
index e618b425e0ceeb9561765155b472657b4345f370..1909bd0da4eb5d8b24411ffd120af9e46c0981bc 100644 (file)
@@ -1709,24 +1709,25 @@ static NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods,
 }
 #endif
 
-struct pdb_search *pdb_search_init(enum pdb_search_type type)
+static int pdb_search_destructor(struct pdb_search *search)
 {
-       TALLOC_CTX *mem_ctx;
-       struct pdb_search *result;
-
-       mem_ctx = talloc_init("pdb_search");
-       if (mem_ctx == NULL) {
-               DEBUG(0, ("talloc_init failed\n"));
-               return NULL;
+       if (!search->search_ended) {
+               search->search_end(search);
        }
+       return 0;
+}
 
-       result = TALLOC_P(mem_ctx, struct pdb_search);
+struct pdb_search *pdb_search_init(TALLOC_CTX *mem_ctx,
+                                  enum pdb_search_type type)
+{
+       struct pdb_search *result;
+
+       result = talloc(mem_ctx, struct pdb_search);
        if (result == NULL) {
                DEBUG(0, ("talloc failed\n"));
                return NULL;
        }
 
-       result->mem_ctx = mem_ctx;
        result->type = type;
        result->cache = NULL;
        result->num_entries = 0;
@@ -1737,6 +1738,8 @@ struct pdb_search *pdb_search_init(enum pdb_search_type type)
        result->next_entry = NULL;
        result->search_end = NULL;
 
+       talloc_set_destructor(result, pdb_search_destructor);
+
        return result;
 }
 
@@ -1783,8 +1786,7 @@ static bool next_entry_groups(struct pdb_search *s,
 
        sid_peek_rid(&map->sid, &rid);
 
-       fill_displayentry(s->mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
-                         entry);
+       fill_displayentry(s, rid, 0, map->nt_name, NULL, map->comment, entry);
 
        state->current_group += 1;
        return True;
@@ -1802,7 +1804,7 @@ static bool pdb_search_grouptype(struct pdb_search *search,
 {
        struct group_search *state;
 
-       state = TALLOC_P(search->mem_ctx, struct group_search);
+       state = talloc(search, struct group_search);
        if (state == NULL) {
                DEBUG(0, ("talloc failed\n"));
                return False;
@@ -1853,7 +1855,7 @@ static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
                        break;
                }
 
-               ADD_TO_LARGE_ARRAY(search->mem_ctx, struct samr_displayentry,
+               ADD_TO_LARGE_ARRAY(search, struct samr_displayentry,
                                   entry, &search->cache, &search->num_entries,
                                   &search->cache_size);
        }
@@ -1861,52 +1863,54 @@ static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
        return (search->num_entries > idx) ? &search->cache[idx] : NULL;
 }
 
-struct pdb_search *pdb_search_users(uint32 acct_flags)
+struct pdb_search *pdb_search_users(TALLOC_CTX *mem_ctx, uint32 acct_flags)
 {
        struct pdb_methods *pdb = pdb_get_methods();
        struct pdb_search *result;
 
-       result = pdb_search_init(PDB_USER_SEARCH);
+       result = pdb_search_init(mem_ctx, PDB_USER_SEARCH);
        if (result == NULL) {
                return NULL;
        }
 
        if (!pdb->search_users(pdb, result, acct_flags)) {
-               talloc_destroy(result->mem_ctx);
+               TALLOC_FREE(result);
                return NULL;
        }
        return result;
 }
 
-struct pdb_search *pdb_search_groups(void)
+struct pdb_search *pdb_search_groups(TALLOC_CTX *mem_ctx)
 {
        struct pdb_methods *pdb = pdb_get_methods();
        struct pdb_search *result;
 
-       result = pdb_search_init(PDB_GROUP_SEARCH);
+       result = pdb_search_init(mem_ctx, PDB_GROUP_SEARCH);
        if (result == NULL) {
                 return NULL;
        }
 
        if (!pdb->search_groups(pdb, result)) {
-               talloc_destroy(result->mem_ctx);
+               TALLOC_FREE(result);
                return NULL;
        }
        return result;
 }
 
-struct pdb_search *pdb_search_aliases(const DOM_SID *sid)
+struct pdb_search *pdb_search_aliases(TALLOC_CTX *mem_ctx, const DOM_SID *sid)
 {
        struct pdb_methods *pdb = pdb_get_methods();
        struct pdb_search *result;
 
        if (pdb == NULL) return NULL;
 
-       result = pdb_search_init(PDB_ALIAS_SEARCH);
-       if (result == NULL) return NULL;
+       result = pdb_search_init(mem_ctx, PDB_ALIAS_SEARCH);
+       if (result == NULL) {
+               return NULL;
+       }
 
        if (!pdb->search_aliases(pdb, result, sid)) {
-               talloc_destroy(result->mem_ctx);
+               TALLOC_FREE(result);
                return NULL;
        }
        return result;
@@ -1935,17 +1939,6 @@ uint32 pdb_search_entries(struct pdb_search *search,
        return search->num_entries - start_idx;
 }
 
-void pdb_search_destroy(struct pdb_search *search)
-{
-       if (search == NULL)
-               return;
-
-       if (!search->search_ended)
-               search->search_end(search);
-
-       talloc_destroy(search->mem_ctx);
-}
-
 /*******************************************************************
  trustdom methods
  *******************************************************************/
index 70a1c62bef8f447031a09e1469c32c832f6ad5c4..77b19e3de950a616eb6cc6f63159ec1a8b63518f 100644 (file)
@@ -4349,7 +4349,8 @@ static bool ldapsam_search_next_entry(struct pdb_search *search,
            !ldapsam_search_nextpage(search))
                    return False;
 
-       result = state->ldap2displayentry(state, search->mem_ctx, state->connection->ldap_struct,
+       result = state->ldap2displayentry(state, search,
+                                         state->connection->ldap_struct,
                                          state->current_entry, entry);
 
        if (!result) {
@@ -4508,7 +4509,7 @@ static bool ldapsam_search_users(struct pdb_methods *methods,
                (struct ldapsam_privates *)methods->private_data;
        struct ldap_search_state *state;
 
-       state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
+       state = talloc(search, struct ldap_search_state);
        if (state == NULL) {
                DEBUG(0, ("talloc failed\n"));
                return False;
@@ -4525,10 +4526,10 @@ static bool ldapsam_search_users(struct pdb_methods *methods,
                state->base = lp_ldap_suffix();
 
        state->acct_flags = acct_flags;
-       state->base = talloc_strdup(search->mem_ctx, state->base);
+       state->base = talloc_strdup(search, state->base);
        state->scope = LDAP_SCOPE_SUBTREE;
-       state->filter = get_ldap_filter(search->mem_ctx, "*");
-       state->attrs = talloc_attrs(search->mem_ctx, "uid", "sambaSid",
+       state->filter = get_ldap_filter(search, "*");
+       state->attrs = talloc_attrs(search, "uid", "sambaSid",
                                    "displayName", "description",
                                    "sambaAcctFlags", NULL);
        state->attrsonly = 0;
@@ -4682,7 +4683,7 @@ static bool ldapsam_search_grouptype(struct pdb_methods *methods,
        struct ldap_search_state *state;
        fstring tmp;
 
-       state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
+       state = talloc(search, struct ldap_search_state);
        if (state == NULL) {
                DEBUG(0, ("talloc failed\n"));
                return False;
@@ -4690,15 +4691,14 @@ static bool ldapsam_search_grouptype(struct pdb_methods *methods,
 
        state->connection = ldap_state->smbldap_state;
 
-       state->base = talloc_strdup(search->mem_ctx, lp_ldap_group_suffix());
+       state->base = talloc_strdup(search, lp_ldap_group_suffix());
        state->connection = ldap_state->smbldap_state;
        state->scope = LDAP_SCOPE_SUBTREE;
-       state->filter = talloc_asprintf(search->mem_ctx,
-                                       "(&(objectclass=%s)"
+       state->filter = talloc_asprintf(search, "(&(objectclass=%s)"
                                        "(sambaGroupType=%d)(sambaSID=%s*))",
                                         LDAP_OBJ_GROUPMAP,
                                         type, sid_to_fstring(tmp, sid));
-       state->attrs = talloc_attrs(search->mem_ctx, "cn", "sambaSid",
+       state->attrs = talloc_attrs(search, "cn", "sambaSid",
                                    "displayName", "description",
                                    "sambaGroupType", NULL);
        state->attrsonly = 0;
index b72e0f2cba38ecf2b897c04d90977bdadbc48a65..d663c7f0b2ffac7161adefa0dd21ccdfa9fa7ff3 100644 (file)
@@ -1566,11 +1566,11 @@ static bool smbpasswd_search_next_entry(struct pdb_search *search,
        entry->acct_flags = state->entries[state->current].acct_flags;
 
        entry->account_name = talloc_strdup(
-               search->mem_ctx, state->entries[state->current].account_name);
+               search, state->entries[state->current].account_name);
        entry->fullname = talloc_strdup(
-               search->mem_ctx, state->entries[state->current].fullname);
+               search, state->entries[state->current].fullname);
        entry->description = talloc_strdup(
-               search->mem_ctx, state->entries[state->current].description);
+               search, state->entries[state->current].description);
 
        if ((entry->account_name == NULL) || (entry->fullname == NULL)
            || (entry->description == NULL)) {
@@ -1593,8 +1593,7 @@ static bool smbpasswd_search_users(struct pdb_methods *methods,
        struct smb_passwd *pwd;
        FILE *fp;
 
-       search_state = TALLOC_ZERO_P(search->mem_ctx,
-                                    struct smbpasswd_search_state);
+       search_state = talloc_zero(search, struct smbpasswd_search_state);
        if (search_state == NULL) {
                DEBUG(0, ("talloc failed\n"));
                return false;
index 143a2e239085b2b690d40714a8a36abdf8ce164a..73fcfee4b35304dfeca5a668772e16eaf9b1f96f 100644 (file)
@@ -102,6 +102,7 @@ static int tdbsam_convert_one(struct db_record *rec, void *priv)
                ret = init_samu_from_buffer(user, SAMU_BUFFER_V3,
                                            (uint8 *)rec->value.dptr,
                                            rec->value.dsize);
+               break;
        case 4:
                ret = init_samu_from_buffer(user, SAMU_BUFFER_V4,
                                            (uint8 *)rec->value.dptr,
@@ -141,6 +142,149 @@ static int tdbsam_convert_one(struct db_record *rec, void *priv)
        return 0;
 }
 
+/**********************************************************************
+ Struct and function to backup an old record.
+ *********************************************************************/
+
+struct tdbsam_backup_state {
+       struct db_context *new_db;
+       bool success;
+};
+
+static int backup_copy_fn(struct db_record *orig_rec, void *state)
+{
+       struct tdbsam_backup_state *bs = (struct tdbsam_backup_state *)state;
+       struct db_record *new_rec;
+       NTSTATUS status;
+
+       new_rec = bs->new_db->fetch_locked(bs->new_db, talloc_tos(), orig_rec->key);
+       if (new_rec == NULL) {
+               bs->success = false;
+               return 1;
+       }
+
+       status = new_rec->store(new_rec, orig_rec->value, TDB_INSERT);
+
+       TALLOC_FREE(new_rec);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               bs->success = false;
+                return 1;
+        }
+        return 0;
+}
+
+/**********************************************************************
+ Make a backup of an old passdb and replace the new one with it. We
+ have to do this as between 3.0.x and 3.2.x the hash function changed
+ by mistake (used unsigned char * instead of char *). This means the
+ previous simple update code will fail due to not being able to find
+ existing records to replace in the tdbsam_convert_one() function. JRA.
+ *********************************************************************/
+
+static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       const char *tmp_fname = NULL;
+       struct db_context *tmp_db = NULL;
+       struct db_context *orig_db = *pp_db;
+       struct tdbsam_backup_state bs;
+       int ret;
+
+       tmp_fname = talloc_asprintf(frame, "%s.tmp", dbname);
+       if (!tmp_fname) {
+               TALLOC_FREE(frame);
+               return false;
+       }
+
+       unlink(tmp_fname);
+
+       /* Remember to open this on the NULL context. We need
+        * it to stay around after we return from here. */
+
+       tmp_db = db_open(NULL, tmp_fname, 0,
+                               TDB_DEFAULT, O_CREAT|O_RDWR, 0600);
+       if (tmp_db == NULL) {
+               DEBUG(0, ("tdbsam_convert_backup: Failed to create backup TDB passwd "
+                         "[%s]\n", tmp_fname));
+               TALLOC_FREE(frame);
+               return false;
+       }
+
+       if (orig_db->transaction_start(orig_db) != 0) {
+               DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (1)\n"));
+               unlink(tmp_fname);
+               TALLOC_FREE(tmp_db);
+               TALLOC_FREE(frame);
+               return false;
+       }
+       if (tmp_db->transaction_start(tmp_db) != 0) {
+               DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (2)\n"));
+               orig_db->transaction_cancel(orig_db);
+               unlink(tmp_fname);
+               TALLOC_FREE(tmp_db);
+               TALLOC_FREE(frame);
+               return false;
+       }
+
+       bs.new_db = tmp_db;
+       bs.success = true;
+
+        ret = orig_db->traverse(orig_db, backup_copy_fn, (void *)&bs);
+        if (ret < 0) {
+                DEBUG(0, ("tdbsam_convert_backup: traverse failed\n"));
+                goto cancel;
+        }
+
+       if (!bs.success) {
+               DEBUG(0, ("tdbsam_convert_backup: Rewriting records failed\n"));
+               goto cancel;
+       }
+
+       if (orig_db->transaction_commit(orig_db) != 0) {
+               smb_panic("tdbsam_convert_backup: orig commit failed\n");
+       }
+       if (tmp_db->transaction_commit(tmp_db) != 0) {
+               smb_panic("tdbsam_convert_backup: orig commit failed\n");
+       }
+
+       /* This is safe from other users as we know we're
+        * under a mutex here. */
+
+       if (rename(tmp_fname, dbname) == -1) {
+               DEBUG(0, ("tdbsam_convert_backup: rename of %s to %s failed %s\n",
+                       tmp_fname,
+                       dbname,
+                       strerror(errno)));
+               smb_panic("tdbsam_convert_backup: replace passdb failed\n");
+       }
+
+       TALLOC_FREE(frame);
+       TALLOC_FREE(orig_db);
+
+       DEBUG(1, ("tdbsam_convert_backup: updated %s file.\n",
+               dbname ));
+
+       /* Replace the global db pointer. */
+       *pp_db = tmp_db;
+       return true;
+
+  cancel:
+
+       if (orig_db->transaction_cancel(orig_db) != 0) {
+               smb_panic("tdbsam_convert: transaction_cancel failed");
+       }
+
+       if (tmp_db->transaction_cancel(tmp_db) != 0) {
+               smb_panic("tdbsam_convert: transaction_cancel failed");
+       }
+
+       unlink(tmp_fname);
+       TALLOC_FREE(tmp_db);
+       TALLOC_FREE(frame);
+       return false;
+}
+
 static bool tdbsam_upgrade_next_rid(struct db_context *db)
 {
        TDB_CONTEXT *tdb;
@@ -172,43 +316,50 @@ static bool tdbsam_upgrade_next_rid(struct db_context *db)
        return true;
 }
 
-static bool tdbsam_convert(struct db_context *db, int32 from)
+static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 from)
 {
        struct tdbsam_convert_state state;
+       struct db_context *db = NULL;
        int ret;
 
+       if (!tdbsam_convert_backup(name, pp_db)) {
+               DEBUG(0, ("tdbsam_convert: Could not backup %s\n", name));
+               return false;
+       }
+
+       db = *pp_db;
        state.from = from;
        state.success = true;
 
        if (db->transaction_start(db) != 0) {
-               DEBUG(0, ("Could not start transaction\n"));
+               DEBUG(0, ("tdbsam_convert: Could not start transaction\n"));
                return false;
        }
 
        if (!tdbsam_upgrade_next_rid(db)) {
-               DEBUG(0, ("tdbsam_upgrade_next_rid failed\n"));
+               DEBUG(0, ("tdbsam_convert: tdbsam_upgrade_next_rid failed\n"));
                goto cancel;
        }
 
        ret = db->traverse(db, tdbsam_convert_one, &state);
        if (ret < 0) {
-               DEBUG(0, ("traverse failed\n"));
+               DEBUG(0, ("tdbsam_convert: traverse failed\n"));
                goto cancel;
        }
 
        if (!state.success) {
-               DEBUG(0, ("Converting records failed\n"));
+               DEBUG(0, ("tdbsam_convert: Converting records failed\n"));
                goto cancel;
        }
 
        if (dbwrap_store_int32(db, TDBSAM_VERSION_STRING,
                               TDBSAM_VERSION) != 0) {
-               DEBUG(0, ("Could not store tdbsam version\n"));
+               DEBUG(0, ("tdbsam_convert: Could not store tdbsam version\n"));
                goto cancel;
        }
 
        if (db->transaction_commit(db) != 0) {
-               DEBUG(0, ("Could not commit transaction\n"));
+               DEBUG(0, ("tdbsam_convert: Could not commit transaction\n"));
                return false;
        }
 
@@ -216,7 +367,7 @@ static bool tdbsam_convert(struct db_context *db, int32 from)
 
  cancel:
        if (db->transaction_cancel(db) != 0) {
-               smb_panic("transaction_cancel failed");
+               smb_panic("tdbsam_convert: transaction_cancel failed");
        }
 
        return false;
@@ -261,17 +412,54 @@ static bool tdbsam_open( const char *name )
        }
 
        if ( version < TDBSAM_VERSION ) {
-               DEBUG(1, ("tdbsam_open: Converting version %d database to "
-                         "version %d.\n", version, TDBSAM_VERSION));
+               /*
+                * Ok - we think we're going to have to convert.
+                * Due to the backup process we now must do to
+                * upgrade we have to get a mutex and re-check
+                * the version. Someone else may have upgraded
+                * whilst we were checking.
+                */
+
+               struct named_mutex *mtx = grab_named_mutex(NULL,
+                                               "tdbsam_upgrade_mutex",
+                                               600);
 
-               if ( !tdbsam_convert(db_sam, version) ) {
-                       DEBUG(0, ("tdbsam_open: Error when trying to convert "
-                                 "tdbsam [%s]\n",name));
+               if (!mtx) {
+                       DEBUG(0, ("tdbsam_open: failed to grab mutex.\n"));
                        TALLOC_FREE(db_sam);
                        return false;
                }
 
-               DEBUG(3, ("TDBSAM converted successfully.\n"));
+               /* Re-check the version */
+               version = dbwrap_fetch_int32(db_sam, TDBSAM_VERSION_STRING);
+               if (version == -1) {
+                       version = 0;    /* Version not found, assume version 0 */
+               }
+
+               /* Compare the version */
+               if (version > TDBSAM_VERSION) {
+                       /* Version more recent than the latest known */
+                       DEBUG(0, ("tdbsam_open: unknown version => %d\n", version));
+                       TALLOC_FREE(db_sam);
+                       TALLOC_FREE(mtx);
+                       return false;
+               }
+
+               if ( version < TDBSAM_VERSION ) {
+                       DEBUG(1, ("tdbsam_open: Converting version %d database to "
+                                 "version %d.\n", version, TDBSAM_VERSION));
+
+                       if ( !tdbsam_convert(&db_sam, name, version) ) {
+                               DEBUG(0, ("tdbsam_open: Error when trying to convert "
+                                         "tdbsam [%s]\n",name));
+                               TALLOC_FREE(db_sam);
+                               TALLOC_FREE(mtx);
+                               return false;
+                       }
+
+                       DEBUG(3, ("TDBSAM converted successfully.\n"));
+               }
+               TALLOC_FREE(mtx);
        }
 
        DEBUG(4,("tdbsam_open: successfully opened %s\n", name ));
@@ -882,12 +1070,9 @@ static bool tdbsam_search_next_entry(struct pdb_search *search,
 
        entry->acct_flags = pdb_get_acct_ctrl(user);
        entry->rid = rid;
-       entry->account_name = talloc_strdup(
-               search->mem_ctx, pdb_get_username(user));
-       entry->fullname = talloc_strdup(
-               search->mem_ctx, pdb_get_fullname(user));
-       entry->description = talloc_strdup(
-               search->mem_ctx, pdb_get_acct_desc(user));
+       entry->account_name = talloc_strdup(search, pdb_get_username(user));
+       entry->fullname = talloc_strdup(search, pdb_get_fullname(user));
+       entry->description = talloc_strdup(search, pdb_get_acct_desc(user));
 
        TALLOC_FREE(user);
 
@@ -912,7 +1097,7 @@ static bool tdbsam_search_users(struct pdb_methods *methods,
                return false;
        }
 
-       state = TALLOC_ZERO_P(search->mem_ctx, struct tdbsam_search_state);
+       state = talloc_zero(search, struct tdbsam_search_state);
        if (state == NULL) {
                DEBUG(0, ("talloc failed\n"));
                return false;
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 e19212eea8c74f97e0d6d4475d21d3e19c134ad8..756a6c23b96974c2ef9157fba1729eff6e03cc47 100644 (file)
@@ -273,8 +273,8 @@ static void send_spoolss_notify2_msg(SPOOLSS_NOTIFY_MSG *msg)
         */
 
        if ((num_messages < 100) && (msg->type == JOB_NOTIFY_TYPE) 
-               && (msg->field == JOB_NOTIFY_TOTAL_BYTES 
-                   || msg->field == JOB_NOTIFY_TOTAL_PAGES )) 
+               && (msg->field == JOB_NOTIFY_FIELD_TOTAL_BYTES
+                   || msg->field == JOB_NOTIFY_FIELD_TOTAL_PAGES ))
        {
 
                for (tmp_ptr = notify_queue_head; tmp_ptr; tmp_ptr = tmp_ptr->next) 
@@ -400,7 +400,7 @@ void notify_printer_status_byname(const char *sharename, uint32 status)
        int snum = print_queue_snum(sharename);
 
        send_notify_field_values(sharename, PRINTER_NOTIFY_TYPE, 
-                                PRINTER_NOTIFY_STATUS, snum,
+                                PRINTER_NOTIFY_FIELD_STATUS, snum,
                                 status, 0, 0);
 }
 
@@ -418,7 +418,7 @@ void notify_job_status_byname(const char *sharename, uint32 jobid, uint32 status
        /* Job id stored in id field, status in value1 */
 
        send_notify_field_values(sharename, JOB_NOTIFY_TYPE,
-                                JOB_NOTIFY_STATUS, jobid,
+                                JOB_NOTIFY_FIELD_STATUS, jobid,
                                 status, 0, flags);
 }
 
@@ -433,7 +433,7 @@ void notify_job_total_bytes(const char *sharename, uint32 jobid,
        /* Job id stored in id field, status in value1 */
 
        send_notify_field_values(sharename, JOB_NOTIFY_TYPE,
-                                JOB_NOTIFY_TOTAL_BYTES, jobid,
+                                JOB_NOTIFY_FIELD_TOTAL_BYTES, jobid,
                                 size, 0, 0);
 }
 
@@ -443,21 +443,21 @@ void notify_job_total_pages(const char *sharename, uint32 jobid,
        /* Job id stored in id field, status in value1 */
 
        send_notify_field_values(sharename, JOB_NOTIFY_TYPE,
-                                JOB_NOTIFY_TOTAL_PAGES, jobid,
+                                JOB_NOTIFY_FIELD_TOTAL_PAGES, jobid,
                                 pages, 0, 0);
 }
 
 void notify_job_username(const char *sharename, uint32 jobid, char *name)
 {
        send_notify_field_buffer(
-               sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME,
+               sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME,
                jobid, strlen(name) + 1, name);
 }
 
 void notify_job_name(const char *sharename, uint32 jobid, char *name)
 {
        send_notify_field_buffer(
-               sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT,
+               sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT,
                jobid, strlen(name) + 1, name);
 }
 
@@ -465,7 +465,7 @@ void notify_job_submitted(const char *sharename, uint32 jobid,
                          time_t submitted)
 {
        send_notify_field_buffer(
-               sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED,
+               sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED,
                jobid, sizeof(submitted), (char *)&submitted);
 }
 
@@ -474,7 +474,7 @@ void notify_printer_driver(int snum, char *driver_name)
        const char *sharename = SERVICE(snum);
 
        send_notify_field_buffer(
-               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME,
+               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME,
                snum, strlen(driver_name) + 1, driver_name);
 }
 
@@ -483,7 +483,7 @@ void notify_printer_comment(int snum, char *comment)
        const char *sharename = SERVICE(snum);
 
        send_notify_field_buffer(
-               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT,
+               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT,
                snum, strlen(comment) + 1, comment);
 }
 
@@ -492,7 +492,7 @@ void notify_printer_sharename(int snum, char *share_name)
        const char *sharename = SERVICE(snum);
 
        send_notify_field_buffer(
-               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME,
+               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME,
                snum, strlen(share_name) + 1, share_name);
 }
 
@@ -501,7 +501,7 @@ void notify_printer_printername(int snum, char *printername)
        const char *sharename = SERVICE(snum);
 
        send_notify_field_buffer(
-               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME,
+               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME,
                snum, strlen(printername) + 1, printername);
 }
 
@@ -510,7 +510,7 @@ void notify_printer_port(int snum, char *port_name)
        const char *sharename = SERVICE(snum);
 
        send_notify_field_buffer(
-               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME,
+               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME,
                snum, strlen(port_name) + 1, port_name);
 }
 
@@ -519,7 +519,7 @@ void notify_printer_location(int snum, char *location)
        const char *sharename = SERVICE(snum);
 
        send_notify_field_buffer(
-               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION,
+               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION,
                snum, strlen(location) + 1, location);
 }
 
index d8658e9280f569c290121107e384fa9ee9820666..8e6fe1f364fda426aecbbe4b16986f33b8f8b882 100644 (file)
@@ -343,7 +343,7 @@ static bool upgrade_to_version_3(void)
 static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
                             TDB_DATA data, void *state )
 {
-       prs_struct ps;
+       NTSTATUS status;
        SEC_DESC_BUF *sd_orig = NULL;
        SEC_DESC_BUF *sd_new, *sd_store;
        SEC_DESC *sec, *new_sec;
@@ -362,22 +362,16 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
 
        /* upgrade the security descriptor */
 
-       ZERO_STRUCT( ps );
-
-       prs_init_empty( &ps, ctx, UNMARSHALL );
-       prs_give_memory( &ps, (char *)data.dptr, data.dsize, False );
-
-       if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_orig, &ps, 1 ) ) {
+       status = unmarshall_sec_desc_buf(ctx, data.dptr, data.dsize, &sd_orig);
+       if (!NT_STATUS_IS_OK(status)) {
                /* delete bad entries */
                DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si.  Deleting....\n",
                        (const char *)key.dptr ));
                tdb_delete( tdb_printers, key );
-               prs_mem_free( &ps );
                return 0;
        }
 
        if (!sd_orig) {
-               prs_mem_free( &ps );
                return 0;
        }
        sec = sd_orig->sd;
@@ -385,7 +379,6 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
        /* is this even valid? */
 
        if ( !sec->dacl ) {
-               prs_mem_free( &ps );
                return 0;
        }
 
@@ -416,45 +409,31 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
                                 &global_sid_Builtin_Administrators,
                                 NULL, NULL, &size_new_sec );
        if (!new_sec) {
-               prs_mem_free( &ps );
                return 0;
        }
        sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );
        if (!sd_new) {
-               prs_mem_free( &ps );
                return 0;
        }
 
        if ( !(sd_store = sec_desc_merge( ctx, sd_new, sd_orig )) ) {
                DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
-               prs_mem_free( &ps );
                return 0;
        }
 
-       prs_mem_free( &ps );
-
        /* store it back */
 
        sd_size = ndr_size_security_descriptor(sd_store->sd, NULL, 0)
                + sizeof(SEC_DESC_BUF);
-       if ( !prs_init(&ps, sd_size, ctx, MARSHALL) ) {
-               DEBUG(0,("sec_desc_upg_fn: Failed to allocate prs memory for %s\n", key.dptr ));
-               return 0;
-       }
 
-       if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_store, &ps, 1 ) ) {
+       status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize);
+       if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
-               prs_mem_free( &ps );
                return 0;
        }
 
-       data.dptr = (uint8 *)prs_data_p( &ps );
-       data.dsize = sd_size;
-
        result = tdb_store( tdb_printers, key, data, TDB_REPLACE );
 
-       prs_mem_free( &ps );
-
        /* 0 to continue and non-zero to stop traversal */
 
        return (result == -1);
@@ -789,13 +768,6 @@ bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form
        return (i !=count);
 }
 
-bool get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
-{
-       fstring form_name;
-       unistr2_to_ascii(form_name, uni_formname, sizeof(form_name));
-       return get_a_builtin_ntform_by_string(form_name, form);
-}
-
 /****************************************************************************
  get a form struct list.
 ****************************************************************************/
@@ -4590,24 +4562,25 @@ static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
  got to keep the endians happy :).
 ****************************************************************************/
 
-static bool convert_driver_init( TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode, uint8 *data, uint32 data_len )
+static bool convert_driver_init(TALLOC_CTX *mem_ctx, NT_DEVICEMODE *nt_devmode,
+                               const uint8_t *data, uint32_t data_len)
 {
-       bool       result = False;
-       prs_struct ps;
-       DEVICEMODE devmode;
+       struct spoolss_DeviceMode devmode;
+       enum ndr_err_code ndr_err;
+       DATA_BLOB blob;
 
        ZERO_STRUCT(devmode);
 
-       prs_init_empty(&ps, ctx, UNMARSHALL);
-       ps.data_p      = (char *)data;
-       ps.buffer_size = data_len;
+       blob = data_blob_const(data, data_len);
 
-       if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
-               result = convert_devicemode("", &devmode, &nt_devmode);
-       else
-               DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
+       ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &devmode,
+                       (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(10,("convert_driver_init: error parsing spoolss_DeviceMode\n"));
+               return false;
+       }
 
-       return result;
+       return convert_devicemode("", &devmode, &nt_devmode);
 }
 
 /****************************************************************************
index fc3667ea3a959ff5a0041ed28ab6a4d99be34d56..8524cfb2bd834fc7a2f13a944dc5bf43e4de6427 100644 (file)
@@ -1387,6 +1387,18 @@ static void print_queue_receive(struct messaging_context *msg,
        return;
 }
 
+static void printing_pause_fd_handler(struct tevent_context *ev,
+                                     struct tevent_fd *fde,
+                                     uint16_t flags,
+                                     void *private_data)
+{
+       /*
+        * If pause_pipe[1] is closed it means the parent smbd
+        * and children exited or aborted.
+        */
+       exit_server_cleanly(NULL);
+}
+
 static pid_t background_lpq_updater_pid = -1;
 
 /****************************************************************************
@@ -1415,6 +1427,9 @@ void start_background_queue(void)
        }
 
        if(background_lpq_updater_pid == 0) {
+               struct tevent_fd *fde;
+               int ret;
+
                /* Child. */
                DEBUG(5,("start_background_queue: background LPQ thread started\n"));
 
@@ -1440,60 +1455,21 @@ void start_background_queue(void)
                messaging_register(smbd_messaging_context(), NULL,
                                   MSG_PRINTER_UPDATE, print_queue_receive);
 
-               DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
-               while (1) {
-                       fd_set r_fds, w_fds;
-                       int ret;
-                       struct timeval to;
-                       int maxfd = 0;
-
-                       /* Process a signal and timed events now... */
-                       if (run_events(smbd_event_context(), 0, NULL, NULL)) {
-                               continue;
-                       }
-
-                       to.tv_sec = SMBD_SELECT_TIMEOUT;
-                       to.tv_usec = 0;
-
-                       /*
-                        * Setup the select fd sets.
-                        */
-
-                       FD_ZERO(&r_fds);
-                       FD_ZERO(&w_fds);
-
-                       /*
-                        * Are there any timed events waiting ? If so, ensure we don't
-                        * select for longer than it would take to wait for them.
-                        */
-
-                       {
-                               struct timeval now;
-                               GetTimeOfDay(&now);
-
-                               event_add_to_select_args(smbd_event_context(), &now,
-                                                        &r_fds, &w_fds, &to, &maxfd);
-                       }
-
-                       FD_SET(pause_pipe[1], &r_fds);
-                       maxfd = MAX(pause_pipe[1], maxfd);
-
-                       ret = sys_select(maxfd, &r_fds, &w_fds, NULL, &to);
-
-                       /*
-                        * If pause_pipe[1] is closed it means the parent smbd
-                        * and children exited or aborted. If sys_select()
-                        * failed, then something more sinister is wrong
-                        */
-                       if ((ret < 0) ||
-                           (ret == 1 && FD_ISSET(pause_pipe[1], &r_fds))) {
-                                exit_server_cleanly(NULL);
-                       }
-
-                       if (run_events(smbd_event_context(), ret, &r_fds, &w_fds)) {
-                               continue;
-                       }
+               fde = tevent_add_fd(smbd_event_context(), smbd_event_context(),
+                                   pause_pipe[1], TEVENT_FD_READ,
+                                   printing_pause_fd_handler,
+                                   NULL);
+               if (!fde) {
+                       DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
+                       smb_panic("tevent_add_fd() failed for pause_pipe");
                }
+
+               DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
+               ret = tevent_loop_wait(smbd_event_context());
+               /* should not be reached */
+               DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
+                        ret, (ret == 0) ? "out of events" : strerror(errno)));
+               exit(1);
        }
 
        close(pause_pipe[1]);
@@ -2407,7 +2383,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 192bc78e09f864d0a9e17c546a9d5a938bd20a42..a02293e528c798b25ae68a1ace344d3648119f67 100644 (file)
@@ -385,9 +385,7 @@ static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subk
 
 static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *values )
 {
-       DEVICEMODE      *devmode;
-       prs_struct      prs;
-       uint32          offset;
+       struct spoolss_DeviceMode *devmode;
        UNISTR2         data;
        char            *p;
        uint32 printer_status = PRINTER_STATUS_OK;
@@ -438,40 +436,40 @@ static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *
        init_unistr2( &data, "RAW", UNI_STR_TERMINATE);
        regval_ctr_addvalue( values, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
-               
-       /* use a prs_struct for converting the devmode and security 
-          descriptor to REG_BINARY */
-       
-       if (!prs_init( &prs, RPC_MAX_PDU_FRAG_LEN, values, MARSHALL))
-               return;
-
        /* stream the device mode */
-               
-       if ( (devmode = construct_dev_mode( info2->sharename )) != NULL ) {
-               if ( spoolss_io_devmode( "devmode", &prs, 0, devmode ) ) {
-                       offset = prs_offset( &prs );
-                       regval_ctr_addvalue( values, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset );
+
+       devmode = construct_dev_mode(values,info2->sharename);
+       if (devmode) {
+               DATA_BLOB blob;
+               enum ndr_err_code ndr_err;
+
+               ndr_err = ndr_push_struct_blob(&blob, values, NULL, devmode,
+                               (ndr_push_flags_fn_t)ndr_push_spoolss_DeviceMode);
+
+               if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       regval_ctr_addvalue(values, "Default Devmode", REG_BINARY,
+                                           (const char *)blob.data, blob.length);
                }
        }
-               
-       prs_mem_clear( &prs );
-       prs_set_offset( &prs, 0 );
-               
+
        /* stream the printer security descriptor */
-       
-       if ( info2->secdesc_buf &&
-            info2->secdesc_buf->sd &&
-            info2->secdesc_buf->sd_size )  
+
+       if (info2->secdesc_buf &&
+           info2->secdesc_buf->sd &&
+           info2->secdesc_buf->sd_size)
        {
-               if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sd, &prs, 0 ) ) {
-                       offset = prs_offset( &prs );
-                       regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&prs), offset );
+               NTSTATUS status;
+               DATA_BLOB blob;
+
+               status = marshall_sec_desc(values, info2->secdesc_buf->sd,
+                                          &blob.data, &blob.length);
+               if (NT_STATUS_IS_OK(status)) {
+                       regval_ctr_addvalue(values, "Security", REG_BINARY,
+                                           (const char *)blob.data, blob.length);
                }
        }
 
-       prs_mem_free( &prs );
-
-       return;         
+       return;
 }
 
 /**********************************************************************
index fed3cbdd525bcb22a71bba61d366008fc4ae682a..14716b2f532cb52154ccca9ddd0595e0bf13337a 100644 (file)
@@ -1114,7 +1114,7 @@ static bool _reg_perfcount_marshall_perf_data_block(prs_struct *ps, PERF_DATA_BL
                return False;
        if(!prs_uint32("DefaultObject", ps, depth, &block.DefaultObject))
                return False;
-       if(!spoolss_io_system_time("SystemTime", ps, depth, &block.SystemTime))
+       if(!smb_io_system_time("SystemTime", ps, depth, &block.SystemTime))
                return False;
        if(!prs_uint32("Padding", ps, depth, &block.Padding))
                return False;
index 33de986e78eaff200322bab9fb519418b127cded..68fd96faa872e5b518345d55fe0d2c86c1740dfe 100644 (file)
@@ -44,7 +44,7 @@
 NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
                                TALLOC_CTX *mem_ctx,
                                bool sec_qos, uint32 des_access,
-                               POLICY_HND *pol)
+                               struct policy_handle *pol)
 {
        struct lsa_ObjectAttribute attr;
        struct lsa_QosInfo qos;
@@ -77,7 +77,7 @@ NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
 
 NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
                                 TALLOC_CTX *mem_ctx, bool sec_qos,
-                                uint32 des_access, POLICY_HND *pol)
+                                uint32 des_access, struct policy_handle *pol)
 {
        struct lsa_ObjectAttribute attr;
        struct lsa_QosInfo qos;
@@ -109,7 +109,7 @@ NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
 
 static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli,
                                               TALLOC_CTX *mem_ctx,
-                                              POLICY_HND *pol,
+                                              struct policy_handle *pol,
                                               int num_sids,
                                               const DOM_SID *sids,
                                               char **domains,
@@ -235,7 +235,7 @@ done:
 
 NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,
                                TALLOC_CTX *mem_ctx,
-                               POLICY_HND *pol,
+                               struct policy_handle *pol,
                                int num_sids,
                                const DOM_SID *sids,
                                char ***pdomains,
@@ -344,7 +344,7 @@ fail:
 
 NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,
                                 TALLOC_CTX *mem_ctx,
-                                POLICY_HND *pol, int num_names,
+                                struct policy_handle *pol, int num_names,
                                 const char **names,
                                 const char ***dom_names,
                                 int level,
index 24dbcb01931e9e0125e5e4b22e9d1119e37cd0b9..57f49fb83aa43763154540df46d459abe7ad0d6f 100644 (file)
@@ -65,7 +65,7 @@ static const struct pipe_id_info {
        { PIPE_SRVSVC,          &ndr_table_srvsvc.syntax_id },
        { PIPE_WKSSVC,          &ndr_table_wkssvc.syntax_id },
        { PIPE_WINREG,          &ndr_table_winreg.syntax_id },
-       { PIPE_SPOOLSS,         &syntax_spoolss },
+       { PIPE_SPOOLSS,         &ndr_table_spoolss.syntax_id },
        { PIPE_NETDFS,          &ndr_table_netdfs.syntax_id },
        { PIPE_ECHO,            &ndr_table_rpcecho.syntax_id },
        { PIPE_SHUTDOWN,        &ndr_table_initshutdown.syntax_id },
@@ -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 2ed7119f4b55c3fb68265bca081ea7a192df4a5d..ec200a24ae5c43de8130884d1a5be726fd09eebe 100644 (file)
@@ -27,7 +27,7 @@
 
 NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                          uint32 reg_type, uint32 access_mask,
-                         POLICY_HND *reg_hnd)
+                         struct policy_handle *reg_hnd)
 {
        ZERO_STRUCTP(reg_hnd);
 
index ed42d56a0251f2eea8836520025f171a4e3ebae5..86bc041374c9f7f8c68e2f4db9aeb6c214addfc8 100644 (file)
@@ -282,7 +282,7 @@ void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
 NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli,
                                  TALLOC_CTX *mem_ctx,
                                  uint32_t access_mask,
-                                 POLICY_HND *connect_pol)
+                                 struct policy_handle *connect_pol)
 {
        NTSTATUS status;
        union samr_ConnectInfo info_in, info_out;
index d76d20c96223bf3f004a26210eb463be630447a7..3f369bdab3c2de92f97d5599076d627427474a51 100644 (file)
@@ -279,983 +279,548 @@ WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli,
        return werror;
 }
 
-
-/*********************************************************************
- Decode various spoolss rpc's and info levels
- ********************************************************************/
-
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumForms
 **********************************************************************/
 
-static bool decode_printer_info_0(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
-                               uint32 returned, PRINTER_INFO_0 **info)
+WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli,
+                               TALLOC_CTX *mem_ctx,
+                               struct policy_handle *handle,
+                               uint32_t level,
+                               uint32_t offered,
+                               uint32_t *count,
+                               union spoolss_FormInfo **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);
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
+       DATA_BLOB buffer;
 
-       for (i=0; i<returned; i++) {
-               if (!smb_io_printer_info_0("", 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_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;
-       }
+       status = rpccli_spoolss_EnumForms(cli, mem_ctx,
+                                         handle,
+                                         level,
+                                         (offered > 0) ? &buffer : NULL,
+                                         offered,
+                                         count,
+                                         info,
+                                         &needed,
+                                         &werror);
 
-       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_info_1("", buffer, &inf[i], 0)) {
-                       return False;
-               }
+               status = rpccli_spoolss_EnumForms(cli, mem_ctx,
+                                                 handle,
+                                                 level,
+                                                 (offered > 0) ? &buffer : NULL,
+                                                 offered,
+                                                 count,
+                                                 info,
+                                                 &needed,
+                                                 &werror);
        }
 
-       *info=inf;
-       return True;
+       return werror;
 }
 
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumPrintProcessors
 **********************************************************************/
 
-static bool decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                               uint32 returned, PRINTER_INFO_2 **info)
+WERROR rpccli_spoolss_enumprintprocessors(struct rpc_pipe_client *cli,
+                                         TALLOC_CTX *mem_ctx,
+                                         const char *servername,
+                                         const char *environment,
+                                         uint32_t level,
+                                         uint32_t offered,
+                                         uint32_t *count,
+                                         union spoolss_PrintProcessorInfo **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);
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
+       DATA_BLOB buffer;
 
-       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;
-               }
+       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_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;
-       }
+       status = rpccli_spoolss_EnumPrintProcessors(cli, mem_ctx,
+                                                   servername,
+                                                   environment,
+                                                   level,
+                                                   (offered > 0) ? &buffer : NULL,
+                                                   offered,
+                                                   count,
+                                                   info,
+                                                   &needed,
+                                                   &werror);
 
-       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++) {
-               inf[i].secdesc = NULL;
-               if (!smb_io_printer_info_3("", buffer, &inf[i], 0)) {
-                       return False;
-               }
+               status = rpccli_spoolss_EnumPrintProcessors(cli, mem_ctx,
+                                                           servername,
+                                                           environment,
+                                                           level,
+                                                           (offered > 0) ? &buffer : NULL,
+                                                           offered,
+                                                           count,
+                                                           info,
+                                                           &needed,
+                                                           &werror);
        }
 
-       *info=inf;
-       return True;
+       return werror;
 }
 
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumPrintProcDataTypes
 **********************************************************************/
 
-static bool decode_port_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                       uint32 returned, PORT_INFO_1 **info)
+WERROR rpccli_spoolss_enumprintprocessordatatypes(struct rpc_pipe_client *cli,
+                                                 TALLOC_CTX *mem_ctx,
+                                                 const char *servername,
+                                                 const char *print_processor_name,
+                                                 uint32_t level,
+                                                 uint32_t offered,
+                                                 uint32_t *count,
+                                                 union spoolss_PrintProcDataTypesInfo **info)
 {
-       uint32 i;
-       PORT_INFO_1 *inf;
-
-       if (returned) {
-               inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_1, returned);
-               if (!inf) {
-                       return False;
-               }
-               memset(inf, 0, returned*sizeof(PORT_INFO_1));
-       } 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_port_info_1("", 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_port_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                       uint32 returned, PORT_INFO_2 **info)
-{
-       uint32 i;
-       PORT_INFO_2 *inf;
-
-       if (returned) {
-               inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_2, returned);
-               if (!inf) {
-                       return False;
-               }
-               memset(inf, 0, returned*sizeof(PORT_INFO_2));
-       } else {
-               inf = NULL;
-       }
+       status = rpccli_spoolss_EnumPrintProcDataTypes(cli, mem_ctx,
+                                                      servername,
+                                                      print_processor_name,
+                                                      level,
+                                                      (offered > 0) ? &buffer : NULL,
+                                                      offered,
+                                                      count,
+                                                      info,
+                                                      &needed,
+                                                      &werror);
 
-       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_port_info_2("", buffer, &(inf[i]), 0)) {
-                       return False;
-               }
+               status = rpccli_spoolss_EnumPrintProcDataTypes(cli, mem_ctx,
+                                                              servername,
+                                                              print_processor_name,
+                                                              level,
+                                                              (offered > 0) ? &buffer : NULL,
+                                                              offered,
+                                                              count,
+                                                              info,
+                                                              &needed,
+                                                              &werror);
        }
 
-       *info=inf;
-       return True;
+       return werror;
 }
 
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumPorts
 **********************************************************************/
 
-static bool decode_printer_driver_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                       uint32 returned, DRIVER_INFO_1 **info)
+WERROR rpccli_spoolss_enumports(struct rpc_pipe_client *cli,
+                               TALLOC_CTX *mem_ctx,
+                               const char *servername,
+                               uint32_t level,
+                               uint32_t offered,
+                               uint32_t *count,
+                               union spoolss_PortInfo **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);
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
+       DATA_BLOB buffer;
 
-       for (i=0; i<returned; i++) {
-               if (!smb_io_printer_driver_info_1("", 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_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;
-       }
+       status = rpccli_spoolss_EnumPorts(cli, mem_ctx,
+                                         servername,
+                                         level,
+                                         (offered > 0) ? &buffer : NULL,
+                                         offered,
+                                         count,
+                                         info,
+                                         &needed,
+                                         &werror);
 
-       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_2("", buffer, &(inf[i]), 0)) {
-                       return False;
-               }
+               status = rpccli_spoolss_EnumPorts(cli, mem_ctx,
+                                                 servername,
+                                                 level,
+                                                 (offered > 0) ? &buffer : NULL,
+                                                 offered,
+                                                 count,
+                                                 info,
+                                                 &needed,
+                                                 &werror);
        }
 
-       *info=inf;
-       return True;
+       return werror;
 }
 
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumMonitors
 **********************************************************************/
 
-static bool decode_printer_driver_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                       uint32 returned, DRIVER_INFO_3 **info)
+WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli,
+                                  TALLOC_CTX *mem_ctx,
+                                  const char *servername,
+                                  uint32_t level,
+                                  uint32_t offered,
+                                  uint32_t *count,
+                                  union spoolss_MonitorInfo **info)
 {
-       uint32 i;
-       DRIVER_INFO_3 *inf;
-
-       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);
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
+       DATA_BLOB buffer;
 
-       for (i=0; i<returned; i++) {
-               if (!smb_io_printer_driver_info_3("", 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;
-}
+       status = rpccli_spoolss_EnumMonitors(cli, mem_ctx,
+                                            servername,
+                                            level,
+                                            (offered > 0) ? &buffer : NULL,
+                                            offered,
+                                            count,
+                                            info,
+                                            &needed,
+                                            &werror);
 
-/**********************************************************************
-**********************************************************************/
-
-static bool decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                         uint32 num_jobs, JOB_INFO_1 **jobs)
-{
-       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);
+       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_1("", buffer, &((*jobs)[i]), 0)) {
-                       return False;
-               }
+               status = rpccli_spoolss_EnumMonitors(cli, mem_ctx,
+                                                    servername,
+                                                    level,
+                                                    (offered > 0) ? &buffer : NULL,
+                                                    offered,
+                                                    count,
+                                                    info,
+                                                    &needed,
+                                                    &werror);
        }
 
-       return True;
+       return werror;
 }
 
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumJobs
 **********************************************************************/
 
-static bool decode_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                         uint32 num_jobs, JOB_INFO_2 **jobs)
+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;
-
-       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);
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
+       DATA_BLOB buffer;
 
-       for (i = 0; i < num_jobs; i++) {
-               if (!smb_io_job_info_2("", 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_forms_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
-                          uint32 num_forms, FORM_1 **forms)
-{
-       int i;
-
-       if (num_forms) {
-               *forms = TALLOC_ARRAY(mem_ctx, FORM_1, num_forms);
-               if (*forms == NULL) {
-                       return False;
-               }
-       } else {
-               *forms = NULL;
-       }
+       status = rpccli_spoolss_EnumJobs(cli, mem_ctx,
+                                        handle,
+                                        firstjob,
+                                        numjobs,
+                                        level,
+                                        (offered > 0) ? &buffer : NULL,
+                                        offered,
+                                        count,
+                                        info,
+                                        &needed,
+                                        &werror);
 
-       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_forms; i++) {
-               if (!smb_io_form_1("", buffer, &((*forms)[i]), 0)) {
-                       return False;
-               }
+               status = rpccli_spoolss_EnumJobs(cli, mem_ctx,
+                                                handle,
+                                                firstjob,
+                                                numjobs,
+                                                level,
+                                                (offered > 0) ? &buffer : NULL,
+                                                offered,
+                                                count,
+                                                info,
+                                                &needed,
+                                                &werror);
        }
 
-       return True;
+       return werror;
 }
 
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumPrinterDrivers
 **********************************************************************/
 
-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,
+                                        const char *server,
+                                        const char *environment,
+                                        uint32_t level,
+                                        uint32_t offered,
+                                        uint32_t *count,
+                                        union spoolss_DriverInfo **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 );
-
-               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_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;
-}
-
-/**********************************************************************
-**********************************************************************/
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
+       DATA_BLOB buffer;
 
-WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                             uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ENUMPORTS in;
-        SPOOL_R_ENUMPORTS 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_enumports( &in, server, level, &buffer, offered );
-       
-       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPORTS,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_enumports,
-                   spoolss_io_r_enumports, 
-                   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_enumports( &in, server, level, &buffer, offered );
-
-               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPORTS,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_enumports,
-                           spoolss_io_r_enumports, 
-                           WERR_GENERAL_FAILURE );
-       }
-       
-       if ( !W_ERROR_IS_OK(out.status) )
-               return out.status;
-       
-       switch (level) {
-       case 1:
-               if (!decode_port_info_1(mem_ctx, out.buffer, out.returned, &ctr->port.info_1)) {
-                       return WERR_GENERAL_FAILURE;
-               }
-               break;
-       case 2:
-               if (!decode_port_info_2(mem_ctx, out.buffer, out.returned, &ctr->port.info_2)) {
-                       return WERR_GENERAL_FAILURE;
-               }
-               break;
-       default:
-               return WERR_UNKNOWN_LEVEL;
+       if (offered > 0) {
+               buffer = data_blob_talloc_zero(mem_ctx, offered);
+               W_ERROR_HAVE_NO_MEMORY(buffer.data);
        }
 
-       *num_ports = out.returned;
-
-       return out.status;
-}
+       status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx,
+                                                  server,
+                                                  environment,
+                                                  level,
+                                                  (offered > 0) ? &buffer : NULL,
+                                                  offered,
+                                                  count,
+                                                  info,
+                                                  &needed,
+                                                  &werror);
 
-/**********************************************************************
-**********************************************************************/
+       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);
 
-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 );
-
-       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_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_EnumPrinterDrivers(cli, mem_ctx,
+                                                  server,
+                                                  environment,
+                                                  level,
+                                                  (offered > 0) ? &buffer : NULL,
+                                                  offered,
+                                                  count,
+                                                  info,
+                                                  &needed,
+                                                  &werror);
        }
 
-       return out.status;
+       return werror;
 }
 
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumPrinters
 **********************************************************************/
 
-WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                            POLICY_HND *handle, int level, uint32 *num_forms,
-                            FORM_1 **forms)
+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_ENUMFORMS in;
-       SPOOL_R_ENUMFORMS 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_enumforms( &in, handle, level, &buffer, offered );
-
-       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMFORMS,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_enumforms,
-                   spoolss_io_r_enumforms, 
-                   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_enumforms( &in, handle, level, &buffer, offered );
-
-               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMFORMS,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_enumforms,
-                           spoolss_io_r_enumforms, 
-                           WERR_GENERAL_FAILURE );
-       }
-
-       if (!W_ERROR_IS_OK(out.status))
-               return out.status;
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
+       DATA_BLOB buffer;
 
-       *num_forms = out.numofforms;
-       
-       if (!decode_forms_1(mem_ctx, out.buffer, *num_forms, forms)) {
-               return WERR_GENERAL_FAILURE;
+       if (offered > 0) {
+               buffer = data_blob_talloc_zero(mem_ctx, offered);
+               W_ERROR_HAVE_NO_MEMORY(buffer.data);
        }
 
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
+       status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,
+                                            flags,
+                                            server,
+                                            level,
+                                            (offered > 0) ? &buffer : NULL,
+                                            offered,
+                                            count,
+                                            info,
+                                            &needed,
+                                            &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_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;
-               
-       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;
+               status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,
+                                                    flags,
+                                                    server,
+                                                    level,
+                                                    (offered > 0) ? &buffer : NULL,
+                                                    offered,
+                                                    count,
+                                                    info,
+                                                    &needed,
+                                                    &werror);
        }
-       
-       *returned = out.returned;
 
-       return out.status;
+       return werror;
 }
 
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_GetPrinterData
 **********************************************************************/
 
-WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                 POLICY_HND *hnd, const char *valuename, 
-                                 REGISTRY_VALUE *value)
+WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct policy_handle *handle,
+                                    const char *value_name,
+                                    uint32_t offered,
+                                    enum winreg_Type *type,
+                                    union spoolss_PrinterData *data)
 {
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_GETPRINTERDATA in;
-       SPOOL_R_GETPRINTERDATA out;
-       uint32 offered;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-       offered = 0;
-       make_spoolss_q_getprinterdata( &in, hnd, valuename, offered );
-
-       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATA,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_getprinterdata,
-                   spoolss_io_r_getprinterdata, 
-                   WERR_GENERAL_FAILURE );
-
-       if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
-               offered = out.needed;
-               
-               ZERO_STRUCT(in);
-               ZERO_STRUCT(out);
-               
-               make_spoolss_q_getprinterdata( &in, hnd, valuename, offered );
-
-               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATA,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_getprinterdata,
-                           spoolss_io_r_getprinterdata, 
-                           WERR_GENERAL_FAILURE );
-       }
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
 
-       if (!W_ERROR_IS_OK(out.status))
-               return out.status;      
+       status = rpccli_spoolss_GetPrinterData(cli, mem_ctx,
+                                              handle,
+                                              value_name,
+                                              offered,
+                                              type,
+                                              data,
+                                              &needed,
+                                              &werror);
 
-       /* Return output parameters */
+       if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
+               offered = needed;
 
-       if (out.needed) {
-               value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data, out.needed);
-       } else {
-               value->data_p = NULL;
+               status = rpccli_spoolss_GetPrinterData(cli, mem_ctx,
+                                                      handle,
+                                                      value_name,
+                                                      offered,
+                                                      type,
+                                                      data,
+                                                      &needed,
+                                                      &werror);
        }
-       value->type = out.type;
-       value->size = out.size;
-
-       return out.status;
-}
 
-/**********************************************************************
-**********************************************************************/
-
-WERROR rpccli_spoolss_setprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                 POLICY_HND *hnd, REGISTRY_VALUE *value)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_SETPRINTERDATA in;
-       SPOOL_R_SETPRINTERDATA out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_setprinterdata( &in, hnd, value->valuename, 
-               value->type, (char *)value->data_p, value->size);
-
-       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTERDATA,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_setprinterdata,
-                   spoolss_io_r_setprinterdata, 
-                   WERR_GENERAL_FAILURE );
-                   
-       return out.status;
+       return werror;
 }
 
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumPrinterKey
 **********************************************************************/
 
-WERROR rpccli_spoolss_enumprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                  POLICY_HND *hnd, uint32 ndx,
-                                  uint32 value_offered, uint32 data_offered,
-                                  uint32 *value_needed, uint32 *data_needed,
-                                  REGISTRY_VALUE *value)
+WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct policy_handle *handle,
+                                    const char *key_name,
+                                    const char ***key_buffer,
+                                    uint32_t offered)
 {
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ENUMPRINTERDATA in;
-       SPOOL_R_ENUMPRINTERDATA out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_enumprinterdata( &in, hnd, ndx, value_offered, data_offered );
-
-       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATA,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_enumprinterdata,
-                   spoolss_io_r_enumprinterdata, 
-                   WERR_GENERAL_FAILURE );
-
-       if ( value_needed )
-               *value_needed = out.realvaluesize;
-       if ( data_needed )
-               *data_needed = out.realdatasize;
-               
-       if (!W_ERROR_IS_OK(out.status))
-               return out.status;
-
-       if (value) {
-               rpcstr_pull(value->valuename, out.value, sizeof(value->valuename), -1,
-                           STR_TERMINATE);
-               if (out.realdatasize) {
-                       value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data,
-                                                      out.realdatasize);
-               } else {
-                       value->data_p = NULL;
-               }
-               value->type = out.type;
-               value->size = out.realdatasize;
-       }
-       
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
 
-WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                    POLICY_HND *hnd, const char *keyname, 
-                                    REGVAL_CTR *ctr)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ENUMPRINTERDATAEX in;
-       SPOOL_R_ENUMPRINTERDATAEX out;
-       int i;
-       uint32 offered;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-       offered = 0;
-       make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered );
-
-       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATAEX,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_enumprinterdataex,
-                   spoolss_io_r_enumprinterdataex, 
-                   WERR_GENERAL_FAILURE );
-
-       if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
-               offered = out.needed;
-               
-               ZERO_STRUCT(in);
-               ZERO_STRUCT(out);
-               
-               make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered );
-
-               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATAEX,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_enumprinterdataex,
-                           spoolss_io_r_enumprinterdataex, 
-                           WERR_GENERAL_FAILURE );
-       }
-       
-       if (!W_ERROR_IS_OK(out.status))
-               return out.status;
+       status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx,
+                                              handle,
+                                              key_name,
+                                              key_buffer,
+                                              offered,
+                                              &needed,
+                                              &werror);
 
-       for (i = 0; i < out.returned; i++) {
-               PRINTER_ENUM_VALUES *v = &out.ctr.values[i];
-               fstring name;
+       if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
+               offered = needed;
 
-               rpcstr_pull(name, v->valuename.buffer, sizeof(name), -1, 
-                           STR_TERMINATE);
-               regval_ctr_addvalue(ctr, name, v->type, (const char *)v->data, v->data_len);
+               status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx,
+                                                      handle,
+                                                      key_name,
+                                                      key_buffer,
+                                                      offered,
+                                                      &needed,
+                                                      &werror);
        }
 
-       return out.status;
+       return werror;
 }
 
 /**********************************************************************
+ convencience wrapper around rpccli_spoolss_EnumPrinterDataEx
 **********************************************************************/
 
-WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                 POLICY_HND *hnd, const char *keyname,
-                                 uint16 **keylist, uint32 *len)
+WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct policy_handle *handle,
+                                       const char *key_name,
+                                       uint32_t offered,
+                                       uint32_t *count,
+                                       struct spoolss_PrinterEnumValues **info)
 {
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ENUMPRINTERKEY in;
-       SPOOL_R_ENUMPRINTERKEY out;
-       uint32 offered = 0;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-       make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered );
-
-       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERKEY,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_enumprinterkey,
-                   spoolss_io_r_enumprinterkey, 
-                   WERR_GENERAL_FAILURE );
-
-       if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
-               offered = out.needed;
-               
-               ZERO_STRUCT(in);
-               ZERO_STRUCT(out);
-               
-               make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered );
-
-               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERKEY,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_enumprinterkey,
-                           spoolss_io_r_enumprinterkey, 
-                           WERR_GENERAL_FAILURE );
-       }
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
+
+       status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx,
+                                                 handle,
+                                                 key_name,
+                                                 offered,
+                                                 count,
+                                                 info,
+                                                 &needed,
+                                                 &werror);
 
-       if ( !W_ERROR_IS_OK(out.status) )
-               return out.status;      
-       
-       if (keylist) {
-               *keylist = SMB_MALLOC_ARRAY(uint16, out.keys.buf_len);
-               if (!*keylist) {
-                       return WERR_NOMEM;
-               }
-               memcpy(*keylist, out.keys.buffer, out.keys.buf_len * 2);
-               if (len)
-                       *len = out.keys.buf_len * 2;
+       if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
+               offered = needed;
+
+               status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx,
+                                                         handle,
+                                                         key_name,
+                                                         offered,
+                                                         count,
+                                                         info,
+                                                         &needed,
+                                                         &werror);
        }
 
-       return out.status;
+       return werror;
 }
-/** @} **/
index a6255adf3d833dad3e362257060acfefb2875513..4c105ea3bc10e9d2482ac97011ef6cef4f6b3264 100644 (file)
@@ -40,3 +40,36 @@ bool init_systemtime(struct spoolss_Time *r,
 
        return true;
 }
+
+/*******************************************************************
+ ********************************************************************/
+
+WERROR pull_spoolss_PrinterData(TALLOC_CTX *mem_ctx,
+                               const DATA_BLOB *blob,
+                               union spoolss_PrinterData *data,
+                               enum winreg_Type type)
+{
+       enum ndr_err_code ndr_err;
+       ndr_err = ndr_pull_union_blob(blob, mem_ctx, NULL, data, type,
+                       (ndr_pull_flags_fn_t)ndr_pull_spoolss_PrinterData);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               return WERR_GENERAL_FAILURE;
+       }
+       return WERR_OK;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+WERROR push_spoolss_PrinterData(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
+                               enum winreg_Type type,
+                               union spoolss_PrinterData *data)
+{
+       enum ndr_err_code ndr_err;
+       ndr_err = ndr_push_union_blob(blob, mem_ctx, NULL, data, type,
+                       (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterData);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               return WERR_GENERAL_FAILURE;
+       }
+       return WERR_OK;
+}
index 658ffe30d6d5e54a9951ac8cbf232373b1c968ac..b1d9d8fbe133aa7ffbdccb6b2afaebff4b1432cf 100644 (file)
@@ -61,8 +61,7 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,
        if (subreq == NULL) {
                goto fail;
        }
-       subreq->async.fn = rpc_sock_read_done;
-       subreq->async.private_data = result;
+       tevent_req_set_callback(subreq, rpc_sock_read_done, result);
        return result;
  fail:
        TALLOC_FREE(result);
@@ -71,8 +70,8 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,
 
 static void rpc_sock_read_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.private_data, struct async_req);
+       struct async_req *req =
+               tevent_req_callback_data(subreq, struct async_req);
        struct rpc_sock_read_state *state = talloc_get_type_abort(
                req->private_data, struct rpc_sock_read_state);
        int err;
@@ -123,8 +122,7 @@ static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx,
        if (subreq == NULL) {
                goto fail;
        }
-       subreq->async.fn = rpc_sock_write_done;
-       subreq->async.private_data = result;
+       tevent_req_set_callback(subreq, rpc_sock_write_done, result);
        return result;
  fail:
        TALLOC_FREE(result);
@@ -133,8 +131,8 @@ static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx,
 
 static void rpc_sock_write_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.private_data, struct async_req);
+       struct async_req *req =
+               tevent_req_callback_data(subreq, struct async_req);
        struct rpc_sock_write_state *state = talloc_get_type_abort(
                req->private_data, struct rpc_sock_write_state);
        int err;
diff --git a/source3/rpc_parse/parse_buffer.c b/source3/rpc_parse/parse_buffer.c
deleted file mode 100644 (file)
index 99546ef..0000000
+++ /dev/null
@@ -1,509 +0,0 @@
-/* 
- *  Unix SMB/CIFS implementation.
- *  RPC Pipe client / server routines
- * 
- *  Copyright (C) Andrew Tridgell              1992-2000,
- *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
- *  Copyright (C) Jean François Micouleau      1998-2000,
- *  Copyright (C) Gerald Carter                2000-2005,
- *  Copyright (C) Tim Potter                  2001-2002.
- *
- *  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"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
-/**********************************************************************
- Initialize a new spoolss buff for use by a client rpc
-**********************************************************************/
-bool rpcbuf_init(RPC_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
-{
-       buffer->size = size;
-       buffer->string_at_end = size;
-       if (!prs_init(&buffer->prs, size, ctx, MARSHALL))
-               return false;
-
-       buffer->struct_start = prs_offset(&buffer->prs);
-       return true;
-}
-
-/*******************************************************************
- Read/write a RPC_BUFFER struct.
-********************************************************************/  
-
-bool prs_rpcbuffer(const char *desc, prs_struct *ps, int depth, RPC_BUFFER *buffer)
-{
-       prs_debug(ps, depth, desc, "prs_rpcbuffer");
-       depth++;
-
-       /* reading */
-       if (UNMARSHALLING(ps)) {
-               buffer->size=0;
-               buffer->string_at_end=0;
-               
-               if (!prs_uint32("size", ps, depth, &buffer->size))
-                       return False;
-                                       
-               /*
-                * JRA. I'm not sure if the data in here is in big-endian format if
-                * the client is big-endian. Leave as default (little endian) for now.
-                */
-
-               if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL))
-                       return False;
-
-               if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size))
-                       return False;
-
-               if (!prs_set_offset(&buffer->prs, 0))
-                       return False;
-
-               if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
-                       return False;
-
-               buffer->string_at_end=buffer->size;
-               
-               return True;
-       }
-       else {
-               bool ret = False;
-
-               if (!prs_uint32("size", ps, depth, &buffer->size))
-                       goto out;
-
-               if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size))
-                       goto out;
-
-               ret = True;
-       out:
-
-               /* We have finished with the data in buffer->prs - free it. */
-               prs_mem_free(&buffer->prs);
-
-               return ret;
-       }
-}
-
-/*******************************************************************
- Read/write an RPC_BUFFER* struct.(allocate memory if unmarshalling)
-********************************************************************/  
-
-bool prs_rpcbuffer_p(const char *desc, prs_struct *ps, int depth, RPC_BUFFER **buffer)
-{
-       uint32 data_p;
-
-       /* caputure the pointer value to stream */
-
-       data_p = *buffer ? 0xf000baaa : 0;
-
-       if ( !prs_uint32("ptr", ps, depth, &data_p ))
-               return False;
-
-       /* we're done if there is no data */
-
-       if ( !data_p )
-               return True;
-
-       if ( UNMARSHALLING(ps) ) {
-               if ( !(*buffer = PRS_ALLOC_MEM(ps, RPC_BUFFER, 1)) )
-                       return False;
-       } else {
-               /* Marshalling case. - coverity paranoia - should already be ok if data_p != 0 */
-               if (!*buffer) {
-                       return True;
-               }
-       }
-
-       return prs_rpcbuffer( desc, ps, depth, *buffer);
-}
-
-/****************************************************************************
- Allocate more memory for a RPC_BUFFER.
-****************************************************************************/
-
-bool rpcbuf_alloc_size(RPC_BUFFER *buffer, uint32 buffer_size)
-{
-       prs_struct *ps;
-       uint32 extra_space;
-       uint32 old_offset;
-       
-       /* if we don't need anything. don't do anything */
-       
-       if ( buffer_size == 0x0 )
-               return True;
-
-       if (!buffer) {
-               return False;
-       }
-
-       ps= &buffer->prs;
-
-       /* damn, I'm doing the reverse operation of prs_grow() :) */
-       if (buffer_size < prs_data_size(ps))
-               extra_space=0;
-       else    
-               extra_space = buffer_size - prs_data_size(ps);
-
-       /*
-        * save the offset and move to the end of the buffer
-        * prs_grow() checks the extra_space against the offset
-        */
-       old_offset=prs_offset(ps);      
-       prs_set_offset(ps, prs_data_size(ps));
-       
-       if (!prs_grow(ps, extra_space))
-               return False;
-
-       prs_set_offset(ps, old_offset);
-
-       buffer->string_at_end=prs_data_size(ps);
-
-       return True;
-}
-
-/*******************************************************************
- move a BUFFER from the query to the reply.
- As the data pointers in RPC_BUFFER are malloc'ed, not talloc'ed,
- this is ok. This is an OPTIMIZATION and is not strictly neccessary.
- Clears the memory to zero also.
-********************************************************************/  
-
-void rpcbuf_move(RPC_BUFFER *src, RPC_BUFFER **dest)
-{
-       if ( !src ) {
-               *dest = NULL;
-               return;
-       }
-
-       prs_switch_type( &src->prs, MARSHALL );
-
-       if ( !prs_set_offset(&src->prs, 0) )
-               return;
-
-       prs_force_dynamic( &src->prs );
-       prs_mem_clear( &src->prs );
-
-       *dest = src;
-}
-
-/*******************************************************************
- Get the size of a BUFFER struct.
-********************************************************************/  
-
-uint32 rpcbuf_get_size(RPC_BUFFER *buffer)
-{
-       return (buffer->size);
-}
-
-
-/*******************************************************************
- * write a UNICODE string and its relative pointer.
- * used by all the RPC structs passing a buffer
- *
- * As I'm a nice guy, I'm forcing myself to explain this code.
- * MS did a good job in the overall spoolss code except in some
- * functions where they are passing the API buffer directly in the
- * RPC request/reply. That's to maintain compatiility at the API level.
- * They could have done it the good way the first time.
- *
- * So what happen is: the strings are written at the buffer's end, 
- * in the reverse order of the original structure. Some pointers to
- * the strings are also in the buffer. Those are relative to the
- * buffer's start.
- *
- * If you don't understand or want to change that function,
- * first get in touch with me: jfm@samba.org
- *
- ********************************************************************/
-
-bool smb_io_relstr(const char *desc, RPC_BUFFER *buffer, int depth, UNISTR *string)
-{
-       prs_struct *ps=&buffer->prs;
-       
-       if (MARSHALLING(ps)) {
-               uint32 struct_offset = prs_offset(ps);
-               uint32 relative_offset;
-               
-               buffer->string_at_end -= (size_of_relative_string(string) - 4);
-               if(!prs_set_offset(ps, buffer->string_at_end))
-                       return False;
-#if 0  /* JERRY */
-               /*
-                * Win2k does not align strings in a buffer
-                * Tested against WinNT 4.0 SP 6a & 2k SP2  --jerry
-                */
-               if (!prs_align(ps))
-                       return False;
-#endif
-               buffer->string_at_end = prs_offset(ps);
-               
-               /* write the string */
-               if (!smb_io_unistr(desc, string, ps, depth))
-                       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)
-                       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 (!smb_io_unistr(desc, string, ps, depth))
-                       return False;
-
-               if(!prs_set_offset(ps, old_offset))
-                       return False;
-       }
-       return True;
-}
-
-/*******************************************************************
- * write a array of UNICODE strings and its relative pointer.
- * used by 2 RPC structs
- ********************************************************************/
-
-bool smb_io_relarraystr(const char *desc, RPC_BUFFER *buffer, int depth, uint16 **string)
-{
-       UNISTR chaine;
-       
-       prs_struct *ps=&buffer->prs;
-       
-       if (MARSHALLING(ps)) {
-               uint32 struct_offset = prs_offset(ps);
-               uint32 relative_offset;
-               uint16 *p;
-               uint16 *q;
-               uint16 zero=0;
-               p=*string;
-               q=*string;
-
-               /* first write the last 0 */
-               buffer->string_at_end -= 2;
-               if(!prs_set_offset(ps, buffer->string_at_end))
-                       return False;
-
-               if(!prs_uint16("leading zero", ps, depth, &zero))
-                       return False;
-
-               while (p && (*p!=0)) {  
-                       while (*q!=0)
-                               q++;
-
-                       /* Yes this should be malloc not talloc. Don't change. */
-
-                       chaine.buffer = (uint16 *)
-                               SMB_MALLOC((q-p+1)*sizeof(uint16));
-                       if (chaine.buffer == NULL)
-                               return False;
-
-                       memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16));
-
-                       buffer->string_at_end -= (q-p+1)*sizeof(uint16);
-
-                       if(!prs_set_offset(ps, buffer->string_at_end)) {
-                               SAFE_FREE(chaine.buffer);
-                               return False;
-                       }
-
-                       /* write the string */
-                       if (!smb_io_unistr(desc, &chaine, ps, depth)) {
-                               SAFE_FREE(chaine.buffer);
-                               return False;
-                       }
-                       q++;
-                       p=q;
-
-                       SAFE_FREE(chaine.buffer);
-               }
-               
-               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 {
-
-               /* UNMARSHALLING */
-
-               uint32 old_offset;
-               uint16 *chaine2=NULL;
-               int l_chaine=0;
-               int l_chaine2=0;
-               size_t realloc_size = 0;
-
-               *string=NULL;
-                               
-               /* read the offset */
-               if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
-                       return False;
-
-               old_offset = prs_offset(ps);
-               if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
-                       return False;
-       
-               do {
-                       if (!smb_io_unistr(desc, &chaine, ps, depth)) {
-                               SAFE_FREE(chaine2);
-                               return False;
-                       }
-                       
-                       l_chaine=str_len_uni(&chaine);
-                       
-                       /* we're going to add two more bytes here in case this
-                          is the last string in the array and we need to add 
-                          an extra NULL for termination */
-                       if (l_chaine > 0) {
-                               realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16);
-
-                               /* Yes this should be realloc - it's freed below. JRA */
-
-                               if((chaine2=(uint16 *)SMB_REALLOC(chaine2, realloc_size)) == NULL) {
-                                       return False;
-                               }
-                               memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
-                               l_chaine2+=l_chaine+1;
-                       }
-               
-               } while(l_chaine!=0);
-               
-               /* the end should be bould NULL terminated so add 
-                  the second one here */
-               if (chaine2)
-               {
-                       chaine2[l_chaine2] = '\0';
-                       *string=(uint16 *)TALLOC_MEMDUP(prs_get_mem_context(ps),chaine2,realloc_size);
-                       SAFE_FREE(chaine2);
-                       if (!*string) {
-                               return False;
-                       }
-               }
-
-               if(!prs_set_offset(ps, old_offset))
-                       return False;
-       }
-       return True;
-}
-
-/*******************************************************************
- Parse a DEVMODE structure and its relative pointer.
-********************************************************************/
-
-bool smb_io_relsecdesc(const char *desc, RPC_BUFFER *buffer, int depth, SEC_DESC **secdesc)
-{
-       prs_struct *ps= &buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_relsecdesc");
-       depth++;
-
-       if (MARSHALLING(ps)) {
-               uint32 struct_offset = prs_offset(ps);
-               uint32 relative_offset;
-
-               if (! *secdesc) {
-                       relative_offset = 0;
-                       if (!prs_uint32("offset", ps, depth, &relative_offset))
-                               return False;
-                       return True;
-               }
-               
-               if (*secdesc != NULL) {
-                       buffer->string_at_end -= ndr_size_security_descriptor(*secdesc, NULL, 0);
-
-                       if(!prs_set_offset(ps, buffer->string_at_end))
-                               return False;
-                       /* write the secdesc */
-                       if (!sec_io_desc(desc, secdesc, ps, depth))
-                               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;
-
-               old_offset = prs_offset(ps);
-               if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
-                       return False;
-
-               /* read the sd */
-               if (!sec_io_desc(desc, secdesc, ps, depth))
-                       return False;
-
-               if(!prs_set_offset(ps, old_offset))
-                       return False;
-       }
-       return True;
-}
-
-
-
-/*******************************************************************
- * return the length of a UNICODE string in number of char, includes:
- * - the leading zero
- * - the relative pointer size
- ********************************************************************/
-
-uint32 size_of_relative_string(UNISTR *string)
-{
-       uint32 size=0;
-       
-       size=str_len_uni(string);       /* the string length       */
-       size=size+1;                    /* add the trailing zero   */
-       size=size*2;                    /* convert in char         */
-       size=size+4;                    /* add the size of the ptr */   
-
-#if 0  /* JERRY */
-       /* 
-        * Do not include alignment as Win2k does not align relative
-        * strings within a buffer   --jerry 
-        */
-       /* Ensure size is 4 byte multiple (prs_align is being called...). */
-       /* size += ((4 - (size & 3)) & 3); */
-#endif 
-
-       return size;
-}
-
index 38d5b953766b9ebc30903b64ecc1c9af78cde09a..8b4135a1e89a83cd398924f1f7af6648024a3d5f 100644 (file)
@@ -59,12 +59,45 @@ bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)
 }
 
 /*******************************************************************
- Reads or writes an NTTIME structure.
 ********************************************************************/
 
-bool smb_io_nttime(const char *desc, prs_struct *ps, int depth, NTTIME *nttime)
+bool smb_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
+{
+       if(!prs_uint16("year", ps, depth, &systime->year))
+               return False;
+       if(!prs_uint16("month", ps, depth, &systime->month))
+               return False;
+       if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
+               return False;
+       if(!prs_uint16("day", ps, depth, &systime->day))
+               return False;
+       if(!prs_uint16("hour", ps, depth, &systime->hour))
+               return False;
+       if(!prs_uint16("minute", ps, depth, &systime->minute))
+               return False;
+       if(!prs_uint16("second", ps, depth, &systime->second))
+               return False;
+       if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
 {
-       return smb_io_time( desc, nttime, ps, depth );
+       systime->year=unixtime->tm_year+1900;
+       systime->month=unixtime->tm_mon+1;
+       systime->dayofweek=unixtime->tm_wday;
+       systime->day=unixtime->tm_mday;
+       systime->hour=unixtime->tm_hour;
+       systime->minute=unixtime->tm_min;
+       systime->second=unixtime->tm_sec;
+       systime->milliseconds=0;
+
+       return True;
 }
 
 /*******************************************************************
@@ -152,100 +185,6 @@ void init_unistr(UNISTR *str, const char *buf)
        }
 }
 
-/*******************************************************************
-reads or writes a UNISTR structure.
-XXXX NOTE: UNISTR structures NEED to be null-terminated.
-********************************************************************/
-
-bool smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth)
-{
-       if (uni == NULL)
-               return False;
-
-       prs_debug(ps, depth, desc, "smb_io_unistr");
-       depth++;
-
-       if(!prs_unistr("unistr", ps, depth, uni))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a BUFFER5 structure.
-the buf_len member tells you how large the buffer is.
-********************************************************************/
-bool smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "smb_io_buffer5");
-       depth++;
-
-       if (buf5 == NULL) return False;
-
-       if(!prs_align(ps))
-               return False;
-       if(!prs_uint32("buf_len", ps, depth, &buf5->buf_len))
-               return False;
-
-       if(buf5->buf_len) {
-               if(!prs_buffer5(True, "buffer" , ps, depth, buf5))
-                       return False;
-       }
-
-       return True;
-}
-
-/*******************************************************************
-creates a UNISTR2 structure: sets up the buffer, too
-********************************************************************/
-
-void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
-{
-       if (buf != NULL) {
-               *ptr = 1;
-               init_unistr2(str, buf, UNI_STR_TERMINATE);
-       } else {
-               *ptr = 0;
-               init_unistr2(str, NULL, UNI_FLAGS_NONE);
-
-       }
-}
-
-/*******************************************************************
- Copies a UNISTR2 structure.
-********************************************************************/
-
-void copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
-{
-       if (from->buffer == NULL) {
-               ZERO_STRUCTP(str);
-               return;
-       }
-
-       SMB_ASSERT(from->uni_max_len >= from->uni_str_len);
-
-       str->uni_max_len = from->uni_max_len;
-       str->offset      = from->offset;
-       str->uni_str_len = from->uni_str_len;
-
-       /* the string buffer is allocated to the maximum size
-          (the the length of the source string) to prevent
-          reallocation of memory. */
-       if (str->buffer == NULL) {
-               if (str->uni_max_len) {
-                       str->buffer = (uint16 *)TALLOC_ZERO_ARRAY(talloc_tos(), uint16, str->uni_max_len);
-                       if ((str->buffer == NULL)) {
-                               smb_panic("copy_unistr2: talloc fail");
-                               return;
-                       }
-                       /* copy the string */
-                       memcpy(str->buffer, from->buffer, str->uni_max_len*sizeof(uint16));
-               } else {
-                       str->buffer = NULL;
-               }
-       }
-}
-
 /*******************************************************************
  Inits a UNISTR2 structure.
 ********************************************************************/
@@ -301,343 +240,3 @@ void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
        if ( num_chars && ((flags == UNI_MAXLEN_TERMINATE) || (flags == UNI_BROKEN_NON_NULL)) )
                str->uni_max_len++;
 }
-
-/** 
- *  Inits a UNISTR2 structure.
- *  @param  ctx talloc context to allocate string on
- *  @param  str pointer to string to create
- *  @param  buf UCS2 null-terminated buffer to init from
-*/
-
-void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf)
-{
-       uint32 len = buf ? strlen_w(buf) : 0;
-
-       ZERO_STRUCTP(str);
-
-       /* set up string lengths. */
-       str->uni_max_len = len;
-       str->offset = 0;
-       str->uni_str_len = len;
-
-       if (len + 1) {
-               str->buffer = TALLOC_ZERO_ARRAY(ctx, uint16, len + 1);
-               if (str->buffer == NULL) {
-                       smb_panic("init_unistr2_w: talloc fail");
-                       return;
-               }
-       } else {
-               str->buffer = NULL;
-       }
-       
-       /*
-        * don't move this test above ! The UNISTR2 must be initialized !!!
-        * jfm, 7/7/2001.
-        */
-       if (buf==NULL)
-               return;
-       
-       /* Yes, this is a strncpy( foo, bar, strlen(bar)) - but as
-           long as the buffer above is talloc()ed correctly then this
-           is the correct thing to do */
-       if (len+1) {
-               strncpy_w(str->buffer, buf, len + 1);
-       }
-}
-
-/*******************************************************************
- Inits a UNISTR2 structure from a UNISTR
-********************************************************************/
-
-void init_unistr2_from_unistr(TALLOC_CTX *ctx, UNISTR2 *to, const UNISTR *from)
-{
-       uint32 i;
-
-       /* the destination UNISTR2 should never be NULL.
-          if it is it is a programming error */
-
-       /* if the source UNISTR is NULL, then zero out
-          the destination string and return */
-       ZERO_STRUCTP (to);
-       if ((from == NULL) || (from->buffer == NULL))
-               return;
-
-       /* get the length; UNISTR must be NULL terminated */
-       i = 0;
-       while ((from->buffer)[i]!='\0')
-               i++;
-       i++;    /* one more to catch the terminating NULL */
-               /* is this necessary -- jerry?  I need to think */
-
-       /* set up string lengths; uni_max_len is set to i+1
-           because we need to account for the final NULL termination */
-       to->uni_max_len = i;
-       to->offset = 0;
-       to->uni_str_len = i;
-
-       /* allocate the space and copy the string buffer */
-       if (i) {
-               to->buffer = TALLOC_ZERO_ARRAY(ctx, uint16, i);
-               if (to->buffer == NULL)
-                       smb_panic("init_unistr2_from_unistr: talloc fail");
-               memcpy(to->buffer, from->buffer, i*sizeof(uint16));
-       } else {
-               to->buffer = NULL;
-       }
-       return;
-}
-
-/*******************************************************************
-  Inits a UNISTR2 structure from a DATA_BLOB.
-  The length of the data_blob must count the bytes of the buffer.
-  Copies the blob data.
-********************************************************************/
-
-void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob) 
-{
-       /* Allocs the unistring */
-       init_unistr2(str, NULL, UNI_FLAGS_NONE);
-       
-       /* Sets the values */
-       str->uni_str_len = blob->length / sizeof(uint16);
-       str->uni_max_len = str->uni_str_len;
-       str->offset = 0;
-       if (blob->length) {
-               str->buffer = (uint16 *) memdup(blob->data, blob->length);
-       } else {
-               str->buffer = NULL;
-       }
-       if ((str->buffer == NULL) && (blob->length > 0)) {
-               smb_panic("init_unistr2_from_datablob: malloc fail");
-       }
-}
-
-/*******************************************************************
- UNISTR2* are a little different in that the pointer and the UNISTR2
- are not necessarily read/written back to back.  So we break it up 
- into 2 separate functions.
- See SPOOL_USER_1 in include/rpc_spoolss.h for an example.
-********************************************************************/
-
-bool prs_io_unistr2_p(const char *desc, prs_struct *ps, int depth, UNISTR2 **uni2)
-{
-       uint32 data_p;
-
-       /* caputure the pointer value to stream */
-
-       data_p = *uni2 ? 0xf000baaa : 0;
-
-       if ( !prs_uint32("ptr", ps, depth, &data_p ))
-               return False;
-
-       /* we're done if there is no data */
-
-       if ( !data_p )
-               return True;
-
-       if (UNMARSHALLING(ps)) {
-               if ( !(*uni2 = PRS_ALLOC_MEM(ps, UNISTR2, 1)) )
-                       return False;
-       }
-
-       return True;
-}
-
-/*******************************************************************
- now read/write the actual UNISTR2.  Memory for the UNISTR2 (but
- not UNISTR2.buffer) has been allocated previously by prs_unistr2_p()
-********************************************************************/
-
-bool prs_io_unistr2(const char *desc, prs_struct *ps, int depth, UNISTR2 *uni2 )
-{
-       /* just return true if there is no pointer to deal with.
-          the memory must have been previously allocated on unmarshalling
-          by prs_unistr2_p() */
-
-       if ( !uni2 )
-               return True;
-
-       /* just pass off to smb_io_unstr2() passing the uni2 address as 
-          the pointer (like you would expect) */
-
-       return smb_io_unistr2( desc, uni2, uni2 ? 1 : 0, ps, depth );
-}
-
-/*******************************************************************
- Reads or writes a UNISTR2 structure.
- XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
-   the uni_str_len member tells you how long the string is;
-   the uni_max_len member tells you how large the buffer is.
-********************************************************************/
-
-bool smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
-{
-       if (uni2 == NULL)
-               return False;
-
-       if (buffer) {
-
-               prs_debug(ps, depth, desc, "smb_io_unistr2");
-               depth++;
-
-               if(!prs_align(ps))
-                       return False;
-               
-               if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len))
-                       return False;
-               if(!prs_uint32("offset     ", ps, depth, &uni2->offset))
-                       return False;
-               if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len))
-                       return False;
-
-               /* buffer advanced by indicated length of string
-                  NOT by searching for null-termination */
-               if(!prs_unistr2(True, "buffer     ", ps, depth, uni2))
-                       return False;
-
-       } else {
-
-               prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL");
-               depth++;
-               memset((char *)uni2, '\0', sizeof(*uni2));
-
-       }
-
-       return True;
-}
-
-/*******************************************************************
- Reads or writes an POLICY_HND structure.
-********************************************************************/
-
-bool smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
-{
-       if (pol == NULL)
-               return False;
-
-       prs_debug(ps, depth, desc, "smb_io_pol_hnd");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-
-       if(UNMARSHALLING(ps))
-               ZERO_STRUCTP(pol);
-       
-       if (!prs_uint32("handle_type", ps, depth, &pol->handle_type))
-               return False;
-       if (!smb_io_uuid("uuid", (struct GUID*)&pol->uuid, ps, depth))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Create a UNISTR3.
-********************************************************************/
-
-void init_unistr3(UNISTR3 *str, const char *buf)
-{
-       if (buf == NULL) {
-               str->uni_str_len=0;
-               str->str.buffer = NULL;
-               return;
-       }
-
-       str->uni_str_len = strlen(buf) + 1;
-
-       if (str->uni_str_len) {
-               str->str.buffer = TALLOC_ZERO_ARRAY(talloc_tos(), uint16, str->uni_str_len);
-               if (str->str.buffer == NULL)
-                       smb_panic("init_unistr3: malloc fail");
-
-               rpcstr_push((char *)str->str.buffer, buf, str->uni_str_len * sizeof(uint16), STR_TERMINATE);
-       } else {
-               str->str.buffer = NULL;
-       }
-}
-
-/*******************************************************************
- Reads or writes a UNISTR3 structure.
-********************************************************************/
-
-bool smb_io_unistr3(const char *desc, UNISTR3 *name, prs_struct *ps, int depth)
-{
-       if (name == NULL)
-               return False;
-
-       prs_debug(ps, depth, desc, "smb_io_unistr3");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-       
-       if(!prs_uint32("uni_str_len", ps, depth, &name->uni_str_len))
-               return False;
-               
-       /* we're done if there is no string */
-       
-       if ( name->uni_str_len == 0 )
-               return True;
-
-       /* don't know if len is specified by uni_str_len member... */
-       /* assume unicode string is unicode-null-terminated, instead */
-
-       if(!prs_unistr3(True, "unistr", name, ps, depth))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Stream a uint64_struct
- ********************************************************************/
-bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64)
-{
-       if (UNMARSHALLING(ps)) {
-               uint32 high, low;
-
-               if (!prs_uint32(name, ps, depth+1, &low))
-                       return False;
-
-               if (!prs_uint32(name, ps, depth+1, &high))
-                       return False;
-
-               *data64 = ((uint64_t)high << 32) + low;
-
-               return True;
-       } else {
-               uint32 high = (*data64) >> 32, low = (*data64) & 0xFFFFFFFF;
-               return prs_uint32(name, ps, depth+1, &low) && 
-                          prs_uint32(name, ps, depth+1, &high);
-       }
-}
-
-/*******************************************************************
-return the length of a UNISTR string.
-********************************************************************/  
-
-uint32 str_len_uni(UNISTR *source)
-{
-       uint32 i=0;
-
-       if (!source->buffer)
-               return 0;
-
-       while (source->buffer[i])
-               i++;
-
-       return i;
-}
-
-/*******************************************************************
- Verifies policy handle
-********************************************************************/
-
-bool policy_handle_is_valid(const POLICY_HND *hnd)
-{
-       POLICY_HND zero_pol;
-
-       ZERO_STRUCT(zero_pol);
-       return ((memcmp(&zero_pol, hnd, sizeof(POLICY_HND)) == 0) ? false : true );
-}
index bc9202ccccfd605317e33ec2cda6f8886b44f555..94732b0a740342fa7166f453f0bcd7d3b148b91c 100644 (file)
@@ -759,6 +759,30 @@ bool prs_int32(const char *name, prs_struct *ps, int depth, int32 *data32)
        return True;
 }
 
+/*******************************************************************
+ Stream a uint64_struct
+ ********************************************************************/
+bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64)
+{
+       if (UNMARSHALLING(ps)) {
+               uint32 high, low;
+
+               if (!prs_uint32(name, ps, depth+1, &low))
+                       return False;
+
+               if (!prs_uint32(name, ps, depth+1, &high))
+                       return False;
+
+               *data64 = ((uint64_t)high << 32) + low;
+
+               return True;
+       } else {
+               uint32 high = (*data64) >> 32, low = (*data64) & 0xFFFFFFFF;
+               return prs_uint32(name, ps, depth+1, &low) &&
+                          prs_uint32(name, ps, depth+1, &high);
+       }
+}
+
 /*******************************************************************
  Stream a NTSTATUS
  ********************************************************************/
@@ -1024,37 +1048,6 @@ bool prs_uint32s(bool charmode, const char *name, prs_struct *ps, int depth, uin
        return True;
 }
 
-/******************************************************************
- Stream an array of unicode string, length/buffer specified separately,
- in uint16 chars. The unicode string is already in little-endian format.
- ********************************************************************/
-
-bool prs_buffer5(bool charmode, const char *name, prs_struct *ps, int depth, BUFFER5 *str)
-{
-       char *p;
-       char *q = prs_mem_get(ps, str->buf_len * sizeof(uint16));
-       if (q == NULL)
-               return False;
-
-       /* If the string is empty, we don't have anything to stream */
-       if (str->buf_len==0)
-               return True;
-
-       if (UNMARSHALLING(ps)) {
-               str->buffer = PRS_ALLOC_MEM(ps,uint16,str->buf_len);
-               if (str->buffer == NULL)
-                       return False;
-       }
-
-       p = (char *)str->buffer;
-
-       dbg_rw_punival(charmode, name, depth, ps, q, p, str->buf_len);
-       
-       ps->data_offset += (str->buf_len * sizeof(uint16));
-
-       return True;
-}
-
 /******************************************************************
  Stream a unicode string, length/buffer specified separately,
  in uint16 chars. The unicode string is already in little-endian format.
@@ -1093,36 +1086,6 @@ bool prs_unistr2(bool charmode, const char *name, prs_struct *ps, int depth, UNI
        return True;
 }
 
-/******************************************************************
- Stream a unicode string, length/buffer specified separately,
- in uint16 chars. The unicode string is already in little-endian format.
- ********************************************************************/
-
-bool prs_unistr3(bool charmode, const char *name, UNISTR3 *str, prs_struct *ps, int depth)
-{
-       char *p;
-       char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16));
-       if (q == NULL)
-               return False;
-
-       if (UNMARSHALLING(ps)) {
-               if (str->uni_str_len) {
-                       str->str.buffer = PRS_ALLOC_MEM(ps,uint16,str->uni_str_len);
-                       if (str->str.buffer == NULL)
-                               return False;
-               } else {
-                       str->str.buffer = NULL;
-               }
-       }
-
-       p = (char *)str->str.buffer;
-
-       dbg_rw_punival(charmode, name, depth, ps, q, p, str->uni_str_len);
-       ps->data_offset += (str->uni_str_len * sizeof(uint16));
-
-       return True;
-}
-
 /*******************************************************************
  Stream a unicode  null-terminated string. As the string is already
  in little-endian format then do it as a stream of bytes.
index 1477a4c81e611f7412462dfaed9d2b21b65a8214..14a4effbf036c2856c82ed7ca680093b967bde0f 100644 (file)
@@ -639,13 +639,3 @@ bool smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len,
 
        return True;
 }
-
-const struct ndr_syntax_id syntax_spoolss = {
-       {
-               0x12345678, 0x1234, 0xabcd,
-               { 0xef, 0x00 },
-               { 0x01, 0x23,
-                 0x45, 0x67, 0x89, 0xab }
-       }, 0x01
-};
-
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
deleted file mode 100644 (file)
index 78c041f..0000000
+++ /dev/null
@@ -1,3101 +0,0 @@
-/* 
- *  Unix SMB/CIFS implementation.
- *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-2000,
- *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
- *  Copyright (C) Jean François Micouleau      1998-2000,
- *  Copyright (C) Gerald Carter                2000-2002,
- *  Copyright (C) Tim Potter                  2001-2002.
- *
- *  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"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
-
-/*******************************************************************
-This should be moved in a more generic lib.
-********************************************************************/  
-
-bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
-{
-       if(!prs_uint16("year", ps, depth, &systime->year))
-               return False;
-       if(!prs_uint16("month", ps, depth, &systime->month))
-               return False;
-       if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
-               return False;
-       if(!prs_uint16("day", ps, depth, &systime->day))
-               return False;
-       if(!prs_uint16("hour", ps, depth, &systime->hour))
-               return False;
-       if(!prs_uint16("minute", ps, depth, &systime->minute))
-               return False;
-       if(!prs_uint16("second", ps, depth, &systime->second))
-               return False;
-       if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
-{
-       systime->year=unixtime->tm_year+1900;
-       systime->month=unixtime->tm_mon+1;
-       systime->dayofweek=unixtime->tm_wday;
-       systime->day=unixtime->tm_mday;
-       systime->hour=unixtime->tm_hour;
-       systime->minute=unixtime->tm_min;
-       systime->second=unixtime->tm_sec;
-       systime->milliseconds=0;
-
-       return True;
-}
-
-/*******************************************************************
- * read or write a DEVICEMODE struct.
- * on reading allocate memory for the private member
- ********************************************************************/
-
-#define DM_NUM_OPTIONAL_FIELDS                 8
-
-bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
-{
-       int available_space;            /* size of the device mode left to parse */
-                                       /* only important on unmarshalling       */
-       int i = 0;
-       uint16 *unistr_buffer;
-       int j;
-                                       
-       struct optional_fields {
-               fstring         name;
-               uint32*         field;
-       } opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
-               { "icmmethod",          NULL },
-               { "icmintent",          NULL },
-               { "mediatype",          NULL },
-               { "dithertype",         NULL },
-               { "reserved1",          NULL },
-               { "reserved2",          NULL },
-               { "panningwidth",       NULL },
-               { "panningheight",      NULL }
-       };
-
-       /* assign at run time to keep non-gcc compilers happy */
-
-       opt_fields[0].field = &devmode->icmmethod;
-       opt_fields[1].field = &devmode->icmintent;
-       opt_fields[2].field = &devmode->mediatype;
-       opt_fields[3].field = &devmode->dithertype;
-       opt_fields[4].field = &devmode->reserved1;
-       opt_fields[5].field = &devmode->reserved2;
-       opt_fields[6].field = &devmode->panningwidth;
-       opt_fields[7].field = &devmode->panningheight;
-               
-       
-       prs_debug(ps, depth, desc, "spoolss_io_devmode");
-       depth++;
-
-       if (UNMARSHALLING(ps)) {
-               devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
-               if (devmode->devicename.buffer == NULL)
-                       return False;
-               unistr_buffer = devmode->devicename.buffer;
-       }
-       else {
-               /* devicename is a static sized string but the buffer we set is not */
-               unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
-               memset( unistr_buffer, 0x0, MAXDEVICENAME );
-               for ( j=0; devmode->devicename.buffer[j]; j++ )
-                       unistr_buffer[j] = devmode->devicename.buffer[j];
-       }
-               
-       if (!prs_uint16uni(True,"devicename", ps, depth, unistr_buffer, MAXDEVICENAME))
-               return False;
-       
-       if (!prs_uint16("specversion",      ps, depth, &devmode->specversion))
-               return False;
-               
-       if (!prs_uint16("driverversion",    ps, depth, &devmode->driverversion))
-               return False;
-       if (!prs_uint16("size",             ps, depth, &devmode->size))
-               return False;
-       if (!prs_uint16("driverextra",      ps, depth, &devmode->driverextra))
-               return False;
-       if (!prs_uint32("fields",           ps, depth, &devmode->fields))
-               return False;
-       if (!prs_uint16("orientation",      ps, depth, &devmode->orientation))
-               return False;
-       if (!prs_uint16("papersize",        ps, depth, &devmode->papersize))
-               return False;
-       if (!prs_uint16("paperlength",      ps, depth, &devmode->paperlength))
-               return False;
-       if (!prs_uint16("paperwidth",       ps, depth, &devmode->paperwidth))
-               return False;
-       if (!prs_uint16("scale",            ps, depth, &devmode->scale))
-               return False;
-       if (!prs_uint16("copies",           ps, depth, &devmode->copies))
-               return False;
-       if (!prs_uint16("defaultsource",    ps, depth, &devmode->defaultsource))
-               return False;
-       if (!prs_uint16("printquality",     ps, depth, &devmode->printquality))
-               return False;
-       if (!prs_uint16("color",            ps, depth, &devmode->color))
-               return False;
-       if (!prs_uint16("duplex",           ps, depth, &devmode->duplex))
-               return False;
-       if (!prs_uint16("yresolution",      ps, depth, &devmode->yresolution))
-               return False;
-       if (!prs_uint16("ttoption",         ps, depth, &devmode->ttoption))
-               return False;
-       if (!prs_uint16("collate",          ps, depth, &devmode->collate))
-               return False;
-
-       if (UNMARSHALLING(ps)) {
-               devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
-               if (devmode->formname.buffer == NULL)
-                       return False;
-               unistr_buffer = devmode->formname.buffer;
-       }
-       else {
-               /* devicename is a static sized string but the buffer we set is not */
-               unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
-               memset( unistr_buffer, 0x0, MAXDEVICENAME );
-               for ( j=0; devmode->formname.buffer[j]; j++ )
-                       unistr_buffer[j] = devmode->formname.buffer[j];
-       }
-       
-       if (!prs_uint16uni(True, "formname",  ps, depth, unistr_buffer, MAXDEVICENAME))
-               return False;
-       if (!prs_uint16("logpixels",        ps, depth, &devmode->logpixels))
-               return False;
-       if (!prs_uint32("bitsperpel",       ps, depth, &devmode->bitsperpel))
-               return False;
-       if (!prs_uint32("pelswidth",        ps, depth, &devmode->pelswidth))
-               return False;
-       if (!prs_uint32("pelsheight",       ps, depth, &devmode->pelsheight))
-               return False;
-       if (!prs_uint32("displayflags",     ps, depth, &devmode->displayflags))
-               return False;
-       if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
-               return False;
-       /* 
-        * every device mode I've ever seen on the wire at least has up 
-        * to the displayfrequency field.   --jerry (05-09-2002)
-        */
-        
-       /* add uint32's + uint16's + two UNICODE strings */
-        
-       available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
-       
-       /* Sanity check - we only have uint32's left tp parse */
-       
-       if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
-               DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
-                       available_space, devmode->size));
-               DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
-               return False;
-       }
-
-       /* 
-        * Conditional parsing.  Assume that the DeviceMode has been 
-        * zero'd by the caller. 
-        */
-       
-       while ((available_space > 0)  && (i < DM_NUM_OPTIONAL_FIELDS))
-       {
-               DEBUG(11, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
-               if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
-                       return False;
-               available_space -= sizeof(uint32);
-               i++;
-       }        
-       
-       /* Sanity Check - we should no available space at this point unless 
-          MS changes the device mode structure */
-               
-       if (available_space) {
-               DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
-               DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
-                       available_space, devmode->size));
-               DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
-               return False;
-       }
-
-
-       if (devmode->driverextra!=0) {
-               if (UNMARSHALLING(ps)) {
-                       devmode->dev_private=PRS_ALLOC_MEM(ps, uint8, devmode->driverextra);
-                       if(devmode->dev_private == NULL)
-                               return False;
-                       DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for dev_private\n",devmode->driverextra)); 
-               }
-                       
-               DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of dev_private\n",devmode->driverextra));
-               if (!prs_uint8s(False, "dev_private",  ps, depth,
-                               devmode->dev_private, devmode->driverextra))
-                       return False;
-       }
-
-       return True;
-}
-
-/*******************************************************************
- * make a structure.
- ********************************************************************/
-
-bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
-                                  const POLICY_HND *handle,
-                                  const char *valuename, uint32 size)
-{
-        if (q_u == NULL) return False;
-
-        DEBUG(5,("make_spoolss_q_getprinterdata\n"));
-
-        q_u->handle = *handle;
-       init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
-        q_u->size = size;
-
-        return True;
-}
-
-/*******************************************************************
- * read a structure.
- * called from spoolss_q_getprinterdata (srv_spoolss.c)
- ********************************************************************/
-
-bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
-{
-       if (q_u == NULL)
-               return False;
-
-       prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-       if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
-               return False;
-       if (!prs_align(ps))
-               return False;
-       if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
-               return False;
-       if (!prs_align(ps))
-               return False;
-       if (!prs_uint32("size", ps, depth, &q_u->size))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- * write a structure.
- * called from spoolss_r_getprinterdata (srv_spoolss.c)
- ********************************************************************/
-
-bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
-{
-       if (r_u == NULL)
-               return False;
-
-       prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-       if (!prs_uint32("type", ps, depth, &r_u->type))
-               return False;
-       if (!prs_uint32("size", ps, depth, &r_u->size))
-               return False;
-       
-       if (UNMARSHALLING(ps) && r_u->size) {
-               r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
-               if(!r_u->data)
-                       return False;
-       }
-
-       if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
-               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;
-}
-
-/*******************************************************************
- * 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 PORT_INFO_1 structure.
-********************************************************************/  
-
-bool smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_port_info_1");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-       
-       if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a PORT_INFO_2 structure.
-********************************************************************/  
-
-bool smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_port_info_2");
-       depth++;        
-       
-       buffer->struct_start=prs_offset(ps);
-       
-       if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
-               return False;
-       if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
-               return False;
-       if (!smb_io_relstr("description", buffer, depth, &info->description))
-               return False;
-       if (!prs_uint32("port_type", ps, depth, &info->port_type))
-               return False;
-       if (!prs_uint32("reserved", ps, depth, &info->reserved))
-               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;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-       
-       prs_debug(ps, depth, desc, "smb_io_form_1");
-       depth++;
-               
-       buffer->struct_start=prs_offset(ps);
-       
-       if (!prs_uint32("flag", ps, depth, &info->flag))
-               return False;
-               
-       if (!smb_io_relstr("name", buffer, depth, &info->name))
-               return False;
-
-       if (!prs_uint32("width", ps, depth, &info->width))
-               return False;
-       if (!prs_uint32("length", ps, depth, &info->length))
-               return False;
-       if (!prs_uint32("left", ps, depth, &info->left))
-               return False;
-       if (!prs_uint32("top", ps, depth, &info->top))
-               return False;
-       if (!prs_uint32("right", ps, depth, &info->right))
-               return False;
-       if (!prs_uint32("bottom", ps, depth, &info->bottom))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a PORT_INFO_1 structure.
-********************************************************************/  
-
-bool smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_port_1");
-       depth++;
-
-       buffer->struct_start=prs_offset(ps);
-
-       if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a PORT_INFO_2 structure.
-********************************************************************/  
-
-bool smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_port_2");
-       depth++;
-
-       buffer->struct_start=prs_offset(ps);
-
-       if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
-               return False;
-       if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
-               return False;
-       if(!smb_io_relstr("description", buffer, depth, &info->description))
-               return False;
-       if(!prs_uint32("port_type", ps, depth, &info->port_type))
-               return False;
-       if(!prs_uint32("reserved", ps, depth, &info->reserved))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
-       depth++;        
-
-       buffer->struct_start=prs_offset(ps);
-       
-       if (smb_io_relstr("name", buffer, depth, &info->name))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
-       depth++;        
-
-       buffer->struct_start=prs_offset(ps);
-       
-       if (smb_io_relstr("name", buffer, depth, &info->name))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
-       depth++;        
-
-       buffer->struct_start=prs_offset(ps);
-
-       if (!smb_io_relstr("name", buffer, depth, &info->name))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
-{
-       prs_struct *ps=&buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
-       depth++;        
-
-       buffer->struct_start=prs_offset(ps);
-
-       if (!smb_io_relstr("name", buffer, depth, &info->name))
-               return False;
-       if (!smb_io_relstr("environment", buffer, depth, &info->environment))
-               return False;
-       if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
-               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_form_1(FORM_1 *info)
-{
-       int size=0;
-
-       size+=size_of_uint32( &info->flag );
-       size+=size_of_relative_string( &info->name );
-       size+=size_of_uint32( &info->width );
-       size+=size_of_uint32( &info->length );
-       size+=size_of_uint32( &info->left );
-       size+=size_of_uint32( &info->top );
-       size+=size_of_uint32( &info->right );
-       size+=size_of_uint32( &info->bottom );
-
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/  
-
-uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
-{
-       int size=0;
-
-       size+=size_of_relative_string( &info->port_name );
-
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/  
-
-uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
-{
-       int size=0;
-
-       size+=size_of_relative_string( &info->port_name );
-       size+=size_of_relative_string( &info->monitor_name );
-       size+=size_of_relative_string( &info->description );
-
-       size+=size_of_uint32( &info->port_type );
-       size+=size_of_uint32( &info->reserved );
-
-       return size;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/  
-
-uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_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_printprocdatatype_info_1(PRINTPROCDATATYPE_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_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;
-}
-
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/  
-
-uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_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_printmonitor_info_2(PRINTMONITOR_2 *info)
-{
-       int size=0;
-       size+=size_of_relative_string( &info->name);
-       size+=size_of_relative_string( &info->environment);
-       size+=size_of_relative_string( &info->dll_name);
-
-       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;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-bool make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
-                               fstring servername, uint32 level, 
-                               RPC_BUFFER *buffer, uint32 offered)
-{
-       q_u->name_ptr = (servername != NULL) ? 1 : 0;
-       init_buf_unistr2(&q_u->name, &q_u->name_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.
- ********************************************************************/
-
-bool make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
-                                const char *name,
-                                const char *environment,
-                                uint32 level,
-                                RPC_BUFFER *buffer, uint32 offered)
-{
-        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;
-}
-
-/*******************************************************************
- Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
-********************************************************************/  
-
-bool spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
-{
-
-       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;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
-{
-
-       prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
-       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_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
-       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("size of buffer needed", ps, depth, &r_u->needed))
-               return False;
-               
-       if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
-               return False;
-               
-       if (!prs_werror("status", ps, depth, &r_u->status))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Parse a SPOOL_R_ENUMPORTS structure.
-********************************************************************/  
-
-bool spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
-       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 spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-
-       if (!prs_uint32("", ps, depth, &q_u->name_ptr))
-               return False;
-       if (!smb_io_unistr2("", &q_u->name,True,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;
-}
-
-/*******************************************************************
- make a BUFFER5 struct from a uint16*
- ******************************************************************/
-
-bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
-{
-
-       buf5->buf_len = len;
-       if (src) {
-               if (len) {
-                       if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
-                               DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
-                               return False;
-                       }
-               } else {
-                       buf5->buffer = NULL;
-               }
-       } else {
-               buf5->buffer=NULL;
-       }
-       
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
-{              
-       prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
-       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 spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
-               return False;
-       if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
-               return False;
-               
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_uint32("", 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;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
-{              
-       prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
-       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 spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
-               return False;
-       if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
-               return False;
-               
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
-               return False;
-       if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_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("buffer", 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_Q_ENUMPRINTMONITORS structure.
-********************************************************************/  
-
-bool spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-               
-       if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
-               return False;
-       if (!smb_io_unistr2("name", &q_u->name, True, 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;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
-{              
-       prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
-       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 spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
-{      
-       prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-       if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
-               return False;
-
-       if (UNMARSHALLING(ps) && r_u->valuesize) {
-               r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
-               if (!r_u->value) {
-                       DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
-                       return False;
-               }
-       }
-
-       if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
-               return False;
-
-       if(!prs_align(ps))
-               return False;
-
-       if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
-               return False;
-
-       if(!prs_uint32("type", ps, depth, &r_u->type))
-               return False;
-
-       if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
-               return False;
-
-       if (UNMARSHALLING(ps) && r_u->datasize) {
-               r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
-               if (!r_u->data) {
-                       DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
-                       return False;
-               }
-       }
-
-       if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
-               return False;
-       if(!prs_align(ps))
-               return False;
-
-       if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
-               return False;
-       if(!prs_werror("status", ps, depth, &r_u->status))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-       if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
-               return False;
-       if(!prs_uint32("index", ps, depth, &q_u->index))
-               return False;
-       if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
-               return False;
-       if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
-               const POLICY_HND *hnd,
-               uint32 idx, uint32 valuelen, uint32 datalen)
-{
-       memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
-       q_u->index=idx;
-       q_u->valuesize=valuelen;
-       q_u->datasize=datalen;
-
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
-                                     const POLICY_HND *hnd, const char *key,
-                                     uint32 size)
-{
-       memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
-       init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
-       q_u->size = size;
-
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
-                                  char* value, uint32 data_type, char* data, uint32 data_size)
-{
-       memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
-       q_u->type = data_type;
-       init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
-
-       q_u->max_len = q_u->real_len = data_size;
-       q_u->data = (unsigned char *)data;
-       
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-       if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
-               return False;
-       if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
-               return False;
-
-       if(!prs_align(ps))
-               return False;
-
-       if(!prs_uint32("type", ps, depth, &q_u->type))
-               return False;
-
-       if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
-               return False;
-
-       switch (q_u->type)
-       {
-               case REG_SZ:
-               case REG_BINARY:
-               case REG_DWORD:
-               case REG_MULTI_SZ:
-                       if (q_u->max_len) {
-                               if (UNMARSHALLING(ps))
-                                       q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
-                               if(q_u->data == NULL)
-                                       return False;
-                               if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
-                                       return False;
-                       }
-                       if(!prs_align(ps))
-                               return False;
-                       break;
-       }       
-       
-       if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-       if(!prs_werror("status",     ps, depth, &r_u->status))
-               return False;
-
-       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.
- ********************************************************************/  
-bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
-                                  POLICY_HND *hnd, const char *key, 
-                                  uint32 size)
-{
-       DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
-
-       memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
-       init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
-       q_u->size = size;
-
-       return True;
-}
-
-/*******************************************************************
- * read a structure.
- ********************************************************************/  
-
-bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-       if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
-               return False;
-               
-       if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
-               return False;
-
-       if(!prs_align(ps))
-               return False;
-       
-       if(!prs_uint32("size", ps, depth, &q_u->size))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- * write a structure.
- ********************************************************************/  
-
-bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-
-       if (!smb_io_buffer5("", &r_u->keys, ps, depth))
-               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.
- ********************************************************************/  
-
-bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-       if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
-               return False;
-               
-       if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
-               return False;
-
-       if(!prs_align(ps))
-               return False;
-       
-       if(!prs_uint32("size", ps, depth, &q_u->size))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
-********************************************************************/  
-
-static bool spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, 
-                               PRINTER_ENUM_VALUES_CTR *ctr, int depth)
-{
-       int     i;
-       uint32  valuename_offset,
-               data_offset,
-               current_offset;
-       const uint32 basic_unit = 20; /* size of static portion of enum_values */
-
-       prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
-       depth++;        
-
-       /* 
-        * offset data begins at 20 bytes per structure * size_of_array.
-        * Don't forget the uint32 at the beginning 
-        * */
-       
-       current_offset = basic_unit * ctr->size_of_array;
-       
-       /* first loop to write basic enum_value information */
-       
-       if (UNMARSHALLING(ps) && ctr->size_of_array) {
-               ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
-               if (!ctr->values)
-                       return False;
-       }
-
-       for (i=0; i<ctr->size_of_array; i++) {
-               uint32 base_offset, return_offset;
-
-               base_offset = prs_offset(ps);
-
-               valuename_offset = current_offset;
-               if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
-                       return False;
-
-               /* Read or write the value. */
-
-               return_offset = prs_offset(ps);
-
-               if (!prs_set_offset(ps, base_offset + valuename_offset)) {
-                       return False;
-               }
-
-               if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
-                       return False;
-
-               /* And go back. */
-               if (!prs_set_offset(ps, return_offset))
-                       return False;
-
-               if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
-                       return False;
-       
-               if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
-                       return False;
-       
-               data_offset = ctr->values[i].value_len + valuename_offset;
-               
-               if (!prs_uint32("data_offset", ps, depth, &data_offset))
-                       return False;
-
-               if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
-                       return False;
-                       
-               /* Read or write the data. */
-
-               return_offset = prs_offset(ps);
-
-               if (!prs_set_offset(ps, base_offset + data_offset)) {
-                       return False;
-               }
-
-               if ( ctr->values[i].data_len ) {
-                       if ( UNMARSHALLING(ps) ) {
-                               ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
-                               if (!ctr->values[i].data)
-                                       return False;
-                       }
-                       if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
-                               return False;
-               }
-
-               current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
-               /* account for 2 byte alignment */
-               current_offset += (current_offset % 2);
-
-               /* Remember how far we got. */
-               data_offset = prs_offset(ps);
-
-               /* And go back. */
-               if (!prs_set_offset(ps, return_offset))
-                       return False;
-
-       }
-
-       /* Go to the last data offset we got to. */
-
-       if (!prs_set_offset(ps, data_offset))
-               return False;
-
-       /* And ensure we're 2 byte aligned. */
-
-       if ( !prs_align_uint16(ps) )
-               return False;
-
-       return True;    
-}
-
-/*******************************************************************
- * write a structure.
- ********************************************************************/  
-
-bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
-{
-       uint32 data_offset, end_offset;
-       prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-
-       if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
-               return False;
-
-       data_offset = prs_offset(ps);
-
-       if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
-               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;
-
-       r_u->ctr.size_of_array = r_u->returned;
-
-       end_offset = prs_offset(ps);
-
-       if (!prs_set_offset(ps, data_offset))
-               return False;
-
-       if (r_u->ctr.size)
-               if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
-                       return False;
-
-       if (!prs_set_offset(ps, end_offset))
-               return False;
-       return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
-                             uint32 level, RPC_BUFFER *buffer,
-                             uint32 offered)
-{
-        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
-        q_u->level = level;
-        q_u->buffer=buffer;
-        q_u->offered=offered;
-
-       return True;
-}
index 2f163a379fba9c3ef3fe3daf4e606ead5297fe47..cf07d97fec0ba3ca7e4857c1e5880a751b3ff455 100644 (file)
@@ -50,7 +50,7 @@ static int eventlog_info_destructor(EVENTLOG_INFO *elog)
  ********************************************************************/
 
 static EVENTLOG_INFO *find_eventlog_info_by_hnd( pipes_struct * p,
-                                               POLICY_HND * handle )
+                                               struct policy_handle * handle )
 {
        EVENTLOG_INFO *info;
 
@@ -174,7 +174,7 @@ static bool get_oldest_entry_hook( EVENTLOG_INFO * info )
 /********************************************************************
  ********************************************************************/
 
-static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hnd )
+static NTSTATUS elog_open( pipes_struct * p, const char *logname, struct policy_handle *hnd )
 {
        EVENTLOG_INFO *elog;
 
@@ -254,7 +254,7 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn
 /********************************************************************
  ********************************************************************/
 
-static NTSTATUS elog_close( pipes_struct *p, POLICY_HND *hnd )
+static NTSTATUS elog_close( pipes_struct *p, struct policy_handle *hnd )
 {
         if ( !( close_policy_hnd( p, hnd ) ) ) {
                 return NT_STATUS_INVALID_HANDLE;
index 2779b8aa18b6a38735c2434ba05827a27424474f..e853bb204724940b2429d3950df2eb28ed7e1a19 100644 (file)
@@ -112,7 +112,7 @@ bool init_pipe_handle_list(pipes_struct *p, const struct ndr_syntax_id *syntax)
   data_ptr is TALLOC_FREE()'ed
 ****************************************************************************/
 
-bool create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void *data_ptr)
+bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_ptr)
 {
        static uint32 pol_hnd_low  = 0;
        static uint32 pol_hnd_high = 0;
@@ -167,7 +167,7 @@ bool create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void *data_ptr)
   find policy by handle - internal version.
 ****************************************************************************/
 
-static struct policy *find_policy_by_hnd_internal(pipes_struct *p, POLICY_HND *hnd, void **data_p)
+static struct policy *find_policy_by_hnd_internal(pipes_struct *p, struct policy_handle *hnd, void **data_p)
 {
        struct policy *pol;
        size_t i;
@@ -197,7 +197,7 @@ static struct policy *find_policy_by_hnd_internal(pipes_struct *p, POLICY_HND *h
   find policy by handle
 ****************************************************************************/
 
-bool find_policy_by_hnd(pipes_struct *p, POLICY_HND *hnd, void **data_p)
+bool find_policy_by_hnd(pipes_struct *p, struct policy_handle *hnd, void **data_p)
 {
        return find_policy_by_hnd_internal(p, hnd, data_p) == NULL ? False : True;
 }
@@ -206,7 +206,7 @@ bool find_policy_by_hnd(pipes_struct *p, POLICY_HND *hnd, void **data_p)
   Close a policy.
 ****************************************************************************/
 
-bool close_policy_hnd(pipes_struct *p, POLICY_HND *hnd)
+bool close_policy_hnd(pipes_struct *p, struct policy_handle *hnd)
 {
        struct policy *pol = find_policy_by_hnd_internal(p, hnd, NULL);
 
index 09b1f664401afabfe7ce91192d11906ee10bd80b..f3ee18da5a50f1f85d3c40861e2cb1103b8087f5 100644 (file)
@@ -2113,7 +2113,11 @@ bool api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss
 
        auth_len = p->hdr.auth_len;
 
-       if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
+       if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN ||
+                       auth_len > RPC_HEADER_LEN +
+                                       RPC_HDR_REQ_LEN +
+                                       RPC_HDR_AUTH_LEN +
+                                       auth_len) {
                DEBUG(0,("Incorrect auth_len %u.\n", (unsigned int)auth_len ));
                return False;
        }
index 33e89c8acbc600272b749a4de4b96c97c890c29c..503e22b653e8baa0cd8eada2bfb0d9d9a5ffadac 100644 (file)
@@ -943,8 +943,8 @@ bool fsp_is_np(struct files_struct *fsp)
 }
 
 struct np_proxy_state {
-       struct async_req_queue *read_queue;
-       struct async_req_queue *write_queue;
+       struct tevent_queue *read_queue;
+       struct tevent_queue *write_queue;
        int fd;
 
        uint8_t *msg;
@@ -1104,11 +1104,11 @@ static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
 
        result->msg = NULL;
 
-       result->read_queue = async_req_queue_init(result);
+       result->read_queue = tevent_queue_create(result, "np_read");
        if (result->read_queue == NULL) {
                goto fail;
        }
-       result->write_queue = async_req_queue_init(result);
+       result->write_queue = tevent_queue_create(result, "np_write");
        if (result->write_queue == NULL) {
                goto fail;
        }
@@ -1175,22 +1175,21 @@ struct np_write_state {
        ssize_t nwritten;
 };
 
-static void np_write_trigger(struct async_req *req);
 static void np_write_done(struct tevent_req *subreq);
 
-struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
-                               struct fake_file_handle *handle,
-                               const uint8_t *data, size_t len)
+struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+                                struct fake_file_handle *handle,
+                                const uint8_t *data, size_t len)
 {
-       struct async_req *result;
+       struct tevent_req *req;
        struct np_write_state *state;
        NTSTATUS status;
 
        DEBUG(6, ("np_write_send: len: %d\n", (int)len));
        dump_data(50, data, len);
 
-       if (!async_req_setup(mem_ctx, &result, &state,
-                            struct np_write_state)) {
+       req = tevent_req_create(mem_ctx, &state, struct np_write_state);
+       if (req == NULL) {
                return NULL;
        }
 
@@ -1214,68 +1213,60 @@ struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
        if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
                struct np_proxy_state *p = talloc_get_type_abort(
                        handle->private_data, struct np_proxy_state);
+               struct tevent_req *subreq;
 
                state->ev = ev;
                state->p = p;
                state->iov.iov_base = CONST_DISCARD(void *, data);
                state->iov.iov_len = len;
 
-               if (!async_req_enqueue(p->write_queue, ev, result,
-                                      np_write_trigger)) {
+               subreq = writev_send(state, ev, p->write_queue, p->fd,
+                                    &state->iov, 1);
+               if (subreq == NULL) {
                        goto fail;
                }
-               return result;
+               tevent_req_set_callback(subreq, np_write_done, req);
+               return req;
        }
 
        status = NT_STATUS_INVALID_HANDLE;
  post_status:
-       if (async_post_ntstatus(result, ev, status)) {
-               return result;
+       if (NT_STATUS_IS_OK(status)) {
+               tevent_req_done(req);
+       } else {
+               tevent_req_nterror(req, status);
        }
+       return tevent_req_post(req, ev);
  fail:
-       TALLOC_FREE(result);
+       TALLOC_FREE(req);
        return NULL;
 }
 
-static void np_write_trigger(struct async_req *req)
-{
-       struct np_write_state *state = talloc_get_type_abort(
-               req->private_data, struct np_write_state);
-       struct tevent_req *subreq;
-
-       subreq = writev_send(state, state->ev, state->p->fd, &state->iov, 1);
-       if (async_req_nomem(subreq, req)) {
-               return;
-       }
-       subreq->async.fn = np_write_done;
-       subreq->async.private_data = req;
-}
-
 static void np_write_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.private_data, struct async_req);
-       struct np_write_state *state = talloc_get_type_abort(
-               req->private_data, struct np_write_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct np_write_state *state = tevent_req_data(
+               req, struct np_write_state);
        ssize_t received;
        int err;
 
        received = writev_recv(subreq, &err);
        if (received < 0) {
-               async_req_nterror(req, map_nt_error_from_unix(err));
+               tevent_req_nterror(req, map_nt_error_from_unix(err));
                return;
        }
        state->nwritten = received;
-       async_req_done(req);
+       tevent_req_done(req);
 }
 
-NTSTATUS np_write_recv(struct async_req *req, ssize_t *pnwritten)
+NTSTATUS np_write_recv(struct tevent_req *req, ssize_t *pnwritten)
 {
-       struct np_write_state *state = talloc_get_type_abort(
-               req->private_data, struct np_write_state);
+       struct np_write_state *state = tevent_req_data(
+               req, struct np_write_state);
        NTSTATUS status;
 
-       if (async_req_is_nterror(req, &status)) {
+       if (tevent_req_is_nterror(req, &status)) {
                return status;
        }
        *pnwritten = state->nwritten;
@@ -1313,19 +1304,19 @@ struct np_read_state {
        bool is_data_outstanding;
 };
 
-static void np_read_trigger(struct async_req *req);
+static void np_read_trigger(struct tevent_req *req, void *private_data);
 static void np_read_done(struct tevent_req *subreq);
 
-struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
-                              struct fake_file_handle *handle,
-                              uint8_t *data, size_t len)
+struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+                               struct fake_file_handle *handle,
+                               uint8_t *data, size_t len)
 {
-       struct async_req *result;
+       struct tevent_req *req;
        struct np_read_state *state;
        NTSTATUS status;
 
-       if (!async_req_setup(mem_ctx, &result, &state,
-                            struct np_read_state)) {
+       req = tevent_req_create(mem_ctx, &state, struct np_read_state);
+       if (req == NULL) {
                return NULL;
        }
 
@@ -1370,44 +1361,46 @@ struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
                state->data = data;
                state->len = len;
 
-               if (!async_req_enqueue(p->read_queue, ev, result,
-                                      np_read_trigger)) {
+               if (!tevent_queue_add(p->read_queue, ev, req, np_read_trigger,
+                                     NULL)) {
                        goto fail;
                }
-               return result;
+               return req;
        }
 
        status = NT_STATUS_INVALID_HANDLE;
  post_status:
-       if (async_post_ntstatus(result, ev, status)) {
-               return result;
+       if (NT_STATUS_IS_OK(status)) {
+               tevent_req_done(req);
+       } else {
+               tevent_req_nterror(req, status);
        }
+       return tevent_req_post(req, ev);
  fail:
-       TALLOC_FREE(result);
+       TALLOC_FREE(req);
        return NULL;
 }
 
-static void np_read_trigger(struct async_req *req)
+static void np_read_trigger(struct tevent_req *req, void *private_data)
 {
-       struct np_read_state *state = talloc_get_type_abort(
-               req->private_data, struct np_read_state);
+       struct np_read_state *state = tevent_req_callback_data(
+               req, struct np_read_state);
        struct tevent_req *subreq;
 
        subreq = read_packet_send(state, state->ev, state->p->fd,
                                  RPC_HEADER_LEN, rpc_frag_more_fn, NULL);
-       if (async_req_nomem(subreq, req)) {
+       if (tevent_req_nomem(subreq, req)) {
                return;
        }
-       subreq->async.fn = np_read_done;
-       subreq->async.private_data = req;
+       tevent_req_set_callback(subreq, np_read_done, req);
 }
 
 static void np_read_done(struct tevent_req *subreq)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.private_data, struct async_req);
-       struct np_read_state *state = talloc_get_type_abort(
-               req->private_data, struct np_read_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct np_read_state *state = tevent_req_data(
+               req, struct np_read_state);
        ssize_t received;
        size_t thistime;
        int err;
@@ -1415,7 +1408,7 @@ static void np_read_done(struct tevent_req *subreq)
        received = read_packet_recv(subreq, state->p, &state->p->msg, &err);
        TALLOC_FREE(subreq);
        if (received == -1) {
-               async_req_nterror(req, map_nt_error_from_unix(err));
+               tevent_req_nterror(req, map_nt_error_from_unix(err));
                return;
        }
 
@@ -1432,18 +1425,18 @@ static void np_read_done(struct tevent_req *subreq)
                state->is_data_outstanding = false;
        }
 
-       async_req_done(req);
+       tevent_req_done(req);
        return;
 }
 
-NTSTATUS np_read_recv(struct async_req *req, ssize_t *nread,
+NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
                      bool *is_data_outstanding)
 {
-       struct np_read_state *state = talloc_get_type_abort(
-               req->private_data, struct np_read_state);
+       struct np_read_state *state = tevent_req_data(
+               req, struct np_read_state);
        NTSTATUS status;
 
-       if (async_req_is_nterror(req, &status)) {
+       if (tevent_req_is_nterror(req, &status)) {
                return status;
        }
        *nread = state->nread;
index 0b8cb35a84372790730e920c3ea603e0f04e8d18..dcbd0963c493f409781fca58f25379f22a2f7e59 100644 (file)
@@ -319,8 +319,8 @@ static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
         * enumerate stuff, so just cache 2 entries.
         */
 
-       static struct disp_info builtin_dispinfo;
-       static struct disp_info domain_dispinfo;
+       static struct disp_info *builtin_dispinfo;
+       static struct disp_info *domain_dispinfo;
 
        /* There are two cases to consider here:
           1) The SID is a domain SID and we look for an equality match, or
@@ -335,18 +335,32 @@ static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
                /*
                 * Necessary only once, but it does not really hurt.
                 */
-               sid_copy(&builtin_dispinfo.sid, &global_sid_Builtin);
+               if (builtin_dispinfo == NULL) {
+                       builtin_dispinfo = talloc_zero(
+                               talloc_autofree_context(), struct disp_info);
+                       if (builtin_dispinfo == NULL) {
+                               return NULL;
+                       }
+               }
+               sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
 
-               return &builtin_dispinfo;
+               return builtin_dispinfo;
        }
 
        if (sid_check_is_domain(psid) || sid_check_is_in_our_domain(psid)) {
                /*
                 * Necessary only once, but it does not really hurt.
                 */
-               sid_copy(&domain_dispinfo.sid, get_global_sam_sid());
+               if (domain_dispinfo == NULL) {
+                       domain_dispinfo = talloc_zero(
+                               talloc_autofree_context(), struct disp_info);
+                       if (domain_dispinfo == NULL) {
+                               return NULL;
+                       }
+               }
+               sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
 
-               return &domain_dispinfo;
+               return domain_dispinfo;
        }
 
        return NULL;
@@ -403,32 +417,11 @@ static void free_samr_cache(DISP_INFO *disp_info)
 
        become_root();
 
-       if (disp_info->users) {
-               DEBUG(10,("free_samr_cache: deleting users cache\n"));
-               pdb_search_destroy(disp_info->users);
-               disp_info->users = NULL;
-       }
-       if (disp_info->machines) {
-               DEBUG(10,("free_samr_cache: deleting machines cache\n"));
-               pdb_search_destroy(disp_info->machines);
-               disp_info->machines = NULL;
-       }
-       if (disp_info->groups) {
-               DEBUG(10,("free_samr_cache: deleting groups cache\n"));
-               pdb_search_destroy(disp_info->groups);
-               disp_info->groups = NULL;
-       }
-       if (disp_info->aliases) {
-               DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
-               pdb_search_destroy(disp_info->aliases);
-               disp_info->aliases = NULL;
-       }
-       if (disp_info->enum_users) {
-               DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
-               pdb_search_destroy(disp_info->enum_users);
-               disp_info->enum_users = NULL;
-       }
-       disp_info->enum_acb_mask = 0;
+       TALLOC_FREE(disp_info->users);
+       TALLOC_FREE(disp_info->machines);
+       TALLOC_FREE(disp_info->groups);
+       TALLOC_FREE(disp_info->aliases);
+       TALLOC_FREE(disp_info->enum_users);
 
        unbecome_root();
 }
@@ -524,7 +517,7 @@ static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
        }
 
        if (info->users == NULL) {
-               info->users = pdb_search_users(acct_flags);
+               info->users = pdb_search_users(info, acct_flags);
                if (info->users == NULL) {
                        return 0;
                }
@@ -548,7 +541,7 @@ static uint32 count_sam_groups(struct disp_info *info)
        }
 
        if (info->groups == NULL) {
-               info->groups = pdb_search_groups();
+               info->groups = pdb_search_groups(info);
                if (info->groups == NULL) {
                        return 0;
                }
@@ -567,7 +560,7 @@ static uint32 count_sam_aliases(struct disp_info *info)
        struct samr_displayentry *entry;
 
        if (info->aliases == NULL) {
-               info->aliases = pdb_search_aliases(&info->sid);
+               info->aliases = pdb_search_aliases(info, &info->sid);
                if (info->aliases == NULL) {
                        return 0;
                }
@@ -726,7 +719,7 @@ NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
 /*******************************************************************
 ********************************************************************/
 
-static bool get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
+static bool get_lsa_policy_samr_sid( pipes_struct *p, struct policy_handle *pol,
                                        DOM_SID *sid, uint32 *acc_granted,
                                        DISP_INFO **ppdisp_info)
 {
@@ -1012,12 +1005,12 @@ NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
 
        if ((info->disp_info->enum_users != NULL) &&
            (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
-               pdb_search_destroy(info->disp_info->enum_users);
-               info->disp_info->enum_users = NULL;
+               TALLOC_FREE(info->disp_info->enum_users);
        }
 
        if (info->disp_info->enum_users == NULL) {
-               info->disp_info->enum_users = pdb_search_users(r->in.acct_flags);
+               info->disp_info->enum_users = pdb_search_users(
+                       info->disp_info, r->in.acct_flags);
                info->disp_info->enum_acb_mask = r->in.acct_flags;
        }
 
@@ -1149,7 +1142,7 @@ NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
        become_root();
 
        if (info->disp_info->groups == NULL) {
-               info->disp_info->groups = pdb_search_groups();
+               info->disp_info->groups = pdb_search_groups(info->disp_info);
 
                if (info->disp_info->groups == NULL) {
                        unbecome_root();
@@ -1216,7 +1209,8 @@ NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
        become_root();
 
        if (info->disp_info->aliases == NULL) {
-               info->disp_info->aliases = pdb_search_aliases(&info->sid);
+               info->disp_info->aliases = pdb_search_aliases(
+                       info->disp_info, &info->sid);
                if (info->disp_info->aliases == NULL) {
                        unbecome_root();
                        return NT_STATUS_ACCESS_DENIED;
@@ -1547,7 +1541,8 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
        case 0x1:
        case 0x4:
                if (info->disp_info->users == NULL) {
-                       info->disp_info->users = pdb_search_users(ACB_NORMAL);
+                       info->disp_info->users = pdb_search_users(
+                               info->disp_info, ACB_NORMAL);
                        if (info->disp_info->users == NULL) {
                                unbecome_root();
                                return NT_STATUS_ACCESS_DENIED;
@@ -1565,8 +1560,8 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
                break;
        case 0x2:
                if (info->disp_info->machines == NULL) {
-                       info->disp_info->machines =
-                               pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
+                       info->disp_info->machines = pdb_search_users(
+                               info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
                        if (info->disp_info->machines == NULL) {
                                unbecome_root();
                                return NT_STATUS_ACCESS_DENIED;
@@ -1585,7 +1580,8 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
        case 0x3:
        case 0x5:
                if (info->disp_info->groups == NULL) {
-                       info->disp_info->groups = pdb_search_groups();
+                       info->disp_info->groups = pdb_search_groups(
+                               info->disp_info);
                        if (info->disp_info->groups == NULL) {
                                unbecome_root();
                                return NT_STATUS_ACCESS_DENIED;
@@ -2126,8 +2122,6 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
 {
        struct samu *sampass=NULL;
        DOM_SID sid;
-       POLICY_HND domain_pol = *r->in.domain_handle;
-       POLICY_HND *user_pol = r->out.user_handle;
        struct samr_info *info = NULL;
        SEC_DESC *psd = NULL;
        uint32    acc_granted;
@@ -2139,7 +2133,7 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
 
        /* find the domain policy handle and get domain SID / access bits in the domain policy. */
 
-       if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
+       if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
                return NT_STATUS_INVALID_HANDLE;
 
        nt_status = access_check_samr_function(acc_granted,
@@ -2192,7 +2186,7 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
        info->acc_granted = acc_granted;
 
        /* get a (unique) handle.  open a policy on it. */
-       if (!create_policy_hnd(p, user_pol, info))
+       if (!create_policy_hnd(p, r->out.user_handle, info))
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 
        return NT_STATUS_OK;
@@ -3036,9 +3030,7 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
 {
        const char *account = NULL;
        DOM_SID sid;
-       POLICY_HND dom_pol = *r->in.domain_handle;
        uint32_t acb_info = r->in.acct_flags;
-       POLICY_HND *user_pol = r->out.user_handle;
        struct samr_info *info = NULL;
        NTSTATUS nt_status;
        uint32 acc_granted;
@@ -3051,7 +3043,7 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
        DISP_INFO *disp_info = NULL;
 
        /* Get the domain SID stored in the domain policy */
-       if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
+       if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted,
                                     &disp_info))
                return NT_STATUS_INVALID_HANDLE;
 
@@ -3163,7 +3155,7 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
        info->acc_granted = acc_granted;
 
        /* get a (unique) handle.  open a policy on it. */
-       if (!create_policy_hnd(p, user_pol, info)) {
+       if (!create_policy_hnd(p, r->out.user_handle, info)) {
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
@@ -3451,9 +3443,7 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
                         struct samr_OpenAlias *r)
 {
        DOM_SID sid;
-       POLICY_HND domain_pol = *r->in.domain_handle;
        uint32 alias_rid = r->in.rid;
-       POLICY_HND *alias_pol = r->out.alias_handle;
        struct    samr_info *info = NULL;
        SEC_DESC *psd = NULL;
        uint32    acc_granted;
@@ -3464,7 +3454,7 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
 
        /* find the domain policy and get the SID / access bits stored in the domain policy */
 
-       if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
+       if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
                return NT_STATUS_INVALID_HANDLE;
 
        status = access_check_samr_function(acc_granted,
@@ -3525,7 +3515,7 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
        info->acc_granted = acc_granted;
 
        /* get a (unique) handle.  open a policy on it. */
-       if (!create_policy_hnd(p, alias_pol, info))
+       if (!create_policy_hnd(p, r->out.alias_handle, info))
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 
        return NT_STATUS_OK;
@@ -4000,7 +3990,6 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
        NTSTATUS status;
        struct samu *pwd = NULL;
        DOM_SID sid;
-       POLICY_HND *pol = r->in.user_handle;
        union samr_UserInfo *info = r->in.info;
        uint16_t switch_value = r->in.level;
        uint32_t acc_granted;
@@ -4013,7 +4002,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
        DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
 
        /* find the policy handle.  open a policy on it. */
-       if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) {
+       if (!get_lsa_policy_samr_sid(p, r->in.user_handle, &sid, &acc_granted, &disp_info)) {
                return NT_STATUS_INVALID_HANDLE;
        }
 
@@ -5632,7 +5621,8 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
        switch (r->in.level) {
        case 1:
                if (info->disp_info->users == NULL) {
-                       info->disp_info->users = pdb_search_users(ACB_NORMAL);
+                       info->disp_info->users = pdb_search_users(
+                               info->disp_info, ACB_NORMAL);
                        if (info->disp_info->users == NULL) {
                                unbecome_root();
                                return NT_STATUS_ACCESS_DENIED;
@@ -5651,8 +5641,8 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
                break;
        case 2:
                if (info->disp_info->machines == NULL) {
-                       info->disp_info->machines =
-                               pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
+                       info->disp_info->machines = pdb_search_users(
+                               info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
                        if (info->disp_info->machines == NULL) {
                                unbecome_root();
                                return NT_STATUS_ACCESS_DENIED;
@@ -5671,7 +5661,8 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
                break;
        case 3:
                if (info->disp_info->groups == NULL) {
-                       info->disp_info->groups = pdb_search_groups();
+                       info->disp_info->groups = pdb_search_groups(
+                               info->disp_info);
                        if (info->disp_info->groups == NULL) {
                                unbecome_root();
                                return NT_STATUS_ACCESS_DENIED;
diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c
deleted file mode 100644 (file)
index ee36f04..0000000
+++ /dev/null
@@ -1,912 +0,0 @@
-/* 
- *  Unix SMB/CIFS implementation.
- *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-2000,
- *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
- *  Copyright (C) Jean François Micouleau      1998-2000,
- *  Copyright (C) Jeremy Allison                    2001,
- *  Copyright (C) Gerald Carter                2001-2002,
- *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2003.
- *  
- *  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"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-/*******************************************************************
- ********************************************************************/
-
-static bool proxy_spoolss_call(pipes_struct *p, uint8_t opnum)
-{
-       struct api_struct *fns;
-       int n_fns;
-
-       spoolss_get_pipe_fns(&fns, &n_fns);
-
-       if (opnum >= n_fns) {
-               return false;
-       }
-
-       if (fns[opnum].opnum != opnum) {
-               smb_panic("SPOOLSS function table not sorted");
-       }
-
-       return fns[opnum].fn(p);
-}
-
-/********************************************************************
- * api_spoolss_open_printer_ex (rarely seen - older call)
- ********************************************************************/
-
-static bool api_spoolss_open_printer(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_OPENPRINTER);
-}
-
-/********************************************************************
- * api_spoolss_open_printer_ex
- ********************************************************************/
-
-static bool api_spoolss_open_printer_ex(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_OPENPRINTEREX);
-}
-
-/********************************************************************
- * api_spoolss_getprinterdata
- *
- * called from the spoolss dispatcher
- ********************************************************************/
-
-static bool api_spoolss_getprinterdata(pipes_struct *p)
-{
-       SPOOL_Q_GETPRINTERDATA q_u;
-       SPOOL_R_GETPRINTERDATA r_u;
-       prs_struct *data = &p->in_data.data;
-       prs_struct *rdata = &p->out_data.rdata;
-
-       ZERO_STRUCT(q_u);
-       ZERO_STRUCT(r_u);
-
-       /* read the stream and fill the struct */
-       if (!spoolss_io_q_getprinterdata("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_getprinterdata: unable to unmarshall SPOOL_Q_GETPRINTERDATA.\n"));
-               return False;
-       }
-       
-       r_u.status = _spoolss_getprinterdata( p, &q_u, &r_u);
-
-       if (!spoolss_io_r_getprinterdata("", &r_u, rdata, 0)) {
-               DEBUG(0,("spoolss_io_r_getprinterdata: unable to marshall SPOOL_R_GETPRINTERDATA.\n"));
-               return False;
-       }
-
-       return True;
-}
-
-/********************************************************************
- * api_spoolss_deleteprinterdata
- *
- * called from the spoolss dispatcher
- ********************************************************************/
-
-static bool api_spoolss_deleteprinterdata(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEPRINTERDATA);
-}
-
-/********************************************************************
- * api_spoolss_closeprinter
- *
- * called from the spoolss dispatcher
- ********************************************************************/
-
-static bool api_spoolss_closeprinter(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_CLOSEPRINTER);
-}
-
-/********************************************************************
- * api_spoolss_abortprinter
- *
- * called from the spoolss dispatcher
- ********************************************************************/
-
-static bool api_spoolss_abortprinter(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ABORTPRINTER);
-}
-
-/********************************************************************
- * api_spoolss_deleteprinter
- *
- * called from the spoolss dispatcher
- ********************************************************************/
-
-static bool api_spoolss_deleteprinter(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEPRINTER);
-}
-
-/********************************************************************
- * api_spoolss_deleteprinterdriver
- *
- * called from the spoolss dispatcher
- ********************************************************************/
-
-static bool api_spoolss_deleteprinterdriver(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEPRINTERDRIVER);
-}
-
-
-/********************************************************************
- * api_spoolss_rffpcnex
- * ReplyFindFirstPrinterChangeNotifyEx
- ********************************************************************/
-
-static bool api_spoolss_rffpcnex(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFYEX);
-}
-
-
-/********************************************************************
- * api_spoolss_rfnpcnex
- * ReplyFindNextPrinterChangeNotifyEx
- * called from the spoolss dispatcher
-
- * Note - this is the *ONLY* function that breaks the RPC call
- * symmetry in all the other calls. We need to do this to fix
- * the massive memory allocation problem with thousands of jobs...
- * JRA.
- ********************************************************************/
-
-static bool api_spoolss_rfnpcnex(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFY);
-}
-
-
-/********************************************************************
- * api_spoolss_enumprinters
- * called from the spoolss dispatcher
- *
- ********************************************************************/
-
-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;
-}
-
-/********************************************************************
- * api_spoolss_getprinter
- * called from the spoolss dispatcher
- *
- ********************************************************************/
-
-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;
-}
-
-/********************************************************************
- * api_spoolss_getprinter
- * called from the spoolss dispatcher
- *
- ********************************************************************/
-
-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;
-}
-
-/********************************************************************
- * api_spoolss_getprinter
- * called from the spoolss dispatcher
- *
- ********************************************************************/
-
-static bool api_spoolss_startpageprinter(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_STARTPAGEPRINTER);
-}
-
-/********************************************************************
- * api_spoolss_getprinter
- * called from the spoolss dispatcher
- *
- ********************************************************************/
-
-static bool api_spoolss_endpageprinter(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ENDPAGEPRINTER);
-}
-
-/********************************************************************
-********************************************************************/
-
-static bool api_spoolss_startdocprinter(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_STARTDOCPRINTER);
-}
-
-/********************************************************************
-********************************************************************/
-
-static bool api_spoolss_enddocprinter(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ENDDOCPRINTER);
-}
-
-/********************************************************************
-********************************************************************/
-
-static bool api_spoolss_writeprinter(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_WRITEPRINTER);
-}
-
-/****************************************************************************
-
-****************************************************************************/
-
-static bool api_spoolss_setprinter(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_SETPRINTER);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_fcpn(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_FINDCLOSEPRINTERNOTIFY);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_addjob(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ADDJOB);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-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;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_schedulejob(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_SCHEDULEJOB);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_setjob(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_SETJOB);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-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;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_getform(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_GETFORM);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_enumforms(pipes_struct *p)
-{
-       SPOOL_Q_ENUMFORMS q_u;
-       SPOOL_R_ENUMFORMS 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_enumforms("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_enumforms: unable to unmarshall SPOOL_Q_ENUMFORMS.\n"));
-               return False;
-       }
-
-       r_u.status = _spoolss_enumforms(p, &q_u, &r_u);
-
-       if (!spoolss_io_r_enumforms("",&r_u,rdata,0)) {
-               DEBUG(0,("spoolss_io_r_enumforms: unable to marshall SPOOL_R_ENUMFORMS.\n"));
-               return False;
-       }
-
-       return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_enumports(pipes_struct *p)
-{
-       SPOOL_Q_ENUMPORTS q_u;
-       SPOOL_R_ENUMPORTS 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_enumports("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_enumports: unable to unmarshall SPOOL_Q_ENUMPORTS.\n"));
-               return False;
-       }
-
-       r_u.status = _spoolss_enumports(p, &q_u, &r_u);
-
-       if (!spoolss_io_r_enumports("",&r_u,rdata,0)) {
-               DEBUG(0,("spoolss_io_r_enumports: unable to marshall SPOOL_R_ENUMPORTS.\n"));
-               return False;
-       }
-
-       return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_addprinterex(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ADDPRINTEREX);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_addprinterdriver(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ADDPRINTERDRIVER);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_getprinterdriverdirectory(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_GETPRINTERDRIVERDIRECTORY);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_enumprinterdata(pipes_struct *p)
-{
-       SPOOL_Q_ENUMPRINTERDATA q_u;
-       SPOOL_R_ENUMPRINTERDATA 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_enumprinterdata("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_enumprinterdata: unable to unmarshall SPOOL_Q_ENUMPRINTERDATA.\n"));
-               return False;
-       }
-       
-       r_u.status = _spoolss_enumprinterdata(p, &q_u, &r_u);
-                               
-       if(!spoolss_io_r_enumprinterdata("", &r_u, rdata, 0)) {
-               DEBUG(0,("spoolss_io_r_enumprinterdata: unable to marshall SPOOL_R_ENUMPRINTERDATA.\n"));
-               return False;
-       }
-
-       return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_setprinterdata(pipes_struct *p)
-{
-       SPOOL_Q_SETPRINTERDATA q_u;
-       SPOOL_R_SETPRINTERDATA 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_setprinterdata("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_setprinterdata: unable to unmarshall SPOOL_Q_SETPRINTERDATA.\n"));
-               return False;
-       }
-       
-       r_u.status = _spoolss_setprinterdata(p, &q_u, &r_u);
-                               
-       if(!spoolss_io_r_setprinterdata("", &r_u, rdata, 0)) {
-               DEBUG(0,("spoolss_io_r_setprinterdata: unable to marshall SPOOL_R_SETPRINTERDATA.\n"));
-               return False;
-       }
-
-       return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-static bool api_spoolss_reset_printer(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_RESETPRINTER);
-}
-
-/****************************************************************************
-****************************************************************************/
-static bool api_spoolss_addform(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ADDFORM);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_deleteform(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEFORM);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_setform(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_SETFORM);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_enumprintprocessors(pipes_struct *p)
-{
-       SPOOL_Q_ENUMPRINTPROCESSORS q_u;
-       SPOOL_R_ENUMPRINTPROCESSORS 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_enumprintprocessors("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_enumprintprocessors: unable to unmarshall SPOOL_Q_ENUMPRINTPROCESSORS.\n"));
-               return False;
-       }
-       
-       r_u.status = _spoolss_enumprintprocessors(p, &q_u, &r_u);
-
-       if(!spoolss_io_r_enumprintprocessors("", &r_u, rdata, 0)) {
-               DEBUG(0,("spoolss_io_r_enumprintprocessors: unable to marshall SPOOL_R_ENUMPRINTPROCESSORS.\n"));
-               return False;
-       }
-       
-       return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_addprintprocessor(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ADDPRINTPROCESSOR);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_enumprintprocdatatypes(pipes_struct *p)
-{
-       SPOOL_Q_ENUMPRINTPROCDATATYPES q_u;
-       SPOOL_R_ENUMPRINTPROCDATATYPES 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_enumprintprocdatatypes("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_enumprintprocdatatypes: unable to unmarshall SPOOL_Q_ENUMPRINTPROCDATATYPES.\n"));
-               return False;
-       }
-       
-       r_u.status = _spoolss_enumprintprocdatatypes(p, &q_u, &r_u);
-
-       if(!spoolss_io_r_enumprintprocdatatypes("", &r_u, rdata, 0)) {
-               DEBUG(0,("spoolss_io_r_enumprintprocdatatypes: unable to marshall SPOOL_R_ENUMPRINTPROCDATATYPES.\n"));
-               return False;
-       }
-       
-       return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_enumprintmonitors(pipes_struct *p)
-{
-       SPOOL_Q_ENUMPRINTMONITORS q_u;
-       SPOOL_R_ENUMPRINTMONITORS 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_enumprintmonitors("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_enumprintmonitors: unable to unmarshall SPOOL_Q_ENUMPRINTMONITORS.\n"));
-               return False;
-       }
-               
-       r_u.status = _spoolss_enumprintmonitors(p, &q_u, &r_u);
-
-       if (!spoolss_io_r_enumprintmonitors("", &r_u, rdata, 0)) {
-               DEBUG(0,("spoolss_io_r_enumprintmonitors: unable to marshall SPOOL_R_ENUMPRINTMONITORS.\n"));
-               return False;
-       }
-       
-       return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-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;
-}
-
-/********************************************************************
- * api_spoolss_getprinterdataex
- *
- * called from the spoolss dispatcher
- ********************************************************************/
-
-static bool api_spoolss_getprinterdataex(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_GETPRINTERDATAEX);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_setprinterdataex(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_SETPRINTERDATAEX);
-}
-
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_enumprinterkey(pipes_struct *p)
-{
-       SPOOL_Q_ENUMPRINTERKEY q_u;
-       SPOOL_R_ENUMPRINTERKEY 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_enumprinterkey("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_setprinterkey: unable to unmarshall SPOOL_Q_ENUMPRINTERKEY.\n"));
-               return False;
-       }
-       
-       r_u.status = _spoolss_enumprinterkey(p, &q_u, &r_u);
-                               
-       if(!spoolss_io_r_enumprinterkey("", &r_u, rdata, 0)) {
-               DEBUG(0,("spoolss_io_r_enumprinterkey: unable to marshall SPOOL_R_ENUMPRINTERKEY.\n"));
-               return False;
-       }
-
-       return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_enumprinterdataex(pipes_struct *p)
-{
-       SPOOL_Q_ENUMPRINTERDATAEX q_u;
-       SPOOL_R_ENUMPRINTERDATAEX 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_enumprinterdataex("", &q_u, data, 0)) {
-               DEBUG(0,("spoolss_io_q_enumprinterdataex: unable to unmarshall SPOOL_Q_ENUMPRINTERDATAEX.\n"));
-               return False;
-       }
-       
-       r_u.status = _spoolss_enumprinterdataex(p, &q_u, &r_u);
-                               
-       if(!spoolss_io_r_enumprinterdataex("", &r_u, rdata, 0)) {
-               DEBUG(0,("spoolss_io_r_enumprinterdataex: unable to marshall SPOOL_R_ENUMPRINTERDATAEX.\n"));
-               return False;
-       }
-
-       return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_getprintprocessordirectory(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_GETPRINTPROCESSORDIRECTORY);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_deleteprinterdataex(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEPRINTERDATAEX);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_deleteprinterkey(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEPRINTERKEY);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_addprinterdriverex(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ADDPRINTERDRIVEREX);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_deleteprinterdriverex(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_DELETEPRINTERDRIVEREX);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_xcvdataport(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_XCVDATA);
-}
-
-/*******************************************************************
-\pipe\spoolss commands
-********************************************************************/
-
-  struct api_struct api_spoolss_cmds[] = 
-    {
- {"SPOOLSS_OPENPRINTER",               SPOOLSS_OPENPRINTER,               api_spoolss_open_printer              },
- {"SPOOLSS_OPENPRINTEREX",             SPOOLSS_OPENPRINTEREX,             api_spoolss_open_printer_ex           },
- {"SPOOLSS_GETPRINTERDATA",            SPOOLSS_GETPRINTERDATA,            api_spoolss_getprinterdata            },
- {"SPOOLSS_CLOSEPRINTER",              SPOOLSS_CLOSEPRINTER,              api_spoolss_closeprinter              },
- {"SPOOLSS_DELETEPRINTER",             SPOOLSS_DELETEPRINTER,             api_spoolss_deleteprinter             },
- {"SPOOLSS_ABORTPRINTER",              SPOOLSS_ABORTPRINTER,              api_spoolss_abortprinter              },
- {"SPOOLSS_RFFPCNEX",                  SPOOLSS_RFFPCNEX,                  api_spoolss_rffpcnex                  },
- {"SPOOLSS_RFNPCNEX",                  SPOOLSS_RFNPCNEX,                  api_spoolss_rfnpcnex                  },
- {"SPOOLSS_ENUMPRINTERS",              SPOOLSS_ENUMPRINTERS,              api_spoolss_enumprinters              },
- {"SPOOLSS_GETPRINTER",                SPOOLSS_GETPRINTER,                api_spoolss_getprinter                },
- {"SPOOLSS_GETPRINTERDRIVER2",         SPOOLSS_GETPRINTERDRIVER2,         api_spoolss_getprinterdriver2         }, 
- {"SPOOLSS_STARTPAGEPRINTER",          SPOOLSS_STARTPAGEPRINTER,          api_spoolss_startpageprinter          },
- {"SPOOLSS_ENDPAGEPRINTER",            SPOOLSS_ENDPAGEPRINTER,            api_spoolss_endpageprinter            }, 
- {"SPOOLSS_STARTDOCPRINTER",           SPOOLSS_STARTDOCPRINTER,           api_spoolss_startdocprinter           },
- {"SPOOLSS_ENDDOCPRINTER",             SPOOLSS_ENDDOCPRINTER,             api_spoolss_enddocprinter             },
- {"SPOOLSS_WRITEPRINTER",              SPOOLSS_WRITEPRINTER,              api_spoolss_writeprinter              },
- {"SPOOLSS_SETPRINTER",                SPOOLSS_SETPRINTER,                api_spoolss_setprinter                },
- {"SPOOLSS_FCPN",                      SPOOLSS_FCPN,                      api_spoolss_fcpn                     },
- {"SPOOLSS_ADDJOB",                    SPOOLSS_ADDJOB,                    api_spoolss_addjob                    },
- {"SPOOLSS_ENUMJOBS",                  SPOOLSS_ENUMJOBS,                  api_spoolss_enumjobs                  },
- {"SPOOLSS_SCHEDULEJOB",               SPOOLSS_SCHEDULEJOB,               api_spoolss_schedulejob               },
- {"SPOOLSS_SETJOB",                    SPOOLSS_SETJOB,                    api_spoolss_setjob                    },
- {"SPOOLSS_ENUMFORMS",                 SPOOLSS_ENUMFORMS,                 api_spoolss_enumforms                 },
- {"SPOOLSS_ENUMPORTS",                 SPOOLSS_ENUMPORTS,                 api_spoolss_enumports                 },
- {"SPOOLSS_ENUMPRINTERDRIVERS",        SPOOLSS_ENUMPRINTERDRIVERS,        api_spoolss_enumprinterdrivers        },
- {"SPOOLSS_ADDPRINTEREX",              SPOOLSS_ADDPRINTEREX,              api_spoolss_addprinterex              },
- {"SPOOLSS_ADDPRINTERDRIVER",          SPOOLSS_ADDPRINTERDRIVER,          api_spoolss_addprinterdriver          },
- {"SPOOLSS_DELETEPRINTERDRIVER",       SPOOLSS_DELETEPRINTERDRIVER,       api_spoolss_deleteprinterdriver       },
- {"SPOOLSS_GETPRINTERDRIVERDIRECTORY", SPOOLSS_GETPRINTERDRIVERDIRECTORY, api_spoolss_getprinterdriverdirectory },
- {"SPOOLSS_ENUMPRINTERDATA",           SPOOLSS_ENUMPRINTERDATA,           api_spoolss_enumprinterdata           },
- {"SPOOLSS_SETPRINTERDATA",            SPOOLSS_SETPRINTERDATA,            api_spoolss_setprinterdata            },
- {"SPOOLSS_RESETPRINTER",              SPOOLSS_RESETPRINTER,              api_spoolss_reset_printer             },
- {"SPOOLSS_DELETEPRINTERDATA",         SPOOLSS_DELETEPRINTERDATA,         api_spoolss_deleteprinterdata         },
- {"SPOOLSS_ADDFORM",                   SPOOLSS_ADDFORM,                   api_spoolss_addform                   },
- {"SPOOLSS_DELETEFORM",                SPOOLSS_DELETEFORM,                api_spoolss_deleteform                },
- {"SPOOLSS_GETFORM",                   SPOOLSS_GETFORM,                   api_spoolss_getform                   },
- {"SPOOLSS_SETFORM",                   SPOOLSS_SETFORM,                   api_spoolss_setform                   },
- {"SPOOLSS_ADDPRINTPROCESSOR",         SPOOLSS_ADDPRINTPROCESSOR,         api_spoolss_addprintprocessor         },
- {"SPOOLSS_ENUMPRINTPROCESSORS",       SPOOLSS_ENUMPRINTPROCESSORS,       api_spoolss_enumprintprocessors       },
- {"SPOOLSS_ENUMMONITORS",              SPOOLSS_ENUMMONITORS,              api_spoolss_enumprintmonitors         },
- {"SPOOLSS_GETJOB",                    SPOOLSS_GETJOB,                    api_spoolss_getjob                    },
- {"SPOOLSS_ENUMPRINTPROCDATATYPES",    SPOOLSS_ENUMPRINTPROCDATATYPES,    api_spoolss_enumprintprocdatatypes    },
- {"SPOOLSS_GETPRINTERDATAEX",          SPOOLSS_GETPRINTERDATAEX,          api_spoolss_getprinterdataex          },
- {"SPOOLSS_SETPRINTERDATAEX",          SPOOLSS_SETPRINTERDATAEX,          api_spoolss_setprinterdataex          },
- {"SPOOLSS_DELETEPRINTERDATAEX",       SPOOLSS_DELETEPRINTERDATAEX,       api_spoolss_deleteprinterdataex       },
- {"SPOOLSS_ENUMPRINTERDATAEX",         SPOOLSS_ENUMPRINTERDATAEX,         api_spoolss_enumprinterdataex         },
- {"SPOOLSS_ENUMPRINTERKEY",            SPOOLSS_ENUMPRINTERKEY,            api_spoolss_enumprinterkey            },
- {"SPOOLSS_DELETEPRINTERKEY",          SPOOLSS_DELETEPRINTERKEY,          api_spoolss_deleteprinterkey          },
- {"SPOOLSS_GETPRINTPROCESSORDIRECTORY",SPOOLSS_GETPRINTPROCESSORDIRECTORY,api_spoolss_getprintprocessordirectory},
- {"SPOOLSS_ADDPRINTERDRIVEREX",        SPOOLSS_ADDPRINTERDRIVEREX,        api_spoolss_addprinterdriverex        },
- {"SPOOLSS_DELETEPRINTERDRIVEREX",     SPOOLSS_DELETEPRINTERDRIVEREX,     api_spoolss_deleteprinterdriverex     },
- {"SPOOLSS_XCVDATAPORT",               SPOOLSS_XCVDATAPORT,               api_spoolss_xcvdataport               },
-};
-
-void spoolss2_get_pipe_fns( struct api_struct **fns, int *n_fns )
-{
-       *fns = api_spoolss_cmds;
-       *n_fns = sizeof(api_spoolss_cmds) / sizeof(struct api_struct);
-}
-
-NTSTATUS rpc_spoolss2_init(void)
-{
-       return rpc_srv_register(
-               SMB_RPC_INTERFACE_VERSION, "spoolss", "spoolss",
-               &ndr_table_spoolss,
-               api_spoolss_cmds,
-               sizeof(api_spoolss_cmds) / sizeof(struct api_struct));
-}
index 814f406e8702948eb6302bb48aeae24806278a33..ab15e5c5f619e25aef2caeec6245f8db466392fb 100644 (file)
@@ -7,6 +7,7 @@
  *  Copyright (C) Jeremy Allison               2001-2002,
  *  Copyright (C) Gerald Carter                       2000-2004,
  *  Copyright (C) Tim Potter                   2001-2002.
+ *  Copyright (C) Guenther Deschner                 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
 
 #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_ARRAY(mem_ctx,fn,ic,info,count) \
+       ((info)?ndr_size_##fn##_info(mem_ctx, ic, 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
@@ -134,7 +148,7 @@ static int nt_printq_status(int v)
  Disconnect from the client
 ****************************************************************************/
 
-static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
+static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
 {
        WERROR result;
        NTSTATUS status;
@@ -217,7 +231,8 @@ static int printer_entry_destructor(Printer_entry *Printer)
   find printer index by handle
 ****************************************************************************/
 
-static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
+static Printer_entry *find_printer_index_by_hnd(pipes_struct *p,
+                                               struct policy_handle *hnd)
 {
        Printer_entry *find_printer = NULL;
 
@@ -233,12 +248,13 @@ static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd
  Close printer index by handle.
 ****************************************************************************/
 
-static bool close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
+static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
 
        if (!Printer) {
-               DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
+               DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
+                       OUR_HANDLE(hnd)));
                return False;
        }
 
@@ -311,12 +327,13 @@ WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sh
  Delete a printer given a handle.
 ****************************************************************************/
 
-static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
+static WERROR delete_printer_handle(pipes_struct *p, struct policy_handle *hnd)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
 
        if (!Printer) {
-               DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
+               DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
+                       OUR_HANDLE(hnd)));
                return WERR_BADFID;
        }
 
@@ -348,13 +365,14 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
  Return the snum of a printer corresponding to an handle.
 ****************************************************************************/
 
-static bool get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number,
-                            struct share_params **params)
+static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd,
+                            int *number, struct share_params **params)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
 
        if (!Printer) {
-               DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
+               DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
+                       OUR_HANDLE(hnd)));
                return False;
        }
 
@@ -537,7 +555,8 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
  Find first available printer slot. creates a printer handle for you.
  ****************************************************************************/
 
-static bool open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint32 access_granted)
+static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd,
+                            char *name, uint32_t access_granted)
 {
        Printer_entry *new_printer;
 
@@ -618,7 +637,7 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type,
                /* Check match for field */
 
                for (j = 0; j < option->types[i].count; j++) {
-                       if (option->types[i].fields[j] == notify_field) {
+                       if (option->types[i].fields[j].field == notify_field) {
                                return True;
                        }
                }
@@ -736,52 +755,52 @@ struct notify2_message_table {
 };
 
 static struct notify2_message_table printer_notify_table[] = {
-       /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string },
-       /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string },
-       /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string },
-       /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string },
-       /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string },
-       /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string },
-       /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string },
-       /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL },
-       /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string },
-       /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string },
-       /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL },
-       /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string },
-       /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL },
-       /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value },
-       /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value },
-       /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL },
-       /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL },
-       /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL },
-       /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value },
+       /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
+       /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
+       /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
+       /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
+       /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
+       /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
+       /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
+       /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
+       /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
+       /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
+       /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
+       /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
+       /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
+       /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
+       /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
+       /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
+       /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
+       /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
+       /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
 };
 
 static struct notify2_message_table job_notify_table[] = {
-       /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL },
-       /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL },
-       /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL },
-       /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string },
-       /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL },
-       /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL },
-       /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL },
-       /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL },
-       /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL },
-       /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL },
-       /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value },
-       /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL },
-       /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL },
-       /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string },
-       /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL },
-       /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL },
-       /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time },
-       /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL },
-       /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL },
-       /* 0x13 */ { "JOB_NOTIFY_TIME", NULL },
-       /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value },
-       /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL },
-       /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value },
-       /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL },
+       /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
+       /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
+       /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
+       /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
+       /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
+       /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
+       /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
+       /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
+       /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
+       /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
+       /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
+       /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
+       /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
+       /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
+       /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
+       /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
+       /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
+       /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
+       /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
+       /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
+       /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
+       /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
+       /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
+       /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
 };
 
 
@@ -1445,12 +1464,11 @@ WERROR _spoolss_OpenPrinter(pipes_struct *p,
 }
 
 /********************************************************************
- FIXME: temporary convert_devicemode_new function
  ********************************************************************/
 
-static bool convert_devicemode_new(const char *printername,
-                                  struct spoolss_DeviceMode *devmode,
-                                  NT_DEVICEMODE **pp_nt_devmode)
+bool convert_devicemode(const char *printername,
+                       const struct spoolss_DeviceMode *devmode,
+                       NT_DEVICEMODE **pp_nt_devmode)
 {
        NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
 
@@ -1460,7 +1478,7 @@ static bool convert_devicemode_new(const char *printername,
         */
 
        if (nt_devmode == NULL) {
-               DEBUG(5, ("convert_devicemode_new: allocating a generic devmode\n"));
+               DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
                if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
                        return false;
        }
@@ -1526,7 +1544,6 @@ static bool convert_devicemode_new(const char *printername,
 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
                              struct spoolss_OpenPrinterEx *r)
 {
-       POLICY_HND              *handle = r->out.handle;
        char *name = CONST_DISCARD(char *, r->in.printername);
        int snum;
        Printer_entry *Printer=NULL;
@@ -1540,16 +1557,16 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
 
        DEBUGADD(3,("checking name: %s\n",name));
 
-       if (!open_printer_hnd(p, handle, name, 0)) {
+       if (!open_printer_hnd(p, r->out.handle, name, 0)) {
                ZERO_STRUCTP(r->out.handle);
                return WERR_INVALID_PARAM;
        }
 
-       Printer=find_printer_index_by_hnd(p, handle);
+       Printer = find_printer_index_by_hnd(p, r->out.handle);
        if ( !Printer ) {
                DEBUG(0,("_spoolss_OpenPrinterEx: logic error.  Can't find printer "
                        "handle we created for printer %s\n", name ));
-               close_printer_handle(p,handle);
+               close_printer_handle(p, r->out.handle);
                ZERO_STRUCTP(r->out.handle);
                return WERR_INVALID_PARAM;
        }
@@ -1600,7 +1617,7 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
                if (r->in.access_mask &
                    ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
                        DEBUG(3, ("access DENIED for non-printserver bits\n"));
-                       close_printer_handle(p, handle);
+                       close_printer_handle(p, r->out.handle);
                        ZERO_STRUCTP(r->out.handle);
                        return WERR_ACCESS_DENIED;
                }
@@ -1612,7 +1629,7 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
                        SE_PRIV se_printop = SE_PRINT_OPERATOR;
 
                        if (!lp_ms_add_printer_wizard()) {
-                               close_printer_handle(p, handle);
+                               close_printer_handle(p, r->out.handle);
                                ZERO_STRUCTP(r->out.handle);
                                return WERR_ACCESS_DENIED;
                        }
@@ -1628,7 +1645,7 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
                                    NULL, NULL,
                                    p->server_info->ptok,
                                    lp_printer_admin(snum))) {
-                               close_printer_handle(p, handle);
+                               close_printer_handle(p, r->out.handle);
                                ZERO_STRUCTP(r->out.handle);
                                return WERR_ACCESS_DENIED;
                        }
@@ -1650,8 +1667,8 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
                /* NT doesn't let us connect to a printer if the connecting user
                   doesn't have print permission.  */
 
-               if (!get_printer_snum(p, handle, &snum, NULL)) {
-                       close_printer_handle(p, handle);
+               if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
+                       close_printer_handle(p, r->out.handle);
                        ZERO_STRUCTP(r->out.handle);
                        return WERR_BADFID;
                }
@@ -1687,14 +1704,14 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
                    !print_access_check(p->server_info, snum,
                                        r->in.access_mask)) {
                        DEBUG(3, ("access DENIED for printer open\n"));
-                       close_printer_handle(p, handle);
+                       close_printer_handle(p, r->out.handle);
                        ZERO_STRUCTP(r->out.handle);
                        return WERR_ACCESS_DENIED;
                }
 
                if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
                        DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
-                       close_printer_handle(p, handle);
+                       close_printer_handle(p, r->out.handle);
                        ZERO_STRUCTP(r->out.handle);
                        return WERR_ACCESS_DENIED;
                }
@@ -1722,12 +1739,11 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
         * save it here in case we get a job submission on this handle
         */
 
-        if ( (Printer->printer_type != SPLHND_SERVER)
-               && r->in.devmode_ctr.devmode )
-        {
-               convert_devicemode_new(Printer->sharename,
-                                      r->in.devmode_ctr.devmode,
-                                      &Printer->nt_devmode);
+        if ((Printer->printer_type != SPLHND_SERVER) &&
+            r->in.devmode_ctr.devmode) {
+               convert_devicemode(Printer->sharename,
+                                  r->in.devmode_ctr.devmode,
+                                  &Printer->nt_devmode);
         }
 
 #if 0  /* JERRY -- I'm doubtful this is really effective */
@@ -1783,8 +1799,8 @@ static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
 /****************************************************************************
 ****************************************************************************/
 
-static bool convert_printer_info_new(struct spoolss_SetPrinterInfoCtr *info_ctr,
-                                    NT_PRINTER_INFO_LEVEL *printer)
+static bool convert_printer_info(struct spoolss_SetPrinterInfoCtr *info_ctr,
+                                NT_PRINTER_INFO_LEVEL *printer)
 {
        bool ret;
 
@@ -1797,7 +1813,7 @@ static bool convert_printer_info_new(struct spoolss_SetPrinterInfoCtr *info_ctr,
                if (!printer->info_2) {
                        printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
                        if (!printer->info_2) {
-                               DEBUG(0,("convert_printer_info_new: "
+                               DEBUG(0,("convert_printer_info: "
                                        "talloc() failed!\n"));
                                return false;
                        }
@@ -1983,83 +1999,14 @@ static bool convert_printer_driver_info(const struct spoolss_AddDriverInfoCtr *r
        return true;
 }
 
-bool convert_devicemode(const char *printername, const DEVICEMODE *devmode,
-                               NT_DEVICEMODE **pp_nt_devmode)
-{
-       NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
-
-       /*
-        * Ensure nt_devmode is a valid pointer
-        * as we will be overwriting it.
-        */
-
-       if (nt_devmode == NULL) {
-               DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
-               if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
-                       return False;
-       }
-
-       rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
-       rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
-
-       nt_devmode->specversion=devmode->specversion;
-       nt_devmode->driverversion=devmode->driverversion;
-       nt_devmode->size=devmode->size;
-       nt_devmode->fields=devmode->fields;
-       nt_devmode->orientation=devmode->orientation;
-       nt_devmode->papersize=devmode->papersize;
-       nt_devmode->paperlength=devmode->paperlength;
-       nt_devmode->paperwidth=devmode->paperwidth;
-       nt_devmode->scale=devmode->scale;
-       nt_devmode->copies=devmode->copies;
-       nt_devmode->defaultsource=devmode->defaultsource;
-       nt_devmode->printquality=devmode->printquality;
-       nt_devmode->color=devmode->color;
-       nt_devmode->duplex=devmode->duplex;
-       nt_devmode->yresolution=devmode->yresolution;
-       nt_devmode->ttoption=devmode->ttoption;
-       nt_devmode->collate=devmode->collate;
-
-       nt_devmode->logpixels=devmode->logpixels;
-       nt_devmode->bitsperpel=devmode->bitsperpel;
-       nt_devmode->pelswidth=devmode->pelswidth;
-       nt_devmode->pelsheight=devmode->pelsheight;
-       nt_devmode->displayflags=devmode->displayflags;
-       nt_devmode->displayfrequency=devmode->displayfrequency;
-       nt_devmode->icmmethod=devmode->icmmethod;
-       nt_devmode->icmintent=devmode->icmintent;
-       nt_devmode->mediatype=devmode->mediatype;
-       nt_devmode->dithertype=devmode->dithertype;
-       nt_devmode->reserved1=devmode->reserved1;
-       nt_devmode->reserved2=devmode->reserved2;
-       nt_devmode->panningwidth=devmode->panningwidth;
-       nt_devmode->panningheight=devmode->panningheight;
-
-       /*
-        * Only change private and driverextra if the incoming devmode
-        * has a new one. JRA.
-        */
-
-       if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) {
-               SAFE_FREE(nt_devmode->nt_dev_private);
-               nt_devmode->driverextra=devmode->driverextra;
-               if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
-                       return False;
-               memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra);
-       }
-
-       *pp_nt_devmode = nt_devmode;
-
-       return True;
-}
-
 /********************************************************************
  * _spoolss_enddocprinter_internal.
  ********************************************************************/
 
-static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
+static WERROR _spoolss_enddocprinter_internal(pipes_struct *p,
+                                             struct policy_handle *handle)
 {
-       Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
        int snum;
 
        if (!Printer) {
@@ -2084,14 +2031,12 @@ static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handl
 WERROR _spoolss_ClosePrinter(pipes_struct *p,
                             struct spoolss_ClosePrinter *r)
 {
-       POLICY_HND *handle = r->in.handle;
-
-       Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
        if (Printer && Printer->document_started)
-               _spoolss_enddocprinter_internal(p, handle);          /* print job was not closed */
+               _spoolss_enddocprinter_internal(p, r->in.handle);          /* print job was not closed */
 
-       if (!close_printer_handle(p, handle))
+       if (!close_printer_handle(p, r->in.handle))
                return WERR_BADFID;
 
        /* clear the returned printer handle.  Observed behavior
@@ -2111,14 +2056,13 @@ WERROR _spoolss_ClosePrinter(pipes_struct *p,
 WERROR _spoolss_DeletePrinter(pipes_struct *p,
                              struct spoolss_DeletePrinter *r)
 {
-       POLICY_HND *handle = r->in.handle;
-       Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
        WERROR result;
 
        if (Printer && Printer->document_started)
-               _spoolss_enddocprinter_internal(p, handle);  /* print job was not closed */
+               _spoolss_enddocprinter_internal(p, r->in.handle);  /* print job was not closed */
 
-       result = delete_printer_handle(p, handle);
+       result = delete_printer_handle(p, r->in.handle);
 
        update_c_setprinter(False);
 
@@ -2384,52 +2328,6 @@ done:
 }
 
 
-/****************************************************************************
- Internal routine for retreiving printerdata
- ***************************************************************************/
-
-static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer,
-                                  const char *key, const char *value, uint32 *type, uint8 **data,
-                                 uint32 *needed, uint32 in_size  )
-{
-       REGISTRY_VALUE          *val;
-       uint32                  size;
-       int                     data_len;
-
-       if ( !(val = get_printer_data( printer->info_2, key, value)) )
-               return WERR_BADFILE;
-
-       *type = regval_type( val );
-
-       DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
-
-       size = regval_size( val );
-
-       /* copy the min(in_size, len) */
-
-       if ( in_size ) {
-               data_len = (size > in_size) ? in_size : size*sizeof(uint8);
-
-               /* special case for 0 length values */
-               if ( data_len ) {
-                       if ( (*data  = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
-                               return WERR_NOMEM;
-               }
-               else {
-                       if ( (*data  = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
-                               return WERR_NOMEM;
-               }
-       }
-       else
-               *data = NULL;
-
-       *needed = size;
-
-       DEBUG(5,("get_printer_dataex: copy done\n"));
-
-       return WERR_OK;
-}
-
 /****************************************************************************
  Internal routine for removing printerdata
  ***************************************************************************/
@@ -2455,74 +2353,58 @@ WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, cons
  GetPrinterData on a printer server Handle.
 ********************************************************************/
 
-static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
+static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
+                                           const char *value,
+                                           enum winreg_Type *type,
+                                           union spoolss_PrinterData *data)
 {
-       int i;
-
        DEBUG(8,("getprinterdata_printer_server:%s\n", value));
 
        if (!StrCaseCmp(value, "W3SvcInstalled")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
-               SIVAL(*data, 0, 0x00);
-               *needed = 0x4;
+               data->value = 0x00;
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "BeepEnabled")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
-               SIVAL(*data, 0, 0x00);
-               *needed = 0x4;
+               data->value = 0x00;
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "EventLog")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
                /* formally was 0x1b */
-               SIVAL(*data, 0, 0x0);
-               *needed = 0x4;
+               data->value = 0x00;
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "NetPopup")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
-               SIVAL(*data, 0, 0x00);
-               *needed = 0x4;
+               data->value = 0x00;
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "MajorVersion")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
 
                /* Windows NT 4.0 seems to not allow uploading of drivers
                   to a server that reports 0x3 as the MajorVersion.
                   need to investigate more how Win2k gets around this .
                   -- jerry */
 
-               if ( RA_WINNT == get_remote_arch() )
-                       SIVAL(*data, 0, 2);
-               else
-                       SIVAL(*data, 0, 3);
+               if (RA_WINNT == get_remote_arch()) {
+                       data->value = 0x02;
+               } else {
+                       data->value = 0x03;
+               }
 
-               *needed = 0x4;
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "MinorVersion")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
-               SIVAL(*data, 0, 0);
-               *needed = 0x4;
+               data->value = 0x00;
                return WERR_OK;
        }
 
@@ -2534,109 +2416,88 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
         *  extra unicode string = e.g. "Service Pack 3"
         */
        if (!StrCaseCmp(value, "OSVersion")) {
-               *type = REG_BINARY;
-               *needed = 0x114;
-
-               if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
-                       return WERR_NOMEM;
-
-               SIVAL(*data, 0, *needed);       /* size */
-               SIVAL(*data, 4, 5);             /* Windows 2000 == 5.0 */
-               SIVAL(*data, 8, 0);
-               SIVAL(*data, 12, 2195);         /* build */
+               DATA_BLOB blob;
+               enum ndr_err_code ndr_err;
+               struct spoolss_OSVersion os;
+
+               os.major                = 5;    /* Windows 2000 == 5.0 */
+               os.minor                = 0;
+               os.build                = 2195; /* build */
+               os.extra_string         = "";   /* leave extra string empty */
+
+               ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &os,
+                       (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       return WERR_GENERAL_FAILURE;
+               }
 
-               /* leave extra string empty */
+               *type = REG_BINARY;
+               data->binary = blob;
 
                return WERR_OK;
        }
 
 
        if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
-               const char *string="C:\\PRINTERS";
                *type = REG_SZ;
-               *needed = 2*(strlen(string)+1);
-               if((*data  = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
-                       return WERR_NOMEM;
-               memset(*data, 0, (*needed > in_size) ? *needed:in_size);
 
-               /* it's done by hand ready to go on the wire */
-               for (i=0; i<strlen(string); i++) {
-                       (*data)[2*i]=string[i];
-                       (*data)[2*i+1]='\0';
-               }
+               data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
+               W_ERROR_HAVE_NO_MEMORY(data->string);
+
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "Architecture")) {
-               const char *string="Windows NT x86";
                *type = REG_SZ;
-               *needed = 2*(strlen(string)+1);
-               if((*data  = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
-                       return WERR_NOMEM;
-               memset(*data, 0, (*needed > in_size) ? *needed:in_size);
-               for (i=0; i<strlen(string); i++) {
-                       (*data)[2*i]=string[i];
-                       (*data)[2*i+1]='\0';
-               }
+
+               data->string = talloc_strdup(mem_ctx, "Windows NT x86");
+               W_ERROR_HAVE_NO_MEMORY(data->string);
+
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "DsPresent")) {
                *type = REG_DWORD;
-               if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
-                       return WERR_NOMEM;
 
                /* only show the publish check box if we are a
-                  memeber of a AD domain */
-
-               if ( lp_security() == SEC_ADS )
-                       SIVAL(*data, 0, 0x01);
-               else
-                       SIVAL(*data, 0, 0x00);
+                  member of a AD domain */
 
-               *needed = 0x4;
+               if (lp_security() == SEC_ADS) {
+                       data->value = 0x01;
+               } else {
+                       data->value = 0x00;
+               }
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "DNSMachineName")) {
                const char *hostname = get_mydnsfullname();
 
-               if (!hostname)
+               if (!hostname) {
                        return WERR_BADFILE;
-               *type = REG_SZ;
-               *needed = 2*(strlen(hostname)+1);
-               if((*data  = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
-                       return WERR_NOMEM;
-               memset(*data, 0, (*needed > in_size) ? *needed:in_size);
-               for (i=0; i<strlen(hostname); i++) {
-                       (*data)[2*i]=hostname[i];
-                       (*data)[2*i+1]='\0';
                }
+
+               *type = REG_SZ;
+               data->string = talloc_strdup(mem_ctx, hostname);
+               W_ERROR_HAVE_NO_MEMORY(data->string);
+
                return WERR_OK;
        }
 
-
-       return WERR_BADFILE;
+       return WERR_INVALID_PARAM;
 }
 
-/********************************************************************
* spoolss_getprinterdata
- ********************************************************************/
+/****************************************************************
_spoolss_GetPrinterData
+****************************************************************/
 
-WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
-{
-       POLICY_HND      *handle = &q_u->handle;
-       UNISTR2         *valuename = &q_u->valuename;
-       uint32          in_size = q_u->size;
-       uint32          *type = &r_u->type;
-       uint32          *out_size = &r_u->size;
-       uint8           **data = &r_u->data;
-       uint32          *needed = &r_u->needed;
-       WERROR          status;
-       fstring         value;
-       Printer_entry   *Printer = find_printer_index_by_hnd(p, handle);
-       NT_PRINTER_INFO_LEVEL   *printer = NULL;
-       int             snum = 0;
+WERROR _spoolss_GetPrinterData(pipes_struct *p,
+                              struct spoolss_GetPrinterData *r)
+{
+       WERROR result;
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
+       NT_PRINTER_INFO_LEVEL *printer = NULL;
+       int snum = 0;
 
        /*
         * Reminder: when it's a string, the length is in BYTES
@@ -2645,79 +2506,80 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
         * JFM, 4/19/1999
         */
 
-       *out_size = in_size;
-
        /* in case of problem, return some default values */
 
-       *needed = 0;
-       *type   = 0;
+       *r->out.needed  = 0;
+       *r->out.type    = 0;
 
-       DEBUG(4,("_spoolss_getprinterdata\n"));
+       DEBUG(4,("_spoolss_GetPrinterData\n"));
 
-       if ( !Printer ) {
-               DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
-               status = WERR_BADFID;
+       if (!Printer) {
+               DEBUG(2,("_spoolss_GetPrinterData: Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
+               result = WERR_BADFID;
                goto done;
        }
 
-       unistr2_to_ascii(value, valuename, sizeof(value));
-
-       if ( Printer->printer_type == SPLHND_SERVER )
-               status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
-       else
-       {
-               if ( !get_printer_snum(p,handle, &snum, NULL) ) {
-                       status = WERR_BADFID;
+       if (Printer->printer_type == SPLHND_SERVER) {
+               result = getprinterdata_printer_server(p->mem_ctx,
+                                                      r->in.value_name,
+                                                      r->out.type,
+                                                      r->out.data);
+       } else {
+               if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
+                       result = WERR_BADFID;
                        goto done;
                }
 
-               status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
-               if ( !W_ERROR_IS_OK(status) )
+               result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
+               if (!W_ERROR_IS_OK(result)) {
                        goto done;
+               }
 
                /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
 
-               if ( strequal(value, "ChangeId") ) {
-                       *type = REG_DWORD;
-                       *needed = sizeof(uint32);
-                       if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
-                               status = WERR_NOMEM;
+               if (strequal(r->in.value_name, "ChangeId")) {
+                       *r->out.type = REG_DWORD;
+                       r->out.data->value = printer->info_2->changeid;
+                       result = WERR_OK;
+               } else {
+                       REGISTRY_VALUE *v;
+                       DATA_BLOB blob;
+
+                       v = get_printer_data(printer->info_2,
+                                            SPOOL_PRINTERDATA_KEY,
+                                            r->in.value_name);
+                       if (!v) {
+                               result = WERR_BADFILE;
                                goto done;
                        }
-                       SIVAL( *data, 0, printer->info_2->changeid );
-                       status = WERR_OK;
-               }
-               else
-                       status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
-       }
 
-       if (*needed > *out_size)
-               status = WERR_MORE_DATA;
-
-done:
-       if ( !W_ERROR_IS_OK(status) )
-       {
-               DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
+                       *r->out.type = v->type;
 
-               /* reply this param doesn't exist */
+                       blob = data_blob_const(v->data_p, v->size);
 
-               if ( *out_size ) {
-                       if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
-                               if ( printer )
-                                       free_a_printer( &printer, 2 );
-                               return WERR_NOMEM;
-                       }
-               } else {
-                       *data = NULL;
+                       result = pull_spoolss_PrinterData(p->mem_ctx, &blob,
+                                                         r->out.data,
+                                                         *r->out.type);
                }
        }
 
+ done:
        /* cleanup & exit */
 
-       if ( printer )
-               free_a_printer( &printer, 2 );
+       if (printer) {
+               free_a_printer(&printer, 2);
+       }
 
-       return status;
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       *r->out.needed  = ndr_size_spoolss_PrinterData(r->out.data, *r->out.type, NULL, 0);
+       *r->out.type    = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
+       r->out.data     = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
+
+       return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
 }
 
 /*********************************************************
@@ -2775,7 +2637,7 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
         * Now start the NT Domain stuff :-).
         */
 
-       ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe);
+       ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
        if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
                        remote_machine, nt_errstr(ret)));
@@ -2792,7 +2654,8 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
 
 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
                                        uint32 localprinter, uint32 type,
-                                       POLICY_HND *handle, struct sockaddr_storage *client_ss)
+                                       struct policy_handle *handle,
+                                       struct sockaddr_storage *client_ss)
 {
        WERROR result;
        NTSTATUS status;
@@ -2878,7 +2741,7 @@ static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx
 
                if (option->types[i].count) {
                        option->types[i].fields = talloc_zero_array(option,
-                               enum spoolss_Field, option->types[i].count);
+                               union spoolss_Field, option->types[i].count);
                        if (!option->types[i].fields) {
                                talloc_free(option);
                                return NULL;
@@ -2906,18 +2769,18 @@ static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx
 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
                                                     struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
 {
-       POLICY_HND *handle = r->in.handle;
        int snum = -1;
        struct spoolss_NotifyOption *option = r->in.notify_options;
        struct sockaddr_storage client_ss;
 
        /* store the notify value in the printer struct */
 
-       Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
        if (!Printer) {
                DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
-                       "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+                       "Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
@@ -2935,7 +2798,7 @@ WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
        if ( Printer->printer_type == SPLHND_SERVER)
                snum = -1;
        else if ( (Printer->printer_type == SPLHND_PRINTER) &&
-                       !get_printer_snum(p, handle, &snum, NULL) )
+                       !get_printer_snum(p, r->in.handle, &snum, NULL) )
                return WERR_BADFID;
 
        if (!interpret_string_addr(&client_ss, p->client_address,
@@ -3423,7 +3286,7 @@ static void spoolss_notify_submitted_time(int snum,
 struct s_notify_info_data_table
 {
        enum spoolss_NotifyType type;
-       enum spoolss_Field field;
+       uint16_t field;
        const char *name;
        enum spoolss_NotifyTable variable_type;
        void (*fn) (int snum, struct spoolss_Notify *data,
@@ -3437,55 +3300,55 @@ struct s_notify_info_data_table
 
 static const struct s_notify_info_data_table notify_info_data_table[] =
 {
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME,         "PRINTER_NOTIFY_SERVER_NAME",         NOTIFY_TABLE_STRING,   spoolss_notify_server_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME,        "PRINTER_NOTIFY_PRINTER_NAME",        NOTIFY_TABLE_STRING,   spoolss_notify_printer_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME,          "PRINTER_NOTIFY_SHARE_NAME",          NOTIFY_TABLE_STRING,   spoolss_notify_share_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME,           "PRINTER_NOTIFY_PORT_NAME",           NOTIFY_TABLE_STRING,   spoolss_notify_port_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME,         "PRINTER_NOTIFY_DRIVER_NAME",         NOTIFY_TABLE_STRING,   spoolss_notify_driver_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT,             "PRINTER_NOTIFY_COMMENT",             NOTIFY_TABLE_STRING,   spoolss_notify_comment },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION,            "PRINTER_NOTIFY_LOCATION",            NOTIFY_TABLE_STRING,   spoolss_notify_location },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE,             "PRINTER_NOTIFY_DEVMODE",             NOTIFY_TABLE_DEVMODE,  spoolss_notify_devmode },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE,             "PRINTER_NOTIFY_SEPFILE",             NOTIFY_TABLE_STRING,   spoolss_notify_sepfile },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR,     "PRINTER_NOTIFY_PRINT_PROCESSOR",     NOTIFY_TABLE_STRING,   spoolss_notify_print_processor },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS,          "PRINTER_NOTIFY_PARAMETERS",          NOTIFY_TABLE_STRING,   spoolss_notify_parameters },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE,            "PRINTER_NOTIFY_DATATYPE",            NOTIFY_TABLE_STRING,   spoolss_notify_datatype },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR,   spoolss_notify_security_desc },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES,          "PRINTER_NOTIFY_ATTRIBUTES",          NOTIFY_TABLE_DWORD,    spoolss_notify_attributes },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY,            "PRINTER_NOTIFY_PRIORITY",            NOTIFY_TABLE_DWORD,    spoolss_notify_priority },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY,    "PRINTER_NOTIFY_DEFAULT_PRIORITY",    NOTIFY_TABLE_DWORD,    spoolss_notify_default_priority },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME,          "PRINTER_NOTIFY_START_TIME",          NOTIFY_TABLE_DWORD,    spoolss_notify_start_time },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME,          "PRINTER_NOTIFY_UNTIL_TIME",          NOTIFY_TABLE_DWORD,    spoolss_notify_until_time },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS,              "PRINTER_NOTIFY_STATUS",              NOTIFY_TABLE_DWORD,    spoolss_notify_status },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING,       "PRINTER_NOTIFY_STATUS_STRING",       NOTIFY_TABLE_STRING,   NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS,               "PRINTER_NOTIFY_CJOBS",               NOTIFY_TABLE_DWORD,    spoolss_notify_cjobs },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM,         "PRINTER_NOTIFY_AVERAGE_PPM",         NOTIFY_TABLE_DWORD,    spoolss_notify_average_ppm },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES,         "PRINTER_NOTIFY_TOTAL_PAGES",         NOTIFY_TABLE_DWORD,    NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED,       "PRINTER_NOTIFY_PAGES_PRINTED",       NOTIFY_TABLE_DWORD,    NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES,         "PRINTER_NOTIFY_TOTAL_BYTES",         NOTIFY_TABLE_DWORD,    NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED,       "PRINTER_NOTIFY_BYTES_PRINTED",       NOTIFY_TABLE_DWORD,    NULL },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_PRINTER_NAME,            "JOB_NOTIFY_PRINTER_NAME",            NOTIFY_TABLE_STRING,   spoolss_notify_printer_name },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_MACHINE_NAME,            "JOB_NOTIFY_MACHINE_NAME",            NOTIFY_TABLE_STRING,   spoolss_notify_server_name },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_PORT_NAME,               "JOB_NOTIFY_PORT_NAME",               NOTIFY_TABLE_STRING,   spoolss_notify_port_name },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_USER_NAME,               "JOB_NOTIFY_USER_NAME",               NOTIFY_TABLE_STRING,   spoolss_notify_username },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_NOTIFY_NAME,             "JOB_NOTIFY_NOTIFY_NAME",             NOTIFY_TABLE_STRING,   spoolss_notify_username },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_DATATYPE,                "JOB_NOTIFY_DATATYPE",                NOTIFY_TABLE_STRING,   spoolss_notify_datatype },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_PRINT_PROCESSOR,         "JOB_NOTIFY_PRINT_PROCESSOR",         NOTIFY_TABLE_STRING,   spoolss_notify_print_processor },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_PARAMETERS,              "JOB_NOTIFY_PARAMETERS",              NOTIFY_TABLE_STRING,   spoolss_notify_parameters },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_DRIVER_NAME,             "JOB_NOTIFY_DRIVER_NAME",             NOTIFY_TABLE_STRING,   spoolss_notify_driver_name },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_DEVMODE,                 "JOB_NOTIFY_DEVMODE",                 NOTIFY_TABLE_DEVMODE,  spoolss_notify_devmode },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_STATUS,                  "JOB_NOTIFY_STATUS",                  NOTIFY_TABLE_DWORD,    spoolss_notify_job_status },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_STATUS_STRING,           "JOB_NOTIFY_STATUS_STRING",           NOTIFY_TABLE_STRING,   spoolss_notify_job_status_string },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_SECURITY_DESCRIPTOR,     "JOB_NOTIFY_SECURITY_DESCRIPTOR",     NOTIFY_TABLE_SECURITYDESCRIPTOR,   NULL },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_DOCUMENT,                "JOB_NOTIFY_DOCUMENT",                NOTIFY_TABLE_STRING,   spoolss_notify_job_name },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_PRIORITY,                "JOB_NOTIFY_PRIORITY",                NOTIFY_TABLE_DWORD,    spoolss_notify_priority },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_POSITION,                "JOB_NOTIFY_POSITION",                NOTIFY_TABLE_DWORD,    spoolss_notify_job_position },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_SUBMITTED,               "JOB_NOTIFY_SUBMITTED",               NOTIFY_TABLE_TIME,     spoolss_notify_submitted_time },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_START_TIME,              "JOB_NOTIFY_START_TIME",              NOTIFY_TABLE_DWORD,    spoolss_notify_start_time },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_UNTIL_TIME,              "JOB_NOTIFY_UNTIL_TIME",              NOTIFY_TABLE_DWORD,    spoolss_notify_until_time },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_TIME,                    "JOB_NOTIFY_TIME",                    NOTIFY_TABLE_DWORD,    spoolss_notify_job_time },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_TOTAL_PAGES,             "JOB_NOTIFY_TOTAL_PAGES",             NOTIFY_TABLE_DWORD,    spoolss_notify_total_pages },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_PAGES_PRINTED,           "JOB_NOTIFY_PAGES_PRINTED",           NOTIFY_TABLE_DWORD,    spoolss_notify_pages_printed },
-{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_TOTAL_BYTES,             "JOB_NOTIFY_TOTAL_BYTES",             NOTIFY_TABLE_DWORD,    spoolss_notify_job_size },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME,         "PRINTER_NOTIFY_FIELD_SERVER_NAME",         NOTIFY_TABLE_STRING,   spoolss_notify_server_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME,        "PRINTER_NOTIFY_FIELD_PRINTER_NAME",        NOTIFY_TABLE_STRING,   spoolss_notify_printer_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME,          "PRINTER_NOTIFY_FIELD_SHARE_NAME",          NOTIFY_TABLE_STRING,   spoolss_notify_share_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME,           "PRINTER_NOTIFY_FIELD_PORT_NAME",           NOTIFY_TABLE_STRING,   spoolss_notify_port_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME,         "PRINTER_NOTIFY_FIELD_DRIVER_NAME",         NOTIFY_TABLE_STRING,   spoolss_notify_driver_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT,             "PRINTER_NOTIFY_FIELD_COMMENT",             NOTIFY_TABLE_STRING,   spoolss_notify_comment },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION,            "PRINTER_NOTIFY_FIELD_LOCATION",            NOTIFY_TABLE_STRING,   spoolss_notify_location },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE,             "PRINTER_NOTIFY_FIELD_DEVMODE",             NOTIFY_TABLE_DEVMODE,  spoolss_notify_devmode },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE,             "PRINTER_NOTIFY_FIELD_SEPFILE",             NOTIFY_TABLE_STRING,   spoolss_notify_sepfile },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR,     "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR",     NOTIFY_TABLE_STRING,   spoolss_notify_print_processor },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS,          "PRINTER_NOTIFY_FIELD_PARAMETERS",          NOTIFY_TABLE_STRING,   spoolss_notify_parameters },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE,            "PRINTER_NOTIFY_FIELD_DATATYPE",            NOTIFY_TABLE_STRING,   spoolss_notify_datatype },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR,   spoolss_notify_security_desc },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES,          "PRINTER_NOTIFY_FIELD_ATTRIBUTES",          NOTIFY_TABLE_DWORD,    spoolss_notify_attributes },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY,            "PRINTER_NOTIFY_FIELD_PRIORITY",            NOTIFY_TABLE_DWORD,    spoolss_notify_priority },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY,    "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY",    NOTIFY_TABLE_DWORD,    spoolss_notify_default_priority },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME,          "PRINTER_NOTIFY_FIELD_START_TIME",          NOTIFY_TABLE_DWORD,    spoolss_notify_start_time },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME,          "PRINTER_NOTIFY_FIELD_UNTIL_TIME",          NOTIFY_TABLE_DWORD,    spoolss_notify_until_time },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS,              "PRINTER_NOTIFY_FIELD_STATUS",              NOTIFY_TABLE_DWORD,    spoolss_notify_status },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING,       "PRINTER_NOTIFY_FIELD_STATUS_STRING",       NOTIFY_TABLE_STRING,   NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS,               "PRINTER_NOTIFY_FIELD_CJOBS",               NOTIFY_TABLE_DWORD,    spoolss_notify_cjobs },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM,         "PRINTER_NOTIFY_FIELD_AVERAGE_PPM",         NOTIFY_TABLE_DWORD,    spoolss_notify_average_ppm },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES,         "PRINTER_NOTIFY_FIELD_TOTAL_PAGES",         NOTIFY_TABLE_DWORD,    NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED,       "PRINTER_NOTIFY_FIELD_PAGES_PRINTED",       NOTIFY_TABLE_DWORD,    NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES,         "PRINTER_NOTIFY_FIELD_TOTAL_BYTES",         NOTIFY_TABLE_DWORD,    NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED,       "PRINTER_NOTIFY_FIELD_BYTES_PRINTED",       NOTIFY_TABLE_DWORD,    NULL },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRINTER_NAME,            "JOB_NOTIFY_FIELD_PRINTER_NAME",            NOTIFY_TABLE_STRING,   spoolss_notify_printer_name },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_MACHINE_NAME,            "JOB_NOTIFY_FIELD_MACHINE_NAME",            NOTIFY_TABLE_STRING,   spoolss_notify_server_name },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PORT_NAME,               "JOB_NOTIFY_FIELD_PORT_NAME",               NOTIFY_TABLE_STRING,   spoolss_notify_port_name },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_USER_NAME,               "JOB_NOTIFY_FIELD_USER_NAME",               NOTIFY_TABLE_STRING,   spoolss_notify_username },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_NOTIFY_NAME,             "JOB_NOTIFY_FIELD_NOTIFY_NAME",             NOTIFY_TABLE_STRING,   spoolss_notify_username },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DATATYPE,                "JOB_NOTIFY_FIELD_DATATYPE",                NOTIFY_TABLE_STRING,   spoolss_notify_datatype },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRINT_PROCESSOR,         "JOB_NOTIFY_FIELD_PRINT_PROCESSOR",         NOTIFY_TABLE_STRING,   spoolss_notify_print_processor },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PARAMETERS,              "JOB_NOTIFY_FIELD_PARAMETERS",              NOTIFY_TABLE_STRING,   spoolss_notify_parameters },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DRIVER_NAME,             "JOB_NOTIFY_FIELD_DRIVER_NAME",             NOTIFY_TABLE_STRING,   spoolss_notify_driver_name },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DEVMODE,                 "JOB_NOTIFY_FIELD_DEVMODE",                 NOTIFY_TABLE_DEVMODE,  spoolss_notify_devmode },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_STATUS,                  "JOB_NOTIFY_FIELD_STATUS",                  NOTIFY_TABLE_DWORD,    spoolss_notify_job_status },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_STATUS_STRING,           "JOB_NOTIFY_FIELD_STATUS_STRING",           NOTIFY_TABLE_STRING,   spoolss_notify_job_status_string },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR,     "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR",     NOTIFY_TABLE_SECURITYDESCRIPTOR,   NULL },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DOCUMENT,                "JOB_NOTIFY_FIELD_DOCUMENT",                NOTIFY_TABLE_STRING,   spoolss_notify_job_name },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRIORITY,                "JOB_NOTIFY_FIELD_PRIORITY",                NOTIFY_TABLE_DWORD,    spoolss_notify_priority },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_POSITION,                "JOB_NOTIFY_FIELD_POSITION",                NOTIFY_TABLE_DWORD,    spoolss_notify_job_position },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_SUBMITTED,               "JOB_NOTIFY_FIELD_SUBMITTED",               NOTIFY_TABLE_TIME,     spoolss_notify_submitted_time },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_START_TIME,              "JOB_NOTIFY_FIELD_START_TIME",              NOTIFY_TABLE_DWORD,    spoolss_notify_start_time },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_UNTIL_TIME,              "JOB_NOTIFY_FIELD_UNTIL_TIME",              NOTIFY_TABLE_DWORD,    spoolss_notify_until_time },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TIME,                    "JOB_NOTIFY_FIELD_TIME",                    NOTIFY_TABLE_DWORD,    spoolss_notify_job_time },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TOTAL_PAGES,             "JOB_NOTIFY_FIELD_TOTAL_PAGES",             NOTIFY_TABLE_DWORD,    spoolss_notify_total_pages },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PAGES_PRINTED,           "JOB_NOTIFY_FIELD_PAGES_PRINTED",           NOTIFY_TABLE_DWORD,    spoolss_notify_pages_printed },
+{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TOTAL_BYTES,             "JOB_NOTIFY_FIELD_TOTAL_BYTES",             NOTIFY_TABLE_DWORD,    spoolss_notify_job_size },
 };
 
 /*******************************************************************
@@ -3493,7 +3356,7 @@ static const struct s_notify_info_data_table notify_info_data_table[] =
 ********************************************************************/
 
 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
-                                                 enum spoolss_Field field)
+                                                 uint16_t field)
 {
        int i=0;
 
@@ -3513,7 +3376,7 @@ static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
 ****************************************************************************/
 
 static bool search_notify(enum spoolss_NotifyType type,
-                         enum spoolss_Field field,
+                         uint16_t field,
                          int *value)
 {
        int i;
@@ -3535,11 +3398,11 @@ static bool search_notify(enum spoolss_NotifyType type,
 
 void construct_info_data(struct spoolss_Notify *info_data,
                         enum spoolss_NotifyType type,
-                        enum spoolss_Field field,
+                        uint16_t field,
                         int id)
 {
        info_data->type                 = type;
-       info_data->field                = field;
+       info_data->field.field          = field;
        info_data->variable_type        = variable_type_of_notify_info_data(type, field);
        info_data->job_id               = id;
 }
@@ -3559,7 +3422,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd,
 {
        int field_num,j;
        enum spoolss_NotifyType type;
-       enum spoolss_Field field;
+       uint16_t field;
 
        struct spoolss_Notify *current_data;
        NT_PRINTER_INFO_LEVEL *printer = NULL;
@@ -3575,7 +3438,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd,
                return False;
 
        for(field_num=0; field_num < option_type->count; field_num++) {
-               field = option_type->fields[field_num];
+               field = option_type->fields[field_num].field;
 
                DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
 
@@ -3624,7 +3487,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue,
 {
        int field_num,j;
        enum spoolss_NotifyType type;
-       enum spoolss_Field field;
+       uint16_t field;
        struct spoolss_Notify *current_data;
 
        DEBUG(4,("construct_notify_jobs_info\n"));
@@ -3636,7 +3499,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue,
                option_type->count));
 
        for(field_num=0; field_num<option_type->count; field_num++) {
-               field = option_type->fields[field_num];
+               field = option_type->fields[field_num].field;
 
                if (!search_notify(type, field, &j) )
                        continue;
@@ -3690,12 +3553,13 @@ static bool construct_notify_jobs_info(print_queue_struct *queue,
  *
  ********************************************************************/
 
-static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
+static WERROR printserver_notify_info(pipes_struct *p,
+                                     struct policy_handle *hnd,
                                      struct spoolss_NotifyInfo *info,
                                      TALLOC_CTX *mem_ctx)
 {
        int snum;
-       Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
        int n_services=lp_numservices();
        int i;
        struct spoolss_NotifyOption *option;
@@ -3756,11 +3620,12 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
  *
  ********************************************************************/
 
-static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spoolss_NotifyInfo *info,
+static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd,
+                                 struct spoolss_NotifyInfo *info,
                                  TALLOC_CTX *mem_ctx)
 {
        int snum;
-       Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
        int i;
        uint32 id;
        struct spoolss_NotifyOption *option;
@@ -3849,10 +3714,9 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spool
 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
                                                 struct spoolss_RouterRefreshPrinterChangeNotify *r)
 {
-       POLICY_HND *handle = r->in.handle;
        struct spoolss_NotifyInfo *info;
 
-       Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
        WERROR result = WERR_BADFID;
 
        /* we always have a spoolss_NotifyInfo struct */
@@ -3866,7 +3730,8 @@ WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
 
        if (!Printer) {
                DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
-                       "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+                       "Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
                goto done;
        }
 
@@ -3895,11 +3760,13 @@ WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
 
        switch (Printer->printer_type) {
                case SPLHND_SERVER:
-                       result = printserver_notify_info(p, handle, info, p->mem_ctx);
+                       result = printserver_notify_info(p, r->in.handle,
+                                                        info, p->mem_ctx);
                        break;
 
                case SPLHND_PRINTER:
-                       result = printer_notify_info(p, handle, info, p->mem_ctx);
+                       result = printer_notify_info(p, r->in.handle,
+                                                    info, p->mem_ctx);
                        break;
        }
 
@@ -3914,219 +3781,161 @@ 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);
-       }
+       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;
 
-       if (!chaine) {
-               free_a_printer(&ntprinter,2);
-               return false;
-       }
-
-       init_unistr(&printer->description, chaine);
-       init_unistr(&printer->name, ntprinter->info_2->printername);
-
-       free_a_printer(&ntprinter,2);
-
-       return True;
-}
-
-/****************************************************************************
- Free a DEVMODE struct.
-****************************************************************************/
-
-static void free_dev_mode(DEVICEMODE *dev)
-{
-       if (dev == NULL)
-               return;
-
-       SAFE_FREE(dev->dev_private);
-       SAFE_FREE(dev);
+       return WERR_OK;
 }
 
-
 /****************************************************************************
- Convert an NT_DEVICEMODE to a DEVICEMODE structure.  Both pointers
+ Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure.  Both pointers
  should be valid upon entry
 ****************************************************************************/
 
-static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
+static WERROR convert_nt_devicemode(TALLOC_CTX *mem_ctx,
+                                   struct spoolss_DeviceMode *r,
+                                   const NT_DEVICEMODE *ntdevmode)
 {
-       if ( !devmode || !ntdevmode )
-               return False;
+       if (!r || !ntdevmode) {
+               return WERR_INVALID_PARAM;
+       }
 
-       init_unistr(&devmode->devicename, ntdevmode->devicename);
-
-       init_unistr(&devmode->formname, ntdevmode->formname);
-
-       devmode->specversion      = ntdevmode->specversion;
-       devmode->driverversion    = ntdevmode->driverversion;
-       devmode->size             = ntdevmode->size;
-       devmode->driverextra      = ntdevmode->driverextra;
-       devmode->fields           = ntdevmode->fields;
-
-       devmode->orientation      = ntdevmode->orientation;
-       devmode->papersize        = ntdevmode->papersize;
-       devmode->paperlength      = ntdevmode->paperlength;
-       devmode->paperwidth       = ntdevmode->paperwidth;
-       devmode->scale            = ntdevmode->scale;
-       devmode->copies           = ntdevmode->copies;
-       devmode->defaultsource    = ntdevmode->defaultsource;
-       devmode->printquality     = ntdevmode->printquality;
-       devmode->color            = ntdevmode->color;
-       devmode->duplex           = ntdevmode->duplex;
-       devmode->yresolution      = ntdevmode->yresolution;
-       devmode->ttoption         = ntdevmode->ttoption;
-       devmode->collate          = ntdevmode->collate;
-       devmode->icmmethod        = ntdevmode->icmmethod;
-       devmode->icmintent        = ntdevmode->icmintent;
-       devmode->mediatype        = ntdevmode->mediatype;
-       devmode->dithertype       = ntdevmode->dithertype;
+       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) {
-               if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
-                       return False;
+               r->driverextra_data = data_blob_talloc(mem_ctx,
+                       ntdevmode->nt_dev_private,
+                       ntdevmode->driverextra);
+               W_ERROR_HAVE_NO_MEMORY(r->driverextra_data.data);
        }
 
-       return True;
+       return WERR_OK;
 }
 
+
 /****************************************************************************
- 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(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"));
 
@@ -4135,23 +3944,22 @@ DEVICEMODE *construct_dev_mode(const char *servicename)
        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: 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(mem_ctx, devmode, printer->info_2->devmode);
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(devmode);
        }
 
 done:
@@ -4161,371 +3969,348 @@ done:
 }
 
 /********************************************************************
- * construct_printer_info_2
- * fill a printer_info_2 struct
+ * construct_printer_info3
+ * fill a spoolss_PrinterInfo3 struct
  ********************************************************************/
 
-static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
+static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
+                                     const NT_PRINTER_INFO_LEVEL *ntprinter,
+                                     struct spoolss_PrinterInfo3 *r,
+                                     int snum)
 {
-       int count;
-       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
-
-       print_status_struct status;
+       /* These are the components of the SD we are returning. */
 
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
-               return False;
+       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 */
 
-       count = print_queue_length(snum, &status);
+               r->secdesc = dup_sec_desc(mem_ctx,
+                                         ntprinter->info_2->secdesc_buf->sd);
+               W_ERROR_HAVE_NO_MEMORY(r->secdesc);
+       }
 
-       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 */
+       return WERR_OK;
+}
 
-       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. */
+/********************************************************************
+ * construct_printer_info4
+ * fill a spoolss_PrinterInfo4 struct
********************************************************************/
 
-       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) */
+static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
+                                     const NT_PRINTER_INFO_LEVEL *ntprinter,
+                                     struct spoolss_PrinterInfo4 *r,
+                                     int snum)
+{
+       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);
 
-       printer->attributes = ntprinter->info_2->attributes;
+       r->attributes   = ntprinter->info_2->attributes;
 
-       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 */
+       return WERR_OK;
+}
 
-       if ( !(printer->devmode = construct_dev_mode(
-                      lp_const_servicename(snum))) )
-               DEBUG(8, ("Returning NULL Devicemode!\n"));
+/********************************************************************
+ * construct_printer_info5
+ * fill a spoolss_PrinterInfo5 struct
+ ********************************************************************/
 
-       printer->secdesc = NULL;
+static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
+                                     const NT_PRINTER_INFO_LEVEL *ntprinter,
+                                     struct spoolss_PrinterInfo5 *r,
+                                     int snum)
+{
+       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 ( 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 */
+       r->attributes   = ntprinter->info_2->attributes;
 
-               printer->secdesc = dup_sec_desc( talloc_tos(),
-                       ntprinter->info_2->secdesc_buf->sd );
-       }
+       /* these two are not used by NT+ according to MSDN */
 
-       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_3
- * fill a printer_info_3 struct
+ * construct_printer_info_6
+ * fill a spoolss_PrinterInfo6 struct
  ********************************************************************/
 
-static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_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;
-       PRINTER_INFO_3 *printer = 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);
 
-       *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;
-       }
+       r->status = nt_printq_status(status.status);
 
-       ZERO_STRUCTP(printer);
+       return WERR_OK;
+}
 
-       /* These are the components of the SD we are returning. */
+/********************************************************************
+ * construct_printer_info7
+ * fill a spoolss_PrinterInfo7 struct
+ ********************************************************************/
 
-       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 construct_printer_info7(TALLOC_CTX *mem_ctx,
+                                     Printer_entry *print_hnd,
+                                     struct spoolss_PrinterInfo7 *r,
+                                     int snum)
+{
+       struct GUID guid;
 
-               printer->secdesc = dup_sec_desc( talloc_tos(),
-                       ntprinter->info_2->secdesc_buf->sd );
+       if (is_printer_published(print_hnd, snum, &guid)) {
+               r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
+               r->action = DSPRINT_PUBLISH;
+       } else {
+               r->guid = talloc_strdup(mem_ctx, "");
+               r->action = DSPRINT_UNPUBLISH;
        }
+       W_ERROR_HAVE_NO_MEMORY(r->guid);
 
-       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_info1
+ * fill a spoolss_PrinterInfo1 struct
+********************************************************************/
 
-static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
+static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
+                                     const NT_PRINTER_INFO_LEVEL *ntprinter,
+                                     uint32_t flags,
+                                     struct spoolss_PrinterInfo1 *r,
+                                     int snum)
 {
-       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+       char *chaine = NULL;
+       r->flags                = flags;
 
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
-               return False;
+       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);
 
-       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->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);
 
-       free_a_printer(&ntprinter, 2);
-       return True;
+       return WERR_OK;
 }
 
 /********************************************************************
- * construct_printer_info_5
- * fill a printer_info_5 struct
- ********************************************************************/
+ * construct_printer_info2
+ * fill a spoolss_PrinterInfo2 struct
+********************************************************************/
 
-static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
+static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
+                                     const NT_PRINTER_INFO_LEVEL *ntprinter,
+                                     struct spoolss_PrinterInfo2 *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;
+       int count;
 
-       init_unistr(&printer->printername, ntprinter->info_2->printername);
-       init_unistr(&printer->portname, ntprinter->info_2->portname);
-       printer->attributes = ntprinter->info_2->attributes;
+       print_status_struct status;
 
-       /* these two are not used by NT+ according to MSDN */
+       count = print_queue_length(snum, &status);
 
-       printer->device_not_selected_timeout = 0x0;  /* have seen 0x3a98 */
-       printer->transmission_retry_timeout  = 0x0;  /* have seen 0xafc8 */
+       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);
 
-       free_a_printer(&ntprinter, 2);
+       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);
 
-       return True;
-}
+       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);
 
-/********************************************************************
- * construct_printer_info_6
- * fill a printer_info_6 struct
- ********************************************************************/
+       r->attributes           = ntprinter->info_2->attributes;
 
-static bool construct_printer_info_6(Printer_entry *print_hnd,
-                                    PRINTER_INFO_6 *printer,
-                                    int snum)
-{
-       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
-       int count;
-       print_status_struct status;
+       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(get_a_printer(print_hnd, &ntprinter, 2,
-                                        lp_const_servicename(snum))))
-               return False;
+       r->devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
+       if (!r->devmode) {
+               DEBUG(8,("Returning NULL Devicemode!\n"));
+       }
 
-       count = print_queue_length(snum, &status);
+       r->secdesc              = NULL;
 
-       printer->status = nt_printq_status(status.status);
+       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 */
 
-       free_a_printer(&ntprinter, 2);
+               r->secdesc      = dup_sec_desc(mem_ctx, ntprinter->info_2->secdesc_buf->sd);
+       }
 
-       return True;
+       return WERR_OK;
 }
 
 /********************************************************************
- * construct_printer_info_7
- * fill a printer_info_7 struct
- ********************************************************************/
+********************************************************************/
 
-static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
+static bool snum_is_shared_printer(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;
-       } else {
-               init_unistr(&printer->guid, "");
-               printer->action = DSPRINT_UNPUBLISH;
-       }
-
-       return True;
+       return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
 }
 
 /********************************************************************
  Spoolss_enumprinters.
 ********************************************************************/
 
-static WERROR enum_all_printers_info_1(uint32 flags, 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)
 {
        int snum;
-       int i;
-       int n_services=lp_numservices();
-       PRINTER_INFO_1 *printers=NULL;
-       PRINTER_INFO_1 current_prt;
+       int n_services = lp_numservices();
+       union spoolss_PrinterInfo *info = NULL;
        WERROR result = WERR_OK;
 
        DEBUG(4,("enum_all_printers_info_1\n"));
 
+       *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_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));
 
-                               memcpy(&printers[*returned], &current_prt, sizeof(PRINTER_INFO_1));
-                               (*returned)++;
-                       }
+               NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+               struct spoolss_PrinterInfo1 info1;
+
+               if (!snum_is_shared_printer(snum)) {
+                       continue;
                }
-       }
 
-       /* check the required size. */
-       for (i=0; i<*returned; i++)
-               (*needed) += spoolss_size_printer_info_1(&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_info1(info, ntprinter, flags, &info1, 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_1("", buffer, &printers[i], 0);
+               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;
+               }
 
-out:
-       /* clear memory */
+               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *count));
 
-       SAFE_FREE(printers);
+               info[*count].info1 = info1;
+               (*count)++;
+       }
+
+ out:
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
+       }
 
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+       *info_p = info;
 
-       return result;
+       return WERR_OK;
 }
 
 /********************************************************************
  enum_all_printers_info_1_local.
 *********************************************************************/
 
-static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+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(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
+       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(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_name(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_name\n"));
 
-       if ((name[0] == '\\') && (name[1] == '\\'))
+       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;
-}
-
-#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)
-               return WERR_NOMEM;
-
-       *returned=1;
-
-       slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
-       slprintf(desc, sizeof(desc)-1,"%s", name);
-       slprintf(comment, sizeof(comment)-1, "Logged on Domain");
-
-       init_unistr(&printer->description, desc);
-       init_unistr(&printer->name, printername);
-       init_unistr(&printer->comment, comment);
-       printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_1(printer);
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
        }
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+       if (!is_myname_or_ipaddr(s)) {
+               return WERR_INVALID_NAME;
        }
 
-       /* fill the buffer with the structures */
-       smb_io_printer_info_1("", buffer, printer, 0);
-
-out:
-       /* clear memory */
-       SAFE_FREE(printer);
-
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
-
-       return result;
+       return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
 }
 
-#endif
-
 /********************************************************************
  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 +4322,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 +4339,90 @@ 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_NAME)
-               return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
+       if (flags & PRINTER_ENUM_LOCAL) {
+               return enum_all_printers_info_1_local(mem_ctx, 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);
-#endif
+       if (flags & PRINTER_ENUM_NAME) {
+               return enum_all_printers_info_1_name(mem_ctx, name, info, count);
+       }
 
-       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 +4431,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 +4460,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,621 +4505,426 @@ 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;
-       }
-       return WERR_UNKNOWN_LEVEL;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
-       PRINTER_INFO_0 *printer=NULL;
-       WERROR result = WERR_OK;
-
-       if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
-               return WERR_NOMEM;
-
-       construct_printer_info_0(print_hnd, printer, snum);
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_0(printer);
-
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
+       default:
+               return WERR_UNKNOWN_LEVEL;
        }
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
        }
 
-       /* fill the buffer with the structures */
-       smb_io_printer_info_0("", buffer, printer, 0);
-
-out:
-       /* clear memory */
-
-       SAFE_FREE(printer);
+       *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 result;
+       return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 }
 
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_GetPrinter
+****************************************************************/
 
-static WERROR getprinter_level_1(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_1 *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_1)) == NULL)
-               return WERR_NOMEM;
-
-       construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_1(printer);
+       int snum;
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
+       /* that's an [in out] buffer */
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+       if (!r->in.buffer && (r->in.offered != 0)) {
+               return WERR_INVALID_PARAM;
        }
 
-       /* fill the buffer with the structures */
-       smb_io_printer_info_1("", buffer, printer, 0);
-
-out:
-       /* clear memory */
-       SAFE_FREE(printer);
-
-       return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
-       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->out.needed = 0;
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
+       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 */
-       if (!smb_io_printer_info_2("", buffer, printer, 0))
-               result = WERR_NOMEM;
-
-out:
-       /* clear memory */
-       free_printer_info_2(printer);
-
-       return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-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;
+       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;
        }
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
-       }
+       free_a_printer(&ntprinter, 2);
 
-       /* fill the buffer with the structures */
-       smb_io_printer_info_3("", buffer, printer, 0);
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(r->out.info);
+               return result;
+       }
 
-out:
-       /* clear memory */
-       free_printer_info_3(printer);
+       *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 result;
+       return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 }
 
-/****************************************************************************
-****************************************************************************/
+/********************************************************************
+ ********************************************************************/
 
-static WERROR getprinter_level_4(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_4 *printer=NULL;
-       WERROR result = WERR_OK;
+       int i, num_strings = 0;
+       const char **array = NULL;
 
-       if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
-               return WERR_NOMEM;
+       for (i=0; fstring_array && fstring_array[i][0] != '\0'; i++) {
 
-       if (!construct_printer_info_4(print_hnd, printer, snum)) {
-               SAFE_FREE(printer);
-               return WERR_NOMEM;
-       }
+               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_4(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_4("", buffer, printer, 0);
-
-out:
-       /* clear memory */
-       free_printer_info_4(printer);
-
-       return result;
+       return array;
 }
 
-/****************************************************************************
-****************************************************************************/
+/********************************************************************
+ * fill a spoolss_DriverInfo1 struct
+ ********************************************************************/
 
-static WERROR getprinter_level_5(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_5 *printer=NULL;
-       WERROR result = WERR_OK;
-
-       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);
 
-       if (!construct_printer_info_5(print_hnd, printer, snum)) {
-               free_printer_info_5(printer);
-               return WERR_NOMEM;
-       }
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_5(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_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;
-
-       if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
-               return WERR_NOMEM;
-       }
-
-       if (!construct_printer_info_6(print_hnd, printer, snum)) {
-               free_printer_info_6(printer);
-               return WERR_NOMEM;
-       }
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_6(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_6("", buffer, printer, 0);
-
-out:
-       /* clear memory */
-       free_printer_info_6(printer);
+/********************************************************************
+ * fill a spoolss_DriverInfo2 struct
+ ********************************************************************/
 
-       return result;
-}
+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_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;
-       }
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_info_7(printer);
+       const char *cservername = canon_servername(servername);
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
+       r->version              = driver->info_3->cversion;
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+       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 (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_7("", buffer, printer, 0);
-
-out:
-       /* clear memory */
-       free_printer_info_7(printer);
-
-       return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
-{
-       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);
-
-       int snum;
-
-       /* that's an [in out] buffer */
-
-       if (!q_u->buffer && (offered!=0)) {
-               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);
 
-       if (offered > MAX_RPC_DATA_SIZE) {
-               return WERR_INVALID_PARAM;
+       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);
 
-       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;
-
-       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);
-       }
-       return WERR_UNKNOWN_LEVEL;
+       return WERR_OK;
 }
 
 /********************************************************************
- * fill a DRIVER_INFO_1 struct
+ * fill a spoolss_DriverInfo3 struct
  ********************************************************************/
 
-static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
+static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
+                                       struct spoolss_DriverInfo3 *r,
+                                       const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+                                       const char *servername)
 {
-       init_unistr( &info->name, driver.info_3->name);
-}
+       const char *cservername = canon_servername(servername);
 
-/********************************************************************
- * construct_printer_driver_info_1
- ********************************************************************/
+       r->version              = driver->info_3->cversion;
 
-static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
-{
-       NT_PRINTER_INFO_LEVEL *printer = NULL;
-       NT_PRINTER_DRIVER_INFO_LEVEL driver;
+       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);
 
-       ZERO_STRUCT(driver);
+       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 (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
-               return WERR_INVALID_PRINTER_NAME;
+       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 (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
-               free_a_printer(&printer, 2);
-               return WERR_UNKNOWN_PRINTER_DRIVER;
+       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_printer_driver_info_1(info, driver, servername, architecture);
+       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);
 
-       free_a_printer(&printer,2);
+       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);
        return WERR_OK;
 }
 
 /********************************************************************
- * construct_printer_driver_info_2
- * fill a printer_info_2 struct
+ * fill a spoolss_DriverInfo6 struct
  ********************************************************************/
 
-static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
+static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
+                                       struct spoolss_DriverInfo6 *r,
+                                       const 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;
+       r->version              = driver->info_3->cversion;
 
-       init_unistr( &info->name, driver.info_3->name );
-       init_unistr( &info->architecture, driver.info_3->environment );
+       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 (strlen(driver.info_3->driverpath)) {
-               temp = talloc_asprintf(ctx,
-                               "\\\\%s%s",
-                               cservername,
-                               driver.info_3->driverpath);
-               init_unistr( &info->driverpath, temp );
+       if (strlen(driver->info_3->driverpath)) {
+               r->driver_path  = talloc_asprintf(mem_ctx, "\\\\%s%s",
+                               cservername, driver->info_3->driverpath);
        } 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, "" );
-}
-
-/********************************************************************
- * construct_printer_driver_info_2
- * 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)
-{
-       NT_PRINTER_INFO_LEVEL *printer = NULL;
-       NT_PRINTER_DRIVER_INFO_LEVEL driver;
-
-       ZERO_STRUCT(printer);
-       ZERO_STRUCT(driver);
-
-       if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
-               return WERR_INVALID_PRINTER_NAME;
+               r->driver_path  = talloc_strdup(mem_ctx, "");
+       }
+       W_ERROR_HAVE_NO_MEMORY(r->driver_path);
 
-       if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
-               free_a_printer(&printer, 2);
-               return WERR_UNKNOWN_PRINTER_DRIVER;
+       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);
 
-       fill_printer_driver_info_2(info, driver, servername);
+       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);
 
-       free_a_printer(&printer,2);
+       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);
+
+       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);
 
        return WERR_OK;
 }
 
 /********************************************************************
- * copy a strings array and convert to UNICODE
- *
- * convert an array of ascii string to a UNICODE string
+ * construct_printer_driver_info_1
  ********************************************************************/
 
-static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
-{
-       int i=0;
-       int j=0;
-       const char *v;
-       char *line = NULL;
-       TALLOC_CTX *ctx = talloc_tos();
-
-       DEBUG(6,("init_unistr_array\n"));
-       *uni_array=NULL;
-
-       while (true) {
-               if ( !char_array ) {
-                       v = "";
-               } else {
-                       v = char_array[i];
-                       if (!v)
-                               v = ""; /* hack to handle null lists */
-               }
-
-               /* hack to allow this to be used in places other than when generating
-                  the list of dependent files */
-
-               TALLOC_FREE(line);
-               if ( servername ) {
-                       line = talloc_asprintf(ctx,
-                                       "\\\\%s%s",
-                                       canon_servername(servername),
-                                       v);
-               } else {
-                       line = talloc_strdup(ctx, v);
-               }
-
-               if (!line) {
-                       SAFE_FREE(*uni_array);
-                       return 0;
-               }
-               DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
-
-               /* add one extra unit16 for the second terminating NULL */
-
-               if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
-                       DEBUG(2,("init_unistr_array: Realloc error\n" ));
-                       return 0;
-               }
-
-               if ( !strlen(v) )
-                       break;
+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;
 
-               j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
-               i++;
-       }
+       ZERO_STRUCT(driver);
+
+       if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
+               return WERR_INVALID_PRINTER_NAME;
 
-       if (*uni_array) {
-               /* special case for ""; we need to add both NULL's here */
-               if (!j)
-                       (*uni_array)[j++]=0x0000;
-               (*uni_array)[j]=0x0000;
+       if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
+               free_a_printer(&printer, 2);
+               return WERR_UNKNOWN_PRINTER_DRIVER;
        }
 
-       DEBUGADD(6,("last one:done\n"));
+       result = fill_printer_driver_info1(mem_ctx, r, &driver, servername, architecture);
 
-       /* return size of array in uint16's */
+       free_a_printer(&printer,2);
 
-       return j+1;
+       return result;
 }
 
 /********************************************************************
- * construct_printer_info_3
- * fill a printer_info_3 struct
+ * construct_printer_driver_info_2
+ * fill a printer_info_2 struct
  ********************************************************************/
 
-static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
+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)
 {
-       char *temp = NULL;
-       TALLOC_CTX *ctx = talloc_tos();
-       const char *cservername = canon_servername(servername);
+       NT_PRINTER_INFO_LEVEL *printer = NULL;
+       NT_PRINTER_DRIVER_INFO_LEVEL driver;
+       WERROR result;
+
+       ZERO_STRUCT(printer);
+       ZERO_STRUCT(driver);
+
+       if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
+               return WERR_INVALID_PRINTER_NAME;
+
+       if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
+               free_a_printer(&printer, 2);
+               return WERR_UNKNOWN_PRINTER_DRIVER;
+       }
+
+       result = fill_printer_driver_info2(mem_ctx, r, &driver, servername);
+
+       free_a_printer(&printer,2);
 
-       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);
+       return result;
 }
 
 /********************************************************************
@@ -5350,7 +4932,12 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_IN
  * 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;
@@ -5397,92 +4984,11 @@ static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, con
 #endif
 
 
-       fill_printer_driver_info_3(info, driver, servername);
+       status = fill_printer_driver_info3(mem_ctx, r, &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, "");
+       return status;
 }
 
 /********************************************************************
@@ -5490,8 +4996,12 @@ static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_IN
  * 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)
+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)
 {
        NT_PRINTER_INFO_LEVEL           *printer = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL    driver;
@@ -5531,246 +5041,104 @@ static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
                }
        }
 
-       fill_printer_driver_info_6(info, driver, servername);
+       status = fill_printer_driver_info6(mem_ctx, r, &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;
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_driver_info_3(&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_3("", buffer, &info, 0);
-
-out:
-       free_printer_driver_info_3(&info);
-
-       return result;
+       return status;
 }
 
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_GetPrinterDriver2
+****************************************************************/
 
-static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
+                                 struct spoolss_GetPrinterDriver2 *r)
 {
-       DRIVER_INFO_6 info;
-       WERROR result;
-
-       ZERO_STRUCT(info);
-
-       result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(result))
-               goto out;
-
-       /* check the required size. */
-       *needed += spoolss_size_printer_driver_info_6(&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_6("", buffer, &info, 0);
-
-out:
-       free_printer_driver_info_6(&info);
-
-       return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
-{
-       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);
 }
 
 
@@ -5781,9 +5149,7 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
                                 struct spoolss_StartPagePrinter *r)
 {
-       POLICY_HND *handle = r->in.handle;
-
-       Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
        if (!Printer) {
                DEBUG(3,("_spoolss_StartPagePrinter: "
@@ -5802,18 +5168,17 @@ WERROR _spoolss_StartPagePrinter(pipes_struct *p,
 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
                               struct spoolss_EndPagePrinter *r)
 {
-       POLICY_HND *handle = r->in.handle;
        int snum;
 
-       Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
        if (!Printer) {
                DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
-                       OUR_HANDLE(handle)));
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p, handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL))
                return WERR_BADFID;
 
        Printer->page_started=False;
@@ -5829,15 +5194,15 @@ WERROR _spoolss_EndPagePrinter(pipes_struct *p,
 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
                                struct spoolss_StartDocPrinter *r)
 {
-       POLICY_HND *handle = r->in.handle;
        uint32_t *jobid = r->out.job_id;
        struct spoolss_DocumentInfo1 *info_1;
        int snum;
-       Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
        if (!Printer) {
                DEBUG(2,("_spoolss_StartDocPrinter: "
-                       "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
+                       "Invalid handle (%s:%u:%u)\n",
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
@@ -5863,12 +5228,12 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p,
        }
 
        /* get the share number of the printer */
-       if (!get_printer_snum(p, handle, &snum, NULL)) {
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
        }
 
        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
@@ -5891,9 +5256,7 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p,
 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
                              struct spoolss_EndDocPrinter *r)
 {
-       POLICY_HND *handle = r->in.handle;
-
-       return _spoolss_enddocprinter_internal(p, handle);
+       return _spoolss_enddocprinter_internal(p, r->in.handle);
 }
 
 /****************************************************************
@@ -5903,21 +5266,20 @@ WERROR _spoolss_EndDocPrinter(pipes_struct *p,
 WERROR _spoolss_WritePrinter(pipes_struct *p,
                             struct spoolss_WritePrinter *r)
 {
-       POLICY_HND *handle = r->in.handle;
        uint32 buffer_size = r->in._data_size;
        uint8 *buffer = r->in.data.data;
        uint32 *buffer_written = &r->in._data_size;
        int snum;
-       Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
        if (!Printer) {
                DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
-                       OUR_HANDLE(handle)));
+                       OUR_HANDLE(r->in.handle)));
                *r->out.num_written = r->in._data_size;
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p, handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL))
                return WERR_BADFID;
 
        (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
@@ -5941,7 +5303,7 @@ WERROR _spoolss_WritePrinter(pipes_struct *p,
  *
  ********************************************************************/
 
-static WERROR control_printer(POLICY_HND *handle, uint32 command,
+static WERROR control_printer(struct policy_handle *handle, uint32_t command,
                              pipes_struct *p)
 {
        int snum;
@@ -5949,7 +5311,8 @@ static WERROR control_printer(POLICY_HND *handle, uint32 command,
        Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
 
        if (!Printer) {
-               DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
+               DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
+                       OUR_HANDLE(handle)));
                return WERR_BADFID;
        }
 
@@ -5990,18 +5353,17 @@ static WERROR control_printer(POLICY_HND *handle, uint32 command,
 WERROR _spoolss_AbortPrinter(pipes_struct *p,
                             struct spoolss_AbortPrinter *r)
 {
-       POLICY_HND      *handle = r->in.handle;
-       Printer_entry   *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
        int             snum;
        WERROR          errcode = WERR_OK;
 
        if (!Printer) {
                DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
-                       OUR_HANDLE(handle)));
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p, handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL))
                return WERR_BADFID;
 
        print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
@@ -6014,7 +5376,7 @@ WERROR _spoolss_AbortPrinter(pipes_struct *p,
  * when updating a printer description
  ********************************************************************/
 
-static WERROR update_printer_sec(POLICY_HND *handle,
+static WERROR update_printer_sec(struct policy_handle *handle,
                                 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
 {
        SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
@@ -6300,7 +5662,7 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV
  * when updating a printer description.
  ********************************************************************/
 
-static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
+static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
                             struct spoolss_SetPrinterInfoCtr *info_ctr,
                             struct spoolss_DeviceMode *devmode)
 {
@@ -6339,7 +5701,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
         * just read from the tdb in the pointer 'printer'.
         */
 
-       if (!convert_printer_info_new(info_ctr, printer)) {
+       if (!convert_printer_info(info_ctr, printer)) {
                result =  WERR_NOMEM;
                goto done;
        }
@@ -6349,9 +5711,8 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
                   convert it and link it*/
 
                DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
-               if (!convert_devicemode_new(printer->info_2->printername,
-                                           devmode,
-                                           &printer->info_2->devmode)) {
+               if (!convert_devicemode(printer->info_2->printername, devmode,
+                                       &printer->info_2->devmode)) {
                        result =  WERR_NOMEM;
                        goto done;
                }
@@ -6494,7 +5855,8 @@ done:
 
 /****************************************************************************
 ****************************************************************************/
-static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
+static WERROR publish_or_unpublish_printer(pipes_struct *p,
+                                          struct policy_handle *handle,
                                           struct spoolss_SetPrinterInfo7 *info7)
 {
 #ifdef HAVE_ADS
@@ -6530,36 +5892,35 @@ static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
 WERROR _spoolss_SetPrinter(pipes_struct *p,
                           struct spoolss_SetPrinter *r)
 {
-       POLICY_HND *handle = r->in.handle;
        WERROR result;
 
-       Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
        if (!Printer) {
                DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
-                       OUR_HANDLE(handle)));
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
        /* check the level */
        switch (r->in.info_ctr->level) {
                case 0:
-                       return control_printer(handle, r->in.command, p);
+                       return control_printer(r->in.handle, r->in.command, p);
                case 2:
-                       result = update_printer(p, handle,
+                       result = update_printer(p, r->in.handle,
                                                r->in.info_ctr,
                                                r->in.devmode_ctr->devmode);
                        if (!W_ERROR_IS_OK(result))
                                return result;
                        if (r->in.secdesc_ctr->sd)
-                               result = update_printer_sec(handle, p,
+                               result = update_printer_sec(r->in.handle, p,
                                                            r->in.secdesc_ctr);
                        return result;
                case 3:
-                       return update_printer_sec(handle, p,
+                       return update_printer_sec(r->in.handle, p,
                                                  r->in.secdesc_ctr);
                case 7:
-                       return publish_or_unpublish_printer(p, handle,
+                       return publish_or_unpublish_printer(p, r->in.handle,
                                                            r->in.info_ctr->info.info7);
                default:
                        return WERR_UNKNOWN_LEVEL;
@@ -6573,12 +5934,11 @@ WERROR _spoolss_SetPrinter(pipes_struct *p,
 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
                                       struct spoolss_FindClosePrinterNotify *r)
 {
-       POLICY_HND *handle = r->in.handle;
-       Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
        if (!Printer) {
                DEBUG(2,("_spoolss_FindClosePrinterNotify: "
-                       "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
+                       "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
@@ -6588,7 +5948,7 @@ WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
                if ( Printer->printer_type == SPLHND_SERVER)
                        snum = -1;
                else if ( (Printer->printer_type == SPLHND_PRINTER) &&
-                               !get_printer_snum(p, handle, &snum, NULL) )
+                               !get_printer_snum(p, r->in.handle, &snum, NULL) )
                        return WERR_BADFID;
 
                srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
@@ -6626,251 +5986,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;
-       }
+       info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
+       W_ERROR_HAVE_NO_MEMORY(info);
 
-       for (i=0; i<*returned; i++)
-               fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
+       *count = num_queues;
 
-       /* check the required size. */
-       for (i=0; i<*returned; i++)
-               (*needed) += spoolss_size_job_info_1(&info[i]);
-
-       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;
-       }
 
-       /* this should not be a failure condition if the devmode is NULL */
+       info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
+       W_ERROR_HAVE_NO_MEMORY(info);
 
-       devmode = construct_dev_mode(lp_const_servicename(snum));
+       *count = num_queues;
 
-       for (i=0; i<*returned; i++)
-               fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
+       for (i=0; i<*count; i++) {
 
-       /* check the required size. */
-       for (i=0; i<*returned; i++)
-               (*needed) += spoolss_size_job_info_2(&info[i]);
+               struct spoolss_DeviceMode *devmode;
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto out;
-       }
+               devmode = construct_dev_mode(info, lp_const_servicename(snum));
+               if (!devmode) {
+                       result = WERR_NOMEM;
+                       goto out;
+               }
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
-               goto out;
+               result = fill_job_info2(info,
+                                       &info[i].info2,
+                                       &queue[i],
+                                       i,
+                                       snum,
+                                       ntprinter,
+                                       devmode);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto out;
+               }
        }
 
-       /* 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;
+ out:
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
+       }
 
-       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);
 }
 
 /****************************************************************
@@ -6890,14 +6275,13 @@ WERROR _spoolss_ScheduleJob(pipes_struct *p,
 WERROR _spoolss_SetJob(pipes_struct *p,
                       struct spoolss_SetJob *r)
 {
-       POLICY_HND *handle = r->in.handle;
        uint32 jobid = r->in.job_id;
        uint32 command = r->in.command;
 
        int snum;
        WERROR errcode = WERR_BADFUNC;
 
-       if (!get_printer_snum(p, handle, &snum, NULL)) {
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
        }
 
@@ -6934,463 +6318,479 @@ 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;
+       }
 
-static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
-{
-       form->flag=list->flag;
-       init_unistr(&form->name, list->name);
-       form->width=list->width;
-       form->length=list->length;
-       form->left=list->left;
-       form->top=list->top;
-       form->right=list->right;
-       form->bottom=list->bottom;
+       *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)
 {
-       form->form_name         = talloc_strdup(mem_ctx, list->name);
-       W_ERROR_HAVE_NO_MEMORY(form->form_name);
+       r->form_name    = talloc_strdup(mem_ctx, form->name);
+       W_ERROR_HAVE_NO_MEMORY(r->form_name);
 
-       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;
+       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
+****************************************************************/
 
-WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
+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)
 {
-       uint32 level = q_u->level;
-       RPC_BUFFER *buffer = NULL;
-       uint32 offered = q_u->offered;
-       uint32 *needed = &r_u->needed;
-       uint32 *numofforms = &r_u->numofforms;
-       uint32 numbuiltinforms;
-
-       nt_forms_struct *list=NULL;
-       nt_forms_struct *builtinlist=NULL;
-       FORM_1 *forms_1;
-       int buffer_size=0;
+       union spoolss_FormInfo *info;
+       WERROR result = WERR_OK;
        int i;
 
-       /* that's an [in out] buffer */
+       *count = num_builtin_forms + num_user_forms;
 
-       if (!q_u->buffer && (offered!=0) ) {
-               return WERR_INVALID_PARAM;
+       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;
+               }
        }
 
-       if (offered > MAX_RPC_DATA_SIZE) {
-               return WERR_INVALID_PARAM;
+       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;
+               }
+       }
+
+ out:
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
        }
 
-       rpcbuf_move(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+       *info_p = info;
 
-       DEBUG(4,("_spoolss_enumforms\n"));
-       DEBUGADD(5,("Offered buffer size [%d]\n", offered));
-       DEBUGADD(5,("Info level [%d]\n",          level));
+       return WERR_OK;
+}
 
-       numbuiltinforms = get_builtin_ntforms(&builtinlist);
-       DEBUGADD(5,("Number of builtin forms [%d]\n",     numbuiltinforms));
-       *numofforms = get_ntforms(&list);
-       DEBUGADD(5,("Number of user forms [%d]\n",     *numofforms));
-       *numofforms += numbuiltinforms;
+/****************************************************************
+ _spoolss_EnumForms
+****************************************************************/
 
-       if (*numofforms == 0) {
-               SAFE_FREE(builtinlist);
-               SAFE_FREE(list);
+WERROR _spoolss_EnumForms(pipes_struct *p,
+                         struct spoolss_EnumForms *r)
+{
+       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 */
+
+       if (!r->in.buffer && (r->in.offered != 0) ) {
+               return WERR_INVALID_PARAM;
+       }
+
+       DEBUG(4,("_spoolss_EnumForms\n"));
+       DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
+       DEBUGADD(5,("Info level [%d]\n",          r->in.level));
+
+       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 (num_user_forms + num_builtin_forms == 0) {
+               SAFE_FREE(builtin_forms);
+               SAFE_FREE(user_forms);
                return WERR_NO_MORE_ITEMS;
        }
 
-       switch (level) {
+       switch (r->in.level) {
        case 1:
-               if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
-                       SAFE_FREE(builtinlist);
-                       SAFE_FREE(list);
-                       *numofforms=0;
-                       return WERR_NOMEM;
-               }
+               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;
+       }
 
-               /* construct the list of form structures */
-               for (i=0; i<numbuiltinforms; i++) {
-                       DEBUGADD(6,("Filling form number [%d]\n",i));
-                       fill_form_1(&forms_1[i], &builtinlist[i]);
-               }
+       SAFE_FREE(user_forms);
+       SAFE_FREE(builtin_forms);
 
-               SAFE_FREE(builtinlist);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
-               for (; i<*numofforms; i++) {
-                       DEBUGADD(6,("Filling form number [%d]\n",i));
-                       fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
-               }
+       *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);
 
-               SAFE_FREE(list);
+       return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+}
 
-               /* check the required size. */
-               for (i=0; i<numbuiltinforms; i++) {
-                       DEBUGADD(6,("adding form [%d]'s size\n",i));
-                       buffer_size += spoolss_size_form_1(&forms_1[i]);
-               }
-               for (; i<*numofforms; i++) {
-                       DEBUGADD(6,("adding form [%d]'s size\n",i));
-                       buffer_size += spoolss_size_form_1(&forms_1[i]);
-               }
+/****************************************************************
+****************************************************************/
 
-               *needed=buffer_size;
+static WERROR find_form_byname(const char *name,
+                              nt_forms_struct *form)
+{
+       nt_forms_struct *list = NULL;
+       int num_forms = 0, i = 0;
 
-               if (*needed > offered) {
-                       SAFE_FREE(forms_1);
-                       *numofforms=0;
-                       return WERR_INSUFFICIENT_BUFFER;
-               }
+       if (get_a_builtin_ntform_by_string(name, form)) {
+               return WERR_OK;
+       }
 
-               if (!rpcbuf_alloc_size(buffer, buffer_size)){
-                       SAFE_FREE(forms_1);
-                       *numofforms=0;
-                       return WERR_NOMEM;
-               }
+       num_forms = get_ntforms(&list);
+       DEBUGADD(5,("Number of forms [%d]\n", num_forms));
 
-               /* fill the buffer with the form structures */
-               for (i=0; i<numbuiltinforms; i++) {
-                       DEBUGADD(6,("adding form [%d] to buffer\n",i));
-                       smb_io_form_1("", buffer, &forms_1[i], 0);
-               }
-               for (; i<*numofforms; i++) {
-                       DEBUGADD(6,("adding form [%d] to buffer\n",i));
-                       smb_io_form_1("", buffer, &forms_1[i], 0);
-               }
+       if (num_forms == 0) {
+               return WERR_BADFID;
+       }
 
-               SAFE_FREE(forms_1);
+       /* Check if the requested name is in the list of form structures */
+       for (i = 0; i < num_forms; i++) {
 
-               return WERR_OK;
+               DEBUG(4,("checking form %s (want %s)\n", list[i].name, name));
 
-       default:
-               SAFE_FREE(list);
-               SAFE_FREE(builtinlist);
-               return WERR_UNKNOWN_LEVEL;
+               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;
 }
 
 /****************************************************************
@@ -7400,94 +6800,60 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
 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);
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static void fill_port_1(PORT_INFO_1 *port, const char *name)
+static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
+                         struct spoolss_PortInfo1 *r,
+                         const char *name)
 {
-       init_unistr(&port->port_name, name);
+       r->port_name = talloc_strdup(mem_ctx, name);
+       W_ERROR_HAVE_NO_MEMORY(r->port_name);
+
+       return WERR_OK;
 }
 
 /****************************************************************************
@@ -7495,13 +6861,23 @@ static void fill_port_1(PORT_INFO_1 *port, const char *name)
  somehow.
 ****************************************************************************/
 
-static void fill_port_2(PORT_INFO_2 *port, const char *name)
+static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
+                         struct spoolss_PortInfo2 *r,
+                         const char *name)
 {
-       init_unistr(&port->port_name, name);
-       init_unistr(&port->monitor_name, "Local Monitor");
-       init_unistr(&port->description, SPL_LOCAL_PORT );
-       port->port_type=PORT_TYPE_WRITE;
-       port->reserved=0x0;
+       r->port_name = talloc_strdup(mem_ctx, name);
+       W_ERROR_HAVE_NO_MEMORY(r->port_name);
+
+       r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
+       W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
+
+       r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
+       W_ERROR_HAVE_NO_MEMORY(r->description);
+
+       r->port_type = SPOOLSS_PORT_TYPE_WRITE;
+       r->reserved = 0;
+
+       return WERR_OK;
 }
 
 
@@ -7569,9 +6945,11 @@ WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
  enumports level 1.
 ****************************************************************************/
 
-static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
+                               union spoolss_PortInfo **info_p,
+                               uint32_t *count)
 {
-       PORT_INFO_1 *ports=NULL;
+       union spoolss_PortInfo *info = NULL;
        int i=0;
        WERROR result = WERR_OK;
        char **qlines = NULL;
@@ -7579,161 +6957,140 @@ static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *need
 
        result = enumports_hook(talloc_tos(), &numlines, &qlines );
        if (!W_ERROR_IS_OK(result)) {
-               TALLOC_FREE(qlines);
-               return result;
+               goto out;
        }
 
-       if(numlines) {
-               if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
-                       DEBUG(10,("Returning WERR_NOMEM [%s]\n",
-                                 win_errstr(WERR_NOMEM)));
-                       TALLOC_FREE(qlines);
-                       return WERR_NOMEM;
+       if (numlines) {
+               info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
+               if (!info) {
+                       DEBUG(10,("Returning WERR_NOMEM\n"));
+                       result = WERR_NOMEM;
+                       goto out;
                }
 
                for (i=0; i<numlines; i++) {
                        DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
-                       fill_port_1(&ports[i], qlines[i]);
+                       result = fill_port_1(info, &info[i].info1, qlines[i]);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto out;
+                       }
                }
        }
        TALLOC_FREE(qlines);
 
-       *returned = numlines;
-
-       /* check the required size. */
-       for (i=0; i<*returned; i++) {
-               DEBUGADD(6,("adding port [%d]'s size\n", i));
-               *needed += spoolss_size_port_info_1(&ports[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 ports structures */
-       for (i=0; i<*returned; i++) {
-               DEBUGADD(6,("adding port [%d] to buffer\n", i));
-               smb_io_port_1("", buffer, &ports[i], 0);
-       }
-
 out:
-       SAFE_FREE(ports);
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               TALLOC_FREE(qlines);
+               *count = 0;
+               *info_p = NULL;
+               return result;
+       }
 
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+       *info_p = info;
+       *count = numlines;
 
-       return result;
+       return WERR_OK;
 }
 
 /****************************************************************************
  enumports level 2.
 ****************************************************************************/
 
-static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
+                               union spoolss_PortInfo **info_p,
+                               uint32_t *count)
 {
-       PORT_INFO_2 *ports=NULL;
+       union spoolss_PortInfo *info = NULL;
        int i=0;
        WERROR result = WERR_OK;
        char **qlines = NULL;
        int numlines = 0;
 
        result = enumports_hook(talloc_tos(), &numlines, &qlines );
-       if ( !W_ERROR_IS_OK(result)) {
-               TALLOC_FREE(qlines);
-               return result;
+       if (!W_ERROR_IS_OK(result)) {
+               goto out;
        }
 
-       if(numlines) {
-               if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
-                       TALLOC_FREE(qlines);
-                       return WERR_NOMEM;
+       if (numlines) {
+               info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
+               if (!info) {
+                       DEBUG(10,("Returning WERR_NOMEM\n"));
+                       result = WERR_NOMEM;
+                       goto out;
                }
 
                for (i=0; i<numlines; i++) {
                        DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
-                       fill_port_2(&(ports[i]), qlines[i]);
+                       result = fill_port_2(info, &info[i].info2, qlines[i]);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto out;
+                       }
                }
        }
-
        TALLOC_FREE(qlines);
 
-       *returned = numlines;
-
-       /* check the required size. */
-       for (i=0; i<*returned; i++) {
-               DEBUGADD(6,("adding port [%d]'s size\n", i));
-               *needed += spoolss_size_port_info_2(&ports[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 ports structures */
-       for (i=0; i<*returned; i++) {
-               DEBUGADD(6,("adding port [%d] to buffer\n", i));
-               smb_io_port_2("", buffer, &ports[i], 0);
-       }
-
 out:
-       SAFE_FREE(ports);
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               TALLOC_FREE(qlines);
+               *count = 0;
+               *info_p = NULL;
+               return result;
+       }
 
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+       *info_p = info;
+       *count = numlines;
 
-       return result;
+       return WERR_OK;
 }
 
-/****************************************************************************
- enumports.
-****************************************************************************/
+/****************************************************************
+ _spoolss_EnumPorts
+****************************************************************/
 
-WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
+WERROR _spoolss_EnumPorts(pipes_struct *p,
+                         struct spoolss_EnumPorts *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;
+       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_enumports\n"));
+       DEBUG(4,("_spoolss_EnumPorts\n"));
 
-       *returned=0;
-       *needed=0;
+       *r->out.count = 0;
+       *r->out.needed = 0;
+       *r->out.info = NULL;
 
-       switch (level) {
+       switch (r->in.level) {
        case 1:
-               return enumports_level_1(buffer, offered, needed, returned);
+               result = enumports_level_1(p->mem_ctx, r->out.info,
+                                          r->out.count);
+               break;
        case 2:
-               return enumports_level_2(buffer, offered, needed, returned);
+               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);
 }
 
 /****************************************************************************
@@ -7745,7 +7102,7 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
                                           struct spoolss_DeviceMode *devmode,
                                           struct security_descriptor *sec_desc,
                                           struct spoolss_UserLevelCtr *user_ctr,
-                                          POLICY_HND *handle)
+                                          struct policy_handle *handle)
 {
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        fstring name;
@@ -7758,7 +7115,7 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
        }
 
        /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
-       if (!convert_printer_info_new(info_ctr, printer)) {
+       if (!convert_printer_info(info_ctr, printer)) {
                free_a_printer(&printer, 2);
                return WERR_NOMEM;
        }
@@ -7831,10 +7188,10 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
                */
                DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
 
-               if (!convert_devicemode_new(printer->info_2->printername,
-                                           devmode,
-                                           &printer->info_2->devmode))
+               if (!convert_devicemode(printer->info_2->printername, devmode,
+                                       &printer->info_2->devmode)) {
                        return  WERR_NOMEM;
+               }
        }
 
        /* write the ASCII on disk */
@@ -8138,9 +7495,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;
@@ -8158,13 +7513,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;
 }
 
@@ -8193,39 +7541,28 @@ 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);
 }
 
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_EnumPrinterData
+****************************************************************/
 
-WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
+WERROR _spoolss_EnumPrinterData(pipes_struct *p,
+                               struct spoolss_EnumPrinterData *r)
 {
-       POLICY_HND *handle = &q_u->handle;
-       uint32 idx               = q_u->index;
-       uint32 in_value_len      = q_u->valuesize;
-       uint32 in_data_len       = q_u->datasize;
-       uint32 *out_max_value_len = &r_u->valuesize;
-       uint16 **out_value       = &r_u->value;
-       uint32 *out_value_len    = &r_u->realvaluesize;
-       uint32 *out_type         = &r_u->type;
-       uint32 *out_max_data_len = &r_u->datasize;
-       uint8  **data_out        = &r_u->data;
-       uint32 *out_data_len     = &r_u->realdatasize;
-
        NT_PRINTER_INFO_LEVEL *printer = NULL;
-
-       uint32          biggest_valuesize;
-       uint32          biggest_datasize;
-       uint32          data_len;
-       Printer_entry   *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
        int             snum;
        WERROR          result;
        REGISTRY_VALUE  *val = NULL;
@@ -8233,25 +7570,26 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
        int             i, key_index, num_values;
        int             name_length;
 
-       *out_type = 0;
+       *r->out.value_needed    = 0;
+       *r->out.type            = REG_NONE;
+       *r->out.data_needed     = 0;
 
-       *out_max_data_len = 0;
-       *data_out         = NULL;
-       *out_data_len     = 0;
-
-       DEBUG(5,("spoolss_enumprinterdata\n"));
+       DEBUG(5,("_spoolss_EnumPrinterData\n"));
 
        if (!Printer) {
-               DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+               DEBUG(2,("_spoolss_EnumPrinterData: Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p,handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
        result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
-       if (!W_ERROR_IS_OK(result))
+       if (!W_ERROR_IS_OK(result)) {
                return result;
+       }
 
        p_data = printer->info_2->data;
        key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
@@ -8264,12 +7602,12 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
         * cf: MSDN EnumPrinterData remark section
         */
 
-       if ( !in_value_len && !in_data_len && (key_index != -1) )
-       {
-               DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
+       if (!r->in.value_offered && !r->in.data_offered && (key_index != -1)) {
+
+               uint32_t biggest_valuesize = 0;
+               uint32_t biggest_datasize = 0;
 
-               biggest_valuesize = 0;
-               biggest_datasize  = 0;
+               DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
 
                num_values = regval_ctr_numvals( p_data->keys[key_index].values );
 
@@ -8291,10 +7629,11 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
                /* the value is an UNICODE string but real_value_size is the length
                   in bytes including the trailing 0 */
 
-               *out_value_len = 2 * (1+biggest_valuesize);
-               *out_data_len  = biggest_datasize;
+               *r->out.value_needed = 2 * (1 + biggest_valuesize);
+               *r->out.data_needed  = biggest_datasize;
 
-               DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
+               DEBUG(6,("final values: [%d], [%d]\n",
+                       *r->out.value_needed, *r->out.data_needed));
 
                goto done;
        }
@@ -8304,46 +7643,34 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
         * that's the number of bytes not the number of unicode chars
         */
 
-       if ( key_index != -1 )
-               val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
+       if (key_index != -1) {
+               val = regval_ctr_specific_value(p_data->keys[key_index].values,
+                                               r->in.enum_index);
+       }
 
-       if ( !val )
-       {
+       if (!val) {
 
                /* out_value should default to "" or else NT4 has
                   problems unmarshalling the response */
 
-               *out_max_value_len=(in_value_len/sizeof(uint16));
-
-               if (in_value_len) {
-                       if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
-                       {
+               if (r->in.value_offered) {
+                       *r->out.value_needed = 1;
+                       r->out.value_name = talloc_strdup(r, "");
+                       if (!r->out.value_name) {
                                result = WERR_NOMEM;
                                goto done;
                        }
-                       *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
                } else {
-                       *out_value=NULL;
-                       *out_value_len = 0;
+                       r->out.value_name = NULL;
+                       *r->out.value_needed = 0;
                }
 
                /* the data is counted in bytes */
 
-               *out_max_data_len = in_data_len;
-               *out_data_len     = in_data_len;
-
-               /* only allocate when given a non-zero data_len */
-
-               if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
-               {
-                       result = WERR_NOMEM;
-                       goto done;
-               }
+               *r->out.data_needed = r->in.data_offered;
 
                result = WERR_NO_MORE_ITEMS;
-       }
-       else
-       {
+       } else {
                /*
                 * the value is:
                 * - counted in bytes in the request
@@ -8354,36 +7681,29 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
                 */
 
                /* name */
-               *out_max_value_len=(in_value_len/sizeof(uint16));
-               if (in_value_len) {
-                       if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
-                       {
+               if (r->in.value_offered) {
+                       r->out.value_name = talloc_strdup(r, regval_name(val));
+                       if (!r->out.value_name) {
                                result = WERR_NOMEM;
                                goto done;
                        }
-
-                       *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
+                       *r->out.value_needed = strlen_m(regval_name(val));
                } else {
-                       *out_value = NULL;
-                       *out_value_len = 0;
+                       r->out.value_name = NULL;
+                       *r->out.value_needed = 0;
                }
 
                /* type */
 
-               *out_type = regval_type( val );
+               *r->out.type = regval_type(val);
 
                /* data - counted in bytes */
 
-               *out_max_data_len = in_data_len;
-               if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
-               {
-                       result = WERR_NOMEM;
-                       goto done;
+               if (r->out.data && regval_size(val)) {
+                       memcpy(r->out.data, regval_data_p(val), regval_size(val));
                }
-               data_len = regval_size(val);
-               if ( *data_out && data_len )
-                       memcpy( *data_out, regval_data_p(val), data_len );
-               *out_data_len = data_len;
+
+               *r->out.data_needed = regval_size(val);
        }
 
 done:
@@ -8391,37 +7711,36 @@ done:
        return result;
 }
 
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_SetPrinterData
+****************************************************************/
 
-WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
+WERROR _spoolss_SetPrinterData(pipes_struct *p,
+                              struct spoolss_SetPrinterData *r)
 {
-       POLICY_HND              *handle = &q_u->handle;
-       UNISTR2                 *value = &q_u->value;
-       uint32                  type = q_u->type;
-       uint8                   *data = q_u->data;
-       uint32                  real_len = q_u->real_len;
-
-       NT_PRINTER_INFO_LEVEL   *printer = NULL;
-       int                     snum=0;
-       WERROR                  status = WERR_OK;
-       Printer_entry           *Printer=find_printer_index_by_hnd(p, handle);
-       fstring                 valuename;
+       NT_PRINTER_INFO_LEVEL *printer = NULL;
+       int snum=0;
+       WERROR result = WERR_OK;
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
+       DATA_BLOB blob;
 
-       DEBUG(5,("spoolss_setprinterdata\n"));
+       DEBUG(5,("_spoolss_SetPrinterData\n"));
 
        if (!Printer) {
-               DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+               DEBUG(2,("_spoolss_SetPrinterData: Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
-       if ( Printer->printer_type == SPLHND_SERVER ) {
-               DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
+       if (Printer->printer_type == SPLHND_SERVER) {
+               DEBUG(10,("_spoolss_SetPrinterData: "
+                       "Not implemented for server handles yet\n"));
                return WERR_INVALID_PARAM;
        }
 
-       if (!get_printer_snum(p,handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
        /*
         * Access check : NT returns "access denied" if you make a
@@ -8431,43 +7750,49 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
         * when connecting to a printer  --jerry
         */
 
-       if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
-       {
-               DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
-               status = WERR_ACCESS_DENIED;
+       if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
+               DEBUG(3,("_spoolss_SetPrinterData: "
+                       "change denied by handle access permissions\n"));
+               result = WERR_ACCESS_DENIED;
                goto done;
        }
 
-       status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
-       if (!W_ERROR_IS_OK(status))
-               return status;
+       result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
-       unistr2_to_ascii(valuename, value, sizeof(valuename));
+       result = push_spoolss_PrinterData(p->mem_ctx, &blob,
+                                         r->in.type, &r->in.data);
+       if (!W_ERROR_IS_OK(result)) {
+               goto done;
+       }
 
        /*
         * When client side code sets a magic printer data key, detect it and save
         * the current printer data and the magic key's data (its the DEVMODE) for
         * future printer/driver initializations.
         */
-       if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
-       {
+       if ((r->in.type == REG_BINARY) && strequal(r->in.value_name, PHANTOM_DEVMODE_KEY)) {
                /* Set devmode and printer initialization info */
-               status = save_driver_init( printer, 2, data, real_len );
+               result = save_driver_init(printer, 2, blob.data, blob.length);
 
-               srv_spoolss_reset_printerdata( printer->info_2->drivername );
+               srv_spoolss_reset_printerdata(printer->info_2->drivername);
+
+               goto done;
        }
-       else
-       {
-       status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
-                                       type, data, real_len );
-               if ( W_ERROR_IS_OK(status) )
-                       status = mod_a_printer(printer, 2);
+
+       result = set_printer_dataex(printer, SPOOL_PRINTERDATA_KEY,
+                                   r->in.value_name, r->in.type,
+                                   blob.data, blob.length);
+       if (W_ERROR_IS_OK(result)) {
+               result = mod_a_printer(printer, 2);
        }
 
 done:
        free_a_printer(&printer, 2);
 
-       return status;
+       return result;
 }
 
 /****************************************************************
@@ -8477,8 +7802,7 @@ done:
 WERROR _spoolss_ResetPrinter(pipes_struct *p,
                             struct spoolss_ResetPrinter *r)
 {
-       POLICY_HND      *handle = r->in.handle;
-       Printer_entry   *Printer=find_printer_index_by_hnd(p, handle);
+       Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
        int             snum;
 
        DEBUG(5,("_spoolss_ResetPrinter\n"));
@@ -8491,11 +7815,11 @@ WERROR _spoolss_ResetPrinter(pipes_struct *p,
 
        if (!Printer) {
                DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
-                       OUR_HANDLE(handle)));
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p,handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL))
                return WERR_BADFID;
 
 
@@ -8510,21 +7834,20 @@ WERROR _spoolss_ResetPrinter(pipes_struct *p,
 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
                                  struct spoolss_DeletePrinterData *r)
 {
-       POLICY_HND      *handle = r->in.handle;
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
        int             snum=0;
        WERROR          status = WERR_OK;
-       Printer_entry   *Printer=find_printer_index_by_hnd(p, handle);
+       Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
        DEBUG(5,("_spoolss_DeletePrinterData\n"));
 
        if (!Printer) {
                DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
-                       OUR_HANDLE(handle)));
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p, handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL))
                return WERR_BADFID;
 
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
@@ -8560,7 +7883,6 @@ WERROR _spoolss_DeletePrinterData(pipes_struct *p,
 WERROR _spoolss_AddForm(pipes_struct *p,
                        struct spoolss_AddForm *r)
 {
-       POLICY_HND *handle = r->in.handle;
        struct spoolss_AddFormInfo1 *form = r->in.info.info1;
        nt_forms_struct tmpForm;
        int snum;
@@ -8569,13 +7891,13 @@ WERROR _spoolss_AddForm(pipes_struct *p,
 
        int count=0;
        nt_forms_struct *list=NULL;
-       Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
        DEBUG(5,("_spoolss_AddForm\n"));
 
        if (!Printer) {
                DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
-                       OUR_HANDLE(handle)));
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
@@ -8584,7 +7906,7 @@ WERROR _spoolss_AddForm(pipes_struct *p,
 
        if ( Printer->printer_type == SPLHND_PRINTER )
        {
-               if (!get_printer_snum(p,handle, &snum, NULL))
+               if (!get_printer_snum(p, r->in.handle, &snum, NULL))
                        return WERR_BADFID;
 
                status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
@@ -8636,12 +7958,11 @@ done:
 WERROR _spoolss_DeleteForm(pipes_struct *p,
                           struct spoolss_DeleteForm *r)
 {
-       POLICY_HND *handle = r->in.handle;
        const char *form_name = r->in.form_name;
        nt_forms_struct tmpForm;
        int count=0;
        nt_forms_struct *list=NULL;
-       Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
        int snum;
        WERROR status = WERR_OK;
        NT_PRINTER_INFO_LEVEL *printer = NULL;
@@ -8650,7 +7971,7 @@ WERROR _spoolss_DeleteForm(pipes_struct *p,
 
        if (!Printer) {
                DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
-                       OUR_HANDLE(handle)));
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
@@ -8658,7 +7979,7 @@ WERROR _spoolss_DeleteForm(pipes_struct *p,
 
        if ( Printer->printer_type == SPLHND_PRINTER )
        {
-               if (!get_printer_snum(p,handle, &snum, NULL))
+               if (!get_printer_snum(p, r->in.handle, &snum, NULL))
                        return WERR_BADFID;
 
                status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
@@ -8706,7 +8027,6 @@ done:
 WERROR _spoolss_SetForm(pipes_struct *p,
                        struct spoolss_SetForm *r)
 {
-       POLICY_HND *handle = r->in.handle;
        struct spoolss_AddFormInfo1 *form = r->in.info.info1;
        nt_forms_struct tmpForm;
        int snum;
@@ -8715,13 +8035,13 @@ WERROR _spoolss_SetForm(pipes_struct *p,
 
        int count=0;
        nt_forms_struct *list=NULL;
-       Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
        DEBUG(5,("_spoolss_SetForm\n"));
 
        if (!Printer) {
                DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
-                       OUR_HANDLE(handle)));
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
@@ -8729,7 +8049,7 @@ WERROR _spoolss_SetForm(pipes_struct *p,
 
        if ( Printer->printer_type == SPLHND_PRINTER )
        {
-               if (!get_printer_snum(p,handle, &snum, NULL))
+               if (!get_printer_snum(p, r->in.handle, &snum, NULL))
                        return WERR_BADFID;
 
                status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
@@ -8770,69 +8090,68 @@ done:
 }
 
 /****************************************************************************
- enumprintprocessors level 1.
+ fill_print_processor1
 ****************************************************************************/
 
-static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
+                                   struct spoolss_PrintProcessorInfo1 *r,
+                                   const char *print_processor_name)
 {
-       PRINTPROCESSOR_1 *info_1=NULL;
-       WERROR result = WERR_OK;
+       r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
+       W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
 
-       if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
-               return WERR_NOMEM;
+       return WERR_OK;
+}
+
+/****************************************************************************
+ enumprintprocessors level 1.
+****************************************************************************/
 
-       (*returned) = 0x1;
+static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
+                                         union spoolss_PrintProcessorInfo **info_p,
+                                         uint32_t *count)
+{
+       union spoolss_PrintProcessorInfo *info;
+       WERROR result;
 
-       init_unistr(&info_1->name, "winprint");
+       info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
+       W_ERROR_HAVE_NO_MEMORY(info);
 
-       *needed += spoolss_size_printprocessor_info_1(info_1);
+       *count = 1;
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
+       result = fill_print_processor1(info, &info[0].info1, "winprint");
+       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;
        }
 
-       smb_io_printprocessor_info_1("", buffer, info_1, 0);
-
-out:
-       SAFE_FREE(info_1);
-
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+       *info_p = info;
 
-       return result;
+       return WERR_OK;
 }
 
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_EnumPrintProcessors
+****************************************************************/
 
-WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
+WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
+                                   struct spoolss_EnumPrintProcessors *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;
+       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(5,("spoolss_enumprintprocessors\n"));
+       DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
 
        /*
         * Enumerate the print processors ...
@@ -8841,213 +8160,254 @@ WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS
         * and I can use my nice printer checker.
         */
 
-       *returned=0;
-       *needed=0;
+       *r->out.count = 0;
+       *r->out.needed = 0;
+       *r->out.info = NULL;
 
-       switch (level) {
+       switch (r->in.level) {
        case 1:
-               return enumprintprocessors_level_1(buffer, offered, needed, returned);
+               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);
 }
 
 /****************************************************************************
- enumprintprocdatatypes level 1.
+ fill_printprocdatatype1
 ****************************************************************************/
 
-static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
+                                     struct spoolss_PrintProcDataTypesInfo1 *r,
+                                     const char *name_array)
 {
-       PRINTPROCDATATYPE_1 *info_1=NULL;
-       WERROR result = WERR_OK;
+       r->name_array = talloc_strdup(mem_ctx, name_array);
+       W_ERROR_HAVE_NO_MEMORY(r->name_array);
 
-       if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
-               return WERR_NOMEM;
+       return WERR_OK;
+}
+
+/****************************************************************************
+ enumprintprocdatatypes level 1.
+****************************************************************************/
 
-       (*returned) = 0x1;
+static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
+                                            union spoolss_PrintProcDataTypesInfo **info_p,
+                                            uint32_t *count)
+{
+       WERROR result;
+       union spoolss_PrintProcDataTypesInfo *info;
 
-       init_unistr(&info_1->name, "RAW");
+       info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
+       W_ERROR_HAVE_NO_MEMORY(info);
 
-       *needed += spoolss_size_printprocdatatype_info_1(info_1);
+       *count = 1;
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
+       result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
+       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;
+       }
+
+       *info_p = info;
+
+       return WERR_OK;
+}
+
+/****************************************************************
+ _spoolss_EnumPrintProcDataTypes
+****************************************************************/
+
+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)) {
+               return WERR_INVALID_PARAM;
        }
 
-       smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
+       DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
 
-out:
-       SAFE_FREE(info_1);
+       *r->out.count = 0;
+       *r->out.needed = 0;
+       *r->out.info = NULL;
+
+       switch (r->in.level) {
+       case 1:
+               result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
+                                                       r->out.count);
+               break;
+       default:
+               return WERR_UNKNOWN_LEVEL;
+       }
 
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+       *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 result;
+       return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 }
 
 /****************************************************************************
+ fill_monitor_1
 ****************************************************************************/
 
-WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
+static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
+                            struct spoolss_MonitorInfo1 *r,
+                            const char *monitor_name)
 {
-       uint32 level = q_u->level;
-       RPC_BUFFER *buffer = NULL;
-       uint32 offered = q_u->offered;
-       uint32 *needed = &r_u->needed;
-       uint32 *returned = &r_u->returned;
-
-       /* that's an [in out] buffer */
-
-       if (!q_u->buffer && (offered!=0)) {
-               return WERR_INVALID_PARAM;
-       }
-
-       if (offered > MAX_RPC_DATA_SIZE) {
-               return WERR_INVALID_PARAM;
-       }
+       r->monitor_name                 = talloc_strdup(mem_ctx, monitor_name);
+       W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
 
-       rpcbuf_move(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+       return WERR_OK;
+}
 
-       DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
+/****************************************************************************
+ fill_monitor_2
+****************************************************************************/
 
-       *returned=0;
-       *needed=0;
+static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
+                            struct spoolss_MonitorInfo2 *r,
+                            const char *monitor_name,
+                            const char *environment,
+                            const char *dll_name)
+{
+       r->monitor_name                 = talloc_strdup(mem_ctx, monitor_name);
+       W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
+       r->environment                  = talloc_strdup(mem_ctx, environment);
+       W_ERROR_HAVE_NO_MEMORY(r->environment);
+       r->dll_name                     = talloc_strdup(mem_ctx, dll_name);
+       W_ERROR_HAVE_NO_MEMORY(r->dll_name);
 
-       switch (level) {
-       case 1:
-               return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
-       default:
-               return WERR_UNKNOWN_LEVEL;
-       }
+       return WERR_OK;
 }
 
 /****************************************************************************
  enumprintmonitors level 1.
 ****************************************************************************/
 
-static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
+                                       union spoolss_MonitorInfo **info_p,
+                                       uint32_t *count)
 {
-       PRINTMONITOR_1 *info_1;
+       union spoolss_MonitorInfo *info;
        WERROR result = WERR_OK;
-       int i;
-
-       if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
-               return WERR_NOMEM;
-
-       *returned = 2;
 
-       init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
-       init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
+       info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
+       W_ERROR_HAVE_NO_MEMORY(info);
 
-       for ( i=0; i<*returned; i++ ) {
-               *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
-       }
+       *count = 2;
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
+       result = fill_monitor_1(info, &info[0].info1,
+                               SPL_LOCAL_PORT);
+       if (!W_ERROR_IS_OK(result)) {
                goto out;
        }
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
+       result = fill_monitor_1(info, &info[1].info1,
+                               SPL_TCPIP_PORT);
+       if (!W_ERROR_IS_OK(result)) {
                goto out;
        }
 
-       for ( i=0; i<*returned; i++ ) {
-               smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
-       }
-
 out:
-       SAFE_FREE(info_1);
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
+       }
 
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+       *info_p = info;
 
-       return result;
+       return WERR_OK;
 }
 
 /****************************************************************************
  enumprintmonitors level 2.
 ****************************************************************************/
 
-static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
+                                       union spoolss_MonitorInfo **info_p,
+                                       uint32_t *count)
 {
-       PRINTMONITOR_2 *info_2;
+       union spoolss_MonitorInfo *info;
        WERROR result = WERR_OK;
-       int i;
 
-       if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
-               return WERR_NOMEM;
-
-       *returned = 2;
-
-       init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
-       init_unistr( &(info_2[0].environment), "Windows NT X86" );
-       init_unistr( &(info_2[0].dll_name), "localmon.dll" );
-
-       init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
-       init_unistr( &(info_2[1].environment), "Windows NT X86" );
-       init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
+       info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
+       W_ERROR_HAVE_NO_MEMORY(info);
 
-       for ( i=0; i<*returned; i++ ) {
-               *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
-       }
+       *count = 2;
 
-       if (*needed > offered) {
-               result = WERR_INSUFFICIENT_BUFFER;
+       result = fill_monitor_2(info, &info[0].info2,
+                               SPL_LOCAL_PORT,
+                               "Windows NT X86", /* FIXME */
+                               "localmon.dll");
+       if (!W_ERROR_IS_OK(result)) {
                goto out;
        }
 
-       if (!rpcbuf_alloc_size(buffer, *needed)) {
-               result = WERR_NOMEM;
+       result = fill_monitor_2(info, &info[1].info2,
+                               SPL_TCPIP_PORT,
+                               "Windows NT X86", /* FIXME */
+                               "tcpmon.dll");
+       if (!W_ERROR_IS_OK(result)) {
                goto out;
        }
 
-       for ( i=0; i<*returned; i++ ) {
-               smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
-       }
-
 out:
-       SAFE_FREE(info_2);
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
+       }
 
-       if ( !W_ERROR_IS_OK(result) )
-               *returned = 0;
+       *info_p = info;
 
-       return result;
+       return WERR_OK;
 }
 
-/****************************************************************************
-****************************************************************************/
+/****************************************************************
+ _spoolss_EnumMonitors
+****************************************************************/
 
-WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
+WERROR _spoolss_EnumMonitors(pipes_struct *p,
+                            struct spoolss_EnumMonitors *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;
+       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(5,("spoolss_enumprintmonitors\n"));
+       DEBUG(5,("_spoolss_EnumMonitors\n"));
 
        /*
         * Enumerate the print monitors ...
@@ -9056,102 +8416,95 @@ WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_
         * and I can use my nice printer checker.
         */
 
-       *returned=0;
-       *needed=0;
+       *r->out.count = 0;
+       *r->out.needed = 0;
+       *r->out.info = NULL;
 
-       switch (level) {
+       switch (r->in.level) {
        case 1:
-               return enumprintmonitors_level_1(buffer, offered, needed, returned);
+               result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
+                                                  r->out.count);
+               break;
        case 2:
-               return enumprintmonitors_level_2(buffer, offered, needed, returned);
+               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);
-
-       if (info_1 == NULL) {
-               return WERR_NOMEM;
-       }
+       int i = 0;
+       bool found = false;
 
-       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;
        }
 
        /*
@@ -9160,54 +8513,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(devmode, devmode, nt_devmode);
+               if (!W_ERROR_IS_OK(result)) {
+                       return result;
                }
+       } else {
+               devmode = construct_dev_mode(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;
@@ -9216,51 +8551,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);
+
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(r->out.info);
+               return result;
+       }
 
-       return wstatus;
+       *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);
 }
 
 /****************************************************************
@@ -9273,31 +8614,27 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
                                 struct spoolss_GetPrinterDataEx *r)
 {
-       POLICY_HND      *handle = r->in.handle;
-       uint8           *data = NULL;
-       const char      *keyname = r->in.key_name;
-       const char      *valuename = r->in.value_name;
-
-       Printer_entry   *Printer = find_printer_index_by_hnd(p, handle);
 
+       Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
+       REGISTRY_VALUE          *val = NULL;
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
        int                     snum = 0;
-       WERROR                  status = WERR_OK;
+       WERROR result = WERR_OK;
 
        DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
 
        DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
-               keyname, valuename));
+               r->in.key_name, r->in.value_name));
 
        /* in case of problem, return some default values */
 
        *r->out.needed  = 0;
-       *r->out.type    = 0;
+       *r->out.type    = REG_NONE;
 
        if (!Printer) {
-               DEBUG(2,("_spoolss_GetPrinterDataEx: "
-                       "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
-               status = WERR_BADFID;
+               DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
+               result = WERR_BADFID;
                goto done;
        }
 
@@ -9306,50 +8643,58 @@ WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
        if (Printer->printer_type == SPLHND_SERVER) {
                DEBUG(10,("_spoolss_GetPrinterDataEx: "
                        "Not implemented for server handles yet\n"));
-               status = WERR_INVALID_PARAM;
+               result = WERR_INVALID_PARAM;
                goto done;
        }
 
-       if ( !get_printer_snum(p,handle, &snum, NULL) )
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
-       status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
-       if ( !W_ERROR_IS_OK(status) )
+       result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
+       if (!W_ERROR_IS_OK(result)) {
                goto done;
+       }
 
        /* check to see if the keyname is valid */
-       if ( !strlen(keyname) ) {
-               status = WERR_INVALID_PARAM;
+       if (!strlen(r->in.key_name)) {
+               result = WERR_INVALID_PARAM;
                goto done;
        }
 
-       if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
+       if (lookup_printerkey(printer->info_2->data, r->in.key_name) == -1) {
                DEBUG(4,("_spoolss_GetPrinterDataEx: "
-                       "Invalid keyname [%s]\n", keyname ));
-               free_a_printer( &printer, 2 );
-               status = WERR_BADFILE;
+                       "Invalid keyname [%s]\n", r->in.key_name ));
+               result = WERR_BADFILE;
                goto done;
        }
 
        /* When given a new keyname, we should just create it */
 
-       status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
-                                    r->out.type, &data, r->out.needed,
-                                    r->in.offered );
+       val = get_printer_data(printer->info_2,
+                              r->in.key_name, r->in.value_name);
+       if (!val) {
+               result = WERR_BADFILE;
+               goto done;
+       }
+
+       *r->out.needed = regval_size(val);
 
        if (*r->out.needed > r->in.offered) {
-               status = WERR_MORE_DATA;
+               result = WERR_MORE_DATA;
+               goto done;
        }
 
-       if (W_ERROR_IS_OK(status)) {
-               memcpy(r->out.buffer, data, r->in.offered);
-       }
+       *r->out.type = regval_type(val);
 
-done:
-       if ( printer )
-       free_a_printer( &printer, 2 );
+       memcpy(r->out.buffer, regval_data_p(val), regval_size(val));
 
-       return status;
+ done:
+       if (printer) {
+               free_a_printer(&printer, 2);
+       }
+
+       return result;
 }
 
 /****************************************************************
@@ -9359,11 +8704,10 @@ done:
 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
                                 struct spoolss_SetPrinterDataEx *r)
 {
-       POLICY_HND              *handle = r->in.handle;
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
        int                     snum = 0;
-       WERROR                  status = WERR_OK;
-       Printer_entry           *Printer = find_printer_index_by_hnd(p, handle);
+       WERROR                  result = WERR_OK;
+       Printer_entry           *Printer = find_printer_index_by_hnd(p, r->in.handle);
        char                    *oid_string;
 
        DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
@@ -9372,19 +8716,20 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
            SetPrinterData if key is "PrinterDriverData" */
 
        if (!Printer) {
-               DEBUG(2,("_spoolss_SetPrinterDataEx: "
-                       "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+               DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
-       if ( Printer->printer_type == SPLHND_SERVER ) {
+       if (Printer->printer_type == SPLHND_SERVER) {
                DEBUG(10,("_spoolss_SetPrinterDataEx: "
                        "Not implemented for server handles yet\n"));
                return WERR_INVALID_PARAM;
        }
 
-       if ( !get_printer_snum(p,handle, &snum, NULL) )
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
        /*
         * Access check : NT returns "access denied" if you make a
@@ -9394,38 +8739,38 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
         * when connecting to a printer  --jerry
         */
 
-       if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
-       {
+       if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
                DEBUG(3, ("_spoolss_SetPrinterDataEx: "
                        "change denied by handle access permissions\n"));
                return WERR_ACCESS_DENIED;
        }
 
-       status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
-       if (!W_ERROR_IS_OK(status))
-               return status;
+       result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
        /* check for OID in valuename */
 
-       if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
-       {
+       oid_string = strchr(r->in.value_name, ',');
+       if (oid_string) {
                *oid_string = '\0';
                oid_string++;
        }
 
        /* save the registry data */
 
-       status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
-                                    r->in.type, r->in.buffer, r->in.offered );
+       result = set_printer_dataex(printer, r->in.key_name, r->in.value_name,
+                                   r->in.type, r->in.buffer, r->in.offered);
 
-       if ( W_ERROR_IS_OK(status) )
-       {
+       if (W_ERROR_IS_OK(result)) {
                /* save the OID if one was specified */
-               if ( oid_string ) {
+               if (oid_string) {
                        char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
                                r->in.key_name, SPOOL_OID_KEY);
                        if (!str) {
-                               return WERR_NOMEM;
+                               result = WERR_NOMEM;
+                               goto done;
                        }
 
                        /*
@@ -9435,17 +8780,18 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
                         * this is right.    --jerry
                         */
 
-                       set_printer_dataex( printer, str, r->in.value_name,
-                                           REG_SZ, (uint8 *)oid_string,
-                                           strlen(oid_string)+1 );
+                       set_printer_dataex(printer, str, r->in.value_name,
+                                          REG_SZ, (uint8_t *)oid_string,
+                                          strlen(oid_string)+1);
                }
 
-               status = mod_a_printer(printer, 2);
+               result = mod_a_printer(printer, 2);
        }
 
+ done:
        free_a_printer(&printer, 2);
 
-       return status;
+       return result;
 }
 
 /****************************************************************
@@ -9455,21 +8801,21 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
                                    struct spoolss_DeletePrinterDataEx *r)
 {
-       POLICY_HND      *handle = r->in.handle;
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
        int             snum=0;
        WERROR          status = WERR_OK;
-       Printer_entry   *Printer=find_printer_index_by_hnd(p, handle);
+       Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
        DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
 
        if (!Printer) {
                DEBUG(2,("_spoolss_DeletePrinterDataEx: "
-                       "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+                       "Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p, handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL))
                return WERR_BADFID;
 
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
@@ -9496,76 +8842,88 @@ WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
        return status;
 }
 
-/********************************************************************
- * spoolss_enumprinterkey
- ********************************************************************/
-
+/****************************************************************
+ _spoolss_EnumPrinterKey
+****************************************************************/
 
-WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
+WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
+                              struct spoolss_EnumPrinterKey *r)
 {
-       fstring         key;
        fstring         *keynames = NULL;
-       uint16          *enumkeys = NULL;
        int             num_keys;
-       int             printerkey_len;
-       POLICY_HND      *handle = &q_u->handle;
-       Printer_entry   *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
        NT_PRINTER_DATA *data;
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
        int             snum = 0;
-       WERROR          status = WERR_BADFILE;
+       WERROR          result = WERR_BADFILE;
+       int i;
+       const char **array = NULL;
 
 
-       DEBUG(4,("_spoolss_enumprinterkey\n"));
+       DEBUG(4,("_spoolss_EnumPrinterKey\n"));
 
        if (!Printer) {
-               DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+               DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
-       if ( !get_printer_snum(p,handle, &snum, NULL) )
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
-       status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
-       if (!W_ERROR_IS_OK(status))
-               return status;
+       result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
        /* get the list of subkey names */
 
-       unistr2_to_ascii(key, &q_u->key, sizeof(key));
        data = printer->info_2->data;
 
-       num_keys = get_printer_subkeys( data, key, &keynames );
-
-       if ( num_keys == -1 ) {
-               status = WERR_BADFILE;
+       num_keys = get_printer_subkeys(data, r->in.key_name, &keynames);
+       if (num_keys == -1) {
+               result = WERR_BADFILE;
                goto done;
        }
 
-       printerkey_len = init_unistr_array( &enumkeys,  keynames, NULL );
+       *r->out.needed = 4;
 
-       r_u->needed = printerkey_len*2;
-
-       if ( q_u->size < r_u->needed ) {
-               status = WERR_MORE_DATA;
+       array = talloc_zero_array(r->out.key_buffer, const char *, num_keys + 1);
+       if (!array) {
+               result = WERR_NOMEM;
                goto done;
        }
 
-       if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
-               status = WERR_NOMEM;
+       for (i=0; i < num_keys; i++) {
+               array[i] = talloc_strdup(array, keynames[i]);
+               if (!array[i]) {
+                       result = WERR_NOMEM;
+                       goto done;
+               }
+
+               *r->out.needed += strlen_m_term(keynames[i]) * 2;
+       }
+
+       if (r->in.offered < *r->out.needed) {
+               result = WERR_MORE_DATA;
                goto done;
        }
 
-       status = WERR_OK;
+       result = WERR_OK;
 
-       if ( q_u->size < r_u->needed )
-               status = WERR_MORE_DATA;
+       *r->out.key_buffer = array;
 
-done:
-       free_a_printer( &printer, 2 );
-       SAFE_FREE( keynames );
+ done:
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(array);
+               ZERO_STRUCTP(r->out.key_buffer);
+       }
+
+       free_a_printer(&printer, 2);
+       SAFE_FREE(keynames);
 
-        return status;
+       return result;
 }
 
 /****************************************************************
@@ -9575,8 +8933,7 @@ done:
 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
                                 struct spoolss_DeletePrinterKey *r)
 {
-       POLICY_HND              *handle = r->in.handle;
-       Printer_entry           *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry           *Printer = find_printer_index_by_hnd(p, r->in.handle);
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
        int                     snum=0;
        WERROR                  status;
@@ -9585,7 +8942,7 @@ WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
 
        if (!Printer) {
                DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
-                       OUR_HANDLE(handle)));
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
@@ -9594,7 +8951,7 @@ WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
        if ( !r->in.key_name )
                return WERR_INVALID_PARAM;
 
-       if (!get_printer_snum(p, handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL))
                return WERR_BADFID;
 
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
@@ -9619,35 +8976,64 @@ WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
        return status;
 }
 
+/****************************************************************
+****************************************************************/
 
-/********************************************************************
- * spoolss_enumprinterdataex
- ********************************************************************/
+static WERROR registry_value_to_printer_enum_value(TALLOC_CTX *mem_ctx,
+                                                  REGISTRY_VALUE *v,
+                                                  struct spoolss_PrinterEnumValues *r)
+{
+       WERROR result;
+
+       r->data = TALLOC_ZERO_P(mem_ctx, union spoolss_PrinterData);
+       W_ERROR_HAVE_NO_MEMORY(r->data);
+
+       r->value_name   = talloc_strdup(mem_ctx, regval_name(v));
+       W_ERROR_HAVE_NO_MEMORY(r->value_name);
+
+       r->type         = regval_type(v);
+       r->data_length  = regval_size(v);
+
+       if (r->data_length) {
+               DATA_BLOB blob = data_blob_const(regval_data_p(v),
+                                                regval_size(v));
+               result = pull_spoolss_PrinterData(mem_ctx, &blob,
+                                                 r->data,
+                                                 r->type);
+               if (!W_ERROR_IS_OK(result)) {
+                       return result;
+               }
+       }
+
+       return WERR_OK;
+}
+
+/****************************************************************
+ _spoolss_EnumPrinterDataEx
+****************************************************************/
 
-WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
+WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
+                                 struct spoolss_EnumPrinterDataEx *r)
 {
-       POLICY_HND      *handle = &q_u->handle;
-       uint32          in_size = q_u->size;
-       uint32          num_entries,
-                       needed;
+       uint32_t        count = 0;
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
-       PRINTER_ENUM_VALUES     *enum_values = NULL;
+       struct spoolss_PrinterEnumValues *info = NULL;
        NT_PRINTER_DATA         *p_data;
-       fstring         key;
-       Printer_entry   *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
        int             snum;
        WERROR          result;
        int             key_index;
        int             i;
-       REGISTRY_VALUE  *val;
-       char            *value_name;
-       uint32          data_len;
 
+       DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
 
-       DEBUG(4,("_spoolss_enumprinterdataex\n"));
+       *r->out.count = 0;
+       *r->out.needed = 0;
+       *r->out.info = NULL;
 
        if (!Printer) {
-               DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
+               DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
+                       OUR_HANDLE(r->in.handle)));
                return WERR_BADFID;
        }
 
@@ -9658,51 +9044,50 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
         * --jerry
         */
 
-       unistr2_to_ascii(key, &q_u->key, sizeof(key));
-       if ( !strlen(key) ) {
+       if (!strlen(r->in.key_name)) {
                result = WERR_INVALID_PARAM;
                goto done;
        }
 
        /* get the printer off of disk */
 
-       if (!get_printer_snum(p,handle, &snum, NULL))
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
+       }
 
        ZERO_STRUCT(printer);
        result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
-       if (!W_ERROR_IS_OK(result))
+       if (!W_ERROR_IS_OK(result)) {
                return result;
+       }
 
        /* now look for a match on the key name */
 
        p_data = printer->info_2->data;
 
-       unistr2_to_ascii(key, &q_u->key, sizeof(key));
-       if ( (key_index = lookup_printerkey( p_data, key)) == -1  )
-       {
-               DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
+       key_index = lookup_printerkey(p_data, r->in.key_name);
+       if (key_index == -1) {
+               DEBUG(10,("_spoolss_EnumPrinterDataEx: Unknown keyname [%s]\n",
+                       r->in.key_name));
                result = WERR_INVALID_PARAM;
                goto done;
        }
 
-       result = WERR_OK;
-       needed = 0;
-
        /* allocate the memory for the array of pointers -- if necessary */
 
-       num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
-       if ( num_entries )
-       {
-               if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
-               {
-                       DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
-                               (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
-                       result = WERR_NOMEM;
-                       goto done;
-               }
+       count = regval_ctr_numvals(p_data->keys[key_index].values);
+       if (!count) {
+               result = WERR_OK; /* ??? */
+               goto done;
+       }
 
-               memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
+       info = TALLOC_ZERO_ARRAY(p->mem_ctx,
+                                struct spoolss_PrinterEnumValues,
+                                count);
+       if (!info) {
+               DEBUG(0,("_spoolss_EnumPrinterDataEx: talloc() failed\n"));
+               result = WERR_NOMEM;
+               goto done;
        }
 
        /*
@@ -9710,37 +9095,25 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
         * back to the  client
         */
 
-       for ( i=0; i<num_entries; i++ )
-       {
-               /* lookup the registry value */
+       for (i=0; i < count; i++) {
 
-               val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
-               DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
+               REGISTRY_VALUE  *val;
 
-               /* copy the data */
+               /* lookup the registry value */
 
-               value_name = regval_name( val );
-               init_unistr( &enum_values[i].valuename, value_name );
-               enum_values[i].value_len = (strlen(value_name)+1) * 2;
-               enum_values[i].type      = regval_type( val );
+               val = regval_ctr_specific_value(p_data->keys[key_index].values, i);
 
-               data_len = regval_size( val );
-               if ( data_len ) {
-                       if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
-                       {
-                               DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
-                                       data_len ));
-                               result = WERR_NOMEM;
-                               goto done;
-                       }
-               }
-               enum_values[i].data_len = data_len;
+               DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val)));
 
-               /* keep track of the size of the array in bytes */
+               /* copy the data */
 
-               needed += spoolss_size_printer_enum_values(&enum_values[i]);
+               result = registry_value_to_printer_enum_value(info, val, &info[i]);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
        }
 
+#if 0 /* FIXME - gd */
        /* housekeeping information in the reply */
 
        /* Fix from Martin Zielinski <mz@seh.de> - ensure
@@ -9751,32 +9124,28 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
        if (needed % 4) {
                needed += 4-(needed % 4);
        }
+#endif
+       *r->out.count   = count;
+       *r->out.info    = info;
 
-       r_u->needed     = needed;
-       r_u->returned   = num_entries;
+ done:
 
-       if (needed > in_size) {
-               result = WERR_MORE_DATA;
-               goto done;
+       if (printer) {
+               free_a_printer(&printer, 2);
        }
 
-       /* copy data into the reply */
-
-       /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
-          response buffer size is != the offered buffer size
-
-               r_u->ctr.size           = r_u->needed;
-       */
-       r_u->ctr.size           = in_size;
-
-       r_u->ctr.size_of_array  = r_u->returned;
-       r_u->ctr.values         = enum_values;
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
-done:
-       if ( printer )
-       free_a_printer(&printer, 2);
+       *r->out.needed  = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
+                                              spoolss_EnumPrinterDataEx, NULL,
+                                              *r->out.info,
+                                              *r->out.count);
+       *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
+       *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
 
-       return result;
+       return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
 }
 
 /****************************************************************************
@@ -9785,9 +9154,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;
@@ -9805,13 +9172,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;
 }
 
@@ -9840,14 +9200,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);
 }
 
 /*******************************************************************
@@ -10103,7 +9466,7 @@ WERROR _spoolss_XcvData(pipes_struct *p,
                        struct spoolss_XcvData *r)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
-       DATA_BLOB out_data;
+       DATA_BLOB out_data = data_blob_null;
        WERROR werror;
 
        if (!Printer) {
@@ -10180,39 +9543,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
 ****************************************************************/
@@ -10224,28 +9554,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
 ****************************************************************/
@@ -10257,17 +9565,6 @@ WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
        return WERR_NOT_SUPPORTED;
 }
 
-/****************************************************************
- _spoolss_EnumPrintProcessors
-****************************************************************/
-
-WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
-                                   struct spoolss_EnumPrintProcessors *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
 /****************************************************************
  _spoolss_ReadPrinter
 ****************************************************************/
@@ -10279,28 +9576,6 @@ WERROR _spoolss_ReadPrinter(pipes_struct *p,
        return WERR_NOT_SUPPORTED;
 }
 
-/****************************************************************
- _spoolss_GetPrinterData
-****************************************************************/
-
-WERROR _spoolss_GetPrinterData(pipes_struct *p,
-                              struct spoolss_GetPrinterData *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_SetPrinterData
-****************************************************************/
-
-WERROR _spoolss_SetPrinterData(pipes_struct *p,
-                              struct spoolss_SetPrinterData *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
 /****************************************************************
  _spoolss_WaitForPrinterChange
 ****************************************************************/
@@ -10312,39 +9587,6 @@ WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
        return WERR_NOT_SUPPORTED;
 }
 
-/****************************************************************
- _spoolss_EnumForms
-****************************************************************/
-
-WERROR _spoolss_EnumForms(pipes_struct *p,
-                         struct spoolss_EnumForms *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_EnumPorts
-****************************************************************/
-
-WERROR _spoolss_EnumPorts(pipes_struct *p,
-                         struct spoolss_EnumPorts *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_EnumMonitors
-****************************************************************/
-
-WERROR _spoolss_EnumMonitors(pipes_struct *p,
-                            struct spoolss_EnumMonitors *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
 /****************************************************************
  _spoolss_AddPort
 ****************************************************************/
@@ -10499,28 +9741,6 @@ WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
        return WERR_NOT_SUPPORTED;
 }
 
-/****************************************************************
- _spoolss_EnumPrintProcDataTypes
-****************************************************************/
-
-WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
-                                      struct spoolss_EnumPrintProcDataTypes *r)
-{
-       p->rng_fault_state = true;
-       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
 ****************************************************************/
@@ -10664,17 +9884,6 @@ WERROR _spoolss_47(pipes_struct *p,
        return WERR_NOT_SUPPORTED;
 }
 
-/****************************************************************
- _spoolss_EnumPrinterData
-****************************************************************/
-
-WERROR _spoolss_EnumPrinterData(pipes_struct *p,
-                               struct spoolss_EnumPrinterData *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
 /****************************************************************
  _spoolss_4a
 ****************************************************************/
@@ -10708,28 +9917,6 @@ WERROR _spoolss_4c(pipes_struct *p,
        return WERR_NOT_SUPPORTED;
 }
 
-/****************************************************************
- _spoolss_EnumPrinterDataEx
-****************************************************************/
-
-WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
-                                 struct spoolss_EnumPrinterDataEx *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
- _spoolss_EnumPrinterKey
-****************************************************************/
-
-WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
-                              struct spoolss_EnumPrinterKey *r)
-{
-       p->rng_fault_state = true;
-       return WERR_NOT_SUPPORTED;
-}
-
 /****************************************************************
  _spoolss_53
 ****************************************************************/
index b90a189f7e3fcb14361af9caedcc2f9d0b7197a7..3ca85aa755582e724021f2fce04f08672ef606c5 100644 (file)
@@ -170,7 +170,7 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx )
  Find a registry key handle and return a SERVICE_INFO
  *****************************************************************/
 
-static SERVICE_INFO *find_service_info_by_hnd(pipes_struct *p, POLICY_HND *hnd)
+static SERVICE_INFO *find_service_info_by_hnd(pipes_struct *p, struct policy_handle *hnd)
 {
        SERVICE_INFO *service_info = NULL;
 
@@ -185,7 +185,7 @@ static SERVICE_INFO *find_service_info_by_hnd(pipes_struct *p, POLICY_HND *hnd)
 /******************************************************************
  *****************************************************************/
 
-static WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, uint32 type,
+static WERROR create_open_service_handle( pipes_struct *p, struct policy_handle *handle, uint32 type,
                                           const char *service, uint32 access_granted )
 {
        SERVICE_INFO *info = NULL;
index 809260120253865245595bf90c3d243df53ad1de..3de9f0e623ad0757fb9e8ed1f9f35ffbae069fae 100644 (file)
@@ -30,7 +30,7 @@
  *****************************************************************/
 
 static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
-                                              POLICY_HND *hnd)
+                                              struct policy_handle *hnd)
 {
        struct registry_key *regkey = NULL;
 
@@ -50,7 +50,7 @@ static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
  HK[LM|U]\<key>\<key>\...
  *******************************************************************/
  
-static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd, 
+static WERROR open_registry_key( pipes_struct *p, struct policy_handle *hnd,
                                 struct registry_key *parent,
                                 const char *subkeyname,
                                 uint32 access_desired  )
@@ -83,7 +83,7 @@ static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd,
  Note that P should be valid & hnd should already have space
  *******************************************************************/
 
-static bool close_registry_key(pipes_struct *p, POLICY_HND *hnd)
+static bool close_registry_key(pipes_struct *p, struct policy_handle *hnd)
 {
        struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
        
index 6424f1b3af249ed3e752d727311871141a8576e8..722a0a38323434ce7052079f7aaf707d3231b51c 100644 (file)
@@ -29,7 +29,7 @@ static NTSTATUS name_to_sid(struct rpc_pipe_client *cli,
                            TALLOC_CTX *mem_ctx,
                            DOM_SID *sid, const char *name)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        enum lsa_SidType *sid_types;
        NTSTATUS result;
        DOM_SID *sids;
@@ -149,7 +149,7 @@ static NTSTATUS cmd_lsa_query_info_policy(struct rpc_pipe_client *cli,
                                           TALLOC_CTX *mem_ctx, int argc, 
                                           const char **argv) 
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        union lsa_PolicyInformation *info = NULL;
 
@@ -207,7 +207,7 @@ static NTSTATUS cmd_lsa_lookup_names(struct rpc_pipe_client *cli,
                                      TALLOC_CTX *mem_ctx, int argc, 
                                      const char **argv)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        DOM_SID *sids;
        enum lsa_SidType *types;
@@ -255,7 +255,7 @@ static NTSTATUS cmd_lsa_lookup_names_level(struct rpc_pipe_client *cli,
                                           TALLOC_CTX *mem_ctx, int argc, 
                                           const char **argv)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        DOM_SID *sids;
        enum lsa_SidType *types;
@@ -305,7 +305,7 @@ static NTSTATUS cmd_lsa_lookup_names_level(struct rpc_pipe_client *cli,
 static NTSTATUS cmd_lsa_lookup_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                     int argc, const char **argv)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        DOM_SID *sids;
        char **domains;
@@ -374,7 +374,7 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx, int argc, 
                                        const char **argv)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct lsa_DomainList domain_list;
 
@@ -439,7 +439,7 @@ static NTSTATUS cmd_lsa_enum_privilege(struct rpc_pipe_client *cli,
                                       TALLOC_CTX *mem_ctx, int argc, 
                                       const char **argv) 
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct lsa_PrivArray priv_array;
 
@@ -496,7 +496,7 @@ static NTSTATUS cmd_lsa_get_dispname(struct rpc_pipe_client *cli,
                                      TALLOC_CTX *mem_ctx, int argc, 
                                      const char **argv) 
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
 
        uint16 lang_id=0;
@@ -544,7 +544,7 @@ static NTSTATUS cmd_lsa_enum_sids(struct rpc_pipe_client *cli,
                                  TALLOC_CTX *mem_ctx, int argc, 
                                  const char **argv) 
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
 
        uint32 enum_context=0;
@@ -600,8 +600,8 @@ static NTSTATUS cmd_lsa_create_account(struct rpc_pipe_client *cli,
                                            TALLOC_CTX *mem_ctx, int argc, 
                                            const char **argv) 
 {
-       POLICY_HND dom_pol;
-       POLICY_HND user_pol;
+       struct policy_handle dom_pol;
+       struct policy_handle user_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 des_access = 0x000f000f;
        
@@ -647,8 +647,8 @@ static NTSTATUS cmd_lsa_enum_privsaccounts(struct rpc_pipe_client *cli,
                                            TALLOC_CTX *mem_ctx, int argc, 
                                            const char **argv) 
 {
-       POLICY_HND dom_pol;
-       POLICY_HND user_pol;
+       struct policy_handle dom_pol;
+       struct policy_handle user_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 access_desired = 0x000f000f;
        DOM_SID sid;
@@ -710,7 +710,7 @@ static NTSTATUS cmd_lsa_enum_acct_rights(struct rpc_pipe_client *cli,
                                         TALLOC_CTX *mem_ctx, int argc, 
                                         const char **argv) 
 {
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        DOM_SID sid;
        struct lsa_RightSet rights;
@@ -760,7 +760,7 @@ static NTSTATUS cmd_lsa_add_acct_rights(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx, int argc, 
                                        const char **argv) 
 {
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct lsa_RightSet rights;
        DOM_SID sid;
@@ -813,7 +813,7 @@ static NTSTATUS cmd_lsa_remove_acct_rights(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx, int argc, 
                                        const char **argv) 
 {
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct lsa_RightSet rights;
        DOM_SID sid;
@@ -868,7 +868,7 @@ static NTSTATUS cmd_lsa_lookup_priv_value(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx, int argc, 
                                        const char **argv) 
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct lsa_LUID luid;
        struct lsa_String name;
@@ -910,7 +910,7 @@ static NTSTATUS cmd_lsa_query_secobj(struct rpc_pipe_client *cli,
                                     TALLOC_CTX *mem_ctx, int argc, 
                                     const char **argv) 
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        SEC_DESC_BUF *sdb;
        uint32 sec_info = DACL_SECURITY_INFORMATION;
@@ -996,7 +996,7 @@ static NTSTATUS cmd_lsa_query_trustdominfobysid(struct rpc_pipe_client *cli,
                                                TALLOC_CTX *mem_ctx, int argc, 
                                                const char **argv) 
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        DOM_SID dom_sid;
        uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
@@ -1045,7 +1045,7 @@ static NTSTATUS cmd_lsa_query_trustdominfobyname(struct rpc_pipe_client *cli,
                                                 TALLOC_CTX *mem_ctx, int argc,
                                                 const char **argv) 
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
        union lsa_TrustedDomainInfo *info = NULL;
@@ -1093,7 +1093,7 @@ static NTSTATUS cmd_lsa_query_trustdominfo(struct rpc_pipe_client *cli,
                                           TALLOC_CTX *mem_ctx, int argc,
                                           const char **argv) 
 {
-       POLICY_HND pol, trustdom_pol;
+       struct policy_handle pol, trustdom_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
        union lsa_TrustedDomainInfo *info = NULL;
@@ -1152,7 +1152,7 @@ static NTSTATUS cmd_lsa_get_username(struct rpc_pipe_client *cli,
                                      TALLOC_CTX *mem_ctx, int argc,
                                      const char **argv)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        const char *servername = cli->desthost;
        struct lsa_String *account_name = NULL;
@@ -1194,7 +1194,7 @@ static NTSTATUS cmd_lsa_add_priv(struct rpc_pipe_client *cli,
                                 TALLOC_CTX *mem_ctx, int argc,
                                 const char **argv)
 {
-       POLICY_HND dom_pol, user_pol;
+       struct policy_handle dom_pol, user_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct lsa_PrivilegeSet privs;
        struct lsa_LUIDAttribute *set = NULL;
@@ -1278,7 +1278,7 @@ static NTSTATUS cmd_lsa_del_priv(struct rpc_pipe_client *cli,
                                 TALLOC_CTX *mem_ctx, int argc,
                                 const char **argv)
 {
-       POLICY_HND dom_pol, user_pol;
+       struct policy_handle dom_pol, user_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct lsa_PrivilegeSet privs;
        struct lsa_LUIDAttribute *set = NULL;
index 936c2081f3676e01bf42c8d9f0427742d77d45e5..428984db133e3e692ddac1bff4939a82a4c2f0bb 100644 (file)
@@ -299,7 +299,7 @@ static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
                                     TALLOC_CTX *mem_ctx,
                                     int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, user_pol;
+       struct policy_handle connect_pol, domain_pol, user_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 info_level = 21;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -487,7 +487,7 @@ static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
                                      TALLOC_CTX *mem_ctx,
                                      int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, group_pol;
+       struct policy_handle connect_pol, domain_pol, group_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        enum samr_GroupInfoEnum info_level = GROUPINFOALL;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -555,7 +555,7 @@ static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
                                           TALLOC_CTX *mem_ctx,
                                           int argc, const char **argv)
 {
-       POLICY_HND              connect_pol,
+       struct policy_handle            connect_pol,
                                domain_pol,
                                user_pol;
        NTSTATUS                result = NT_STATUS_UNSUCCESSFUL;
@@ -624,7 +624,7 @@ static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
                                           TALLOC_CTX *mem_ctx,
                                           int argc, const char **argv)
 {
-       POLICY_HND              connect_pol, domain_pol;
+       struct policy_handle            connect_pol, domain_pol;
        NTSTATUS                result = NT_STATUS_UNSUCCESSFUL;
        DOM_SID                *sids;
        size_t                     num_sids;
@@ -709,7 +709,7 @@ static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
                                         TALLOC_CTX *mem_ctx,
                                         int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, group_pol;
+       struct policy_handle connect_pol, domain_pol, group_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 group_rid;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -783,7 +783,7 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx,
                                        int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 start_idx, size, num_dom_users, i;
        struct samr_SamArray *dom_users = NULL;
@@ -862,7 +862,7 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
                                          TALLOC_CTX *mem_ctx,
                                          int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 start_idx, size, num_dom_groups, i;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -935,7 +935,7 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
                                          TALLOC_CTX *mem_ctx,
                                          int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 start_idx, size, num_als_groups, i;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -1008,7 +1008,7 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
                                      TALLOC_CTX *mem_ctx,
                                      int argc, const char **argv)
 {
-       POLICY_HND connect_pol;
+       struct policy_handle connect_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 start_idx, size, num_entries, i;
        uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -1071,7 +1071,7 @@ static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
                                         TALLOC_CTX *mem_ctx,
                                         int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, alias_pol;
+       struct policy_handle connect_pol, domain_pol, alias_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 alias_rid, i;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -1144,7 +1144,7 @@ static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli,
                                         TALLOC_CTX *mem_ctx,
                                         int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, alias_pol;
+       struct policy_handle connect_pol, domain_pol, alias_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32_t alias_rid;
        uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -1239,7 +1239,7 @@ static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
                                      TALLOC_CTX *mem_ctx,
                                      int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, alias_pol;
+       struct policy_handle connect_pol, domain_pol, alias_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 alias_rid;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -1320,7 +1320,7 @@ static NTSTATUS cmd_samr_query_dispinfo_internal(struct rpc_pipe_client *cli,
                                                 int argc, const char **argv,
                                                 uint32_t opcode)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 start_idx=0, max_entries=250, max_size = 0xffff, num_entries = 0, i;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -1512,7 +1512,7 @@ static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx,
                                        int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 switch_level = 2;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -1615,7 +1615,7 @@ static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
                                          TALLOC_CTX *mem_ctx,
                                          int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, user_pol;
+       struct policy_handle connect_pol, domain_pol, user_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct lsa_String acct_name;
        uint32 acb_info;
@@ -1693,7 +1693,7 @@ static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
                                           TALLOC_CTX *mem_ctx,
                                           int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, group_pol;
+       struct policy_handle connect_pol, domain_pol, group_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct lsa_String grp_name;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -1759,7 +1759,7 @@ static NTSTATUS cmd_samr_create_dom_alias(struct rpc_pipe_client *cli,
                                           TALLOC_CTX *mem_ctx,
                                           int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, alias_pol;
+       struct policy_handle connect_pol, domain_pol, alias_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct lsa_String alias_name;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -1827,7 +1827,7 @@ static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
                                       int argc, const char **argv)
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        uint32 num_names;
        struct samr_Ids rids, name_types;
        int i;
@@ -1902,7 +1902,7 @@ static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
                                      int argc, const char **argv)
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        uint32_t num_rids, *rids;
        struct lsa_Strings names;
        struct samr_Ids types;
@@ -1977,7 +1977,7 @@ static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli,
                                          int argc, const char **argv)
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       POLICY_HND connect_pol, domain_pol, group_pol;
+       struct policy_handle connect_pol, domain_pol, group_pol;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
 
        if ((argc < 2) || (argc > 3)) {
@@ -2058,7 +2058,7 @@ static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
                                          int argc, const char **argv)
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       POLICY_HND connect_pol, domain_pol, user_pol;
+       struct policy_handle connect_pol, domain_pol, user_pol;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
 
        if ((argc < 2) || (argc > 3)) {
@@ -2140,7 +2140,7 @@ static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
                                     TALLOC_CTX *mem_ctx,
                                     int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, user_pol, *pol;
+       struct policy_handle connect_pol, domain_pol, user_pol, *pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 sec_info = DACL_SECURITY_INFORMATION;
        uint32 user_rid = 0;
@@ -2230,7 +2230,7 @@ static NTSTATUS cmd_samr_get_usrdom_pwinfo(struct rpc_pipe_client *cli,
                                           int argc, const char **argv)
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       POLICY_HND connect_pol, domain_pol, user_pol;
+       struct policy_handle connect_pol, domain_pol, user_pol;
        struct samr_PwInfo info;
        uint32_t rid;
 
@@ -2316,7 +2316,7 @@ static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
                                       TALLOC_CTX *mem_ctx,
                                       int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
        fstring sid_string;
@@ -2369,7 +2369,7 @@ static NTSTATUS cmd_samr_chgpasswd(struct rpc_pipe_client *cli,
                                   TALLOC_CTX *mem_ctx,
                                   int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, user_pol;
+       struct policy_handle connect_pol, domain_pol, user_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        const char *user, *oldpass, *newpass;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -2461,7 +2461,7 @@ static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli,
                                    TALLOC_CTX *mem_ctx,
                                    int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        const char *user, *oldpass, *newpass;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -2518,7 +2518,7 @@ static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
                                    TALLOC_CTX *mem_ctx,
                                    int argc, const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        const char *user, *oldpass, *newpass;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
@@ -2604,7 +2604,7 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli,
                                         int argc, const char **argv,
                                         int opcode)
 {
-       POLICY_HND connect_pol, domain_pol, user_pol;
+       struct policy_handle connect_pol, domain_pol, user_pol;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
        const char *user, *param;
        uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
index c68cf00530de09ffa2c0e9d00d124ceaa792a335..cd044624260504fe469a8158c200de88864a39c8 100644 (file)
@@ -6,6 +6,7 @@
    Copyright (C) Tim Potter                        2000
    Copyright (C) Andrew Tridgell              1992-1999
    Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+   Copyright (C) Guenther Deschner                 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
@@ -104,7 +105,7 @@ static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli,
                                             int argc, const char **argv)
 {
        WERROR          werror;
-       POLICY_HND      hnd;
+       struct policy_handle    hnd;
 
        if (argc != 2) {
                printf("Usage: %s <printername>\n", argv[0]);
@@ -137,57 +138,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 +184,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 +197,30 @@ static void display_print_info_1(PRINTER_INFO_1 *i1)
 /****************************************************************************
 ****************************************************************************/
 
-static void display_print_info_2(PRINTER_INFO_2 *i2)
+static void display_print_info2(struct spoolss_PrinterInfo2 *r)
 {
-       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);
+       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 +228,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 +249,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;
 }
@@ -359,55 +315,45 @@ static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
 /****************************************************************************
 ****************************************************************************/
 
-static void display_port_info_1(PORT_INFO_1 *i1)
+static void display_port_info_1(struct spoolss_PortInfo1 *r)
 {
-       fstring buffer;
-
-       rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
-       printf("\tPort Name:\t[%s]\n", buffer);
+       printf("\tPort Name:\t[%s]\n", r->port_name);
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static void display_port_info_2(PORT_INFO_2 *i2)
+static void display_port_info_2(struct spoolss_PortInfo2 *r)
 {
-       fstring buffer;
-
-       rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
-       printf("\tPort Name:\t[%s]\n", buffer);
-       rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
-
-       printf("\tMonitor Name:\t[%s]\n", buffer);
-       rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE);
-
-       printf("\tDescription:\t[%s]\n", buffer);
+       printf("\tPort Name:\t[%s]\n", r->port_name);
+       printf("\tMonitor Name:\t[%s]\n", r->monitor_name);
+       printf("\tDescription:\t[%s]\n", r->description);
        printf("\tPort Type:\t" );
-       if ( i2->port_type ) {
+       if (r->port_type) {
                int comma = 0; /* hack */
                printf( "[" );
-               if ( i2->port_type & PORT_TYPE_READ ) {
+               if (r->port_type & SPOOLSS_PORT_TYPE_READ) {
                        printf( "Read" );
                        comma = 1;
                }
-               if ( i2->port_type & PORT_TYPE_WRITE ) {
+               if (r->port_type & SPOOLSS_PORT_TYPE_WRITE) {
                        printf( "%sWrite", comma ? ", " : "" );
                        comma = 1;
                }
                /* These two have slightly different interpretations
                 on 95/98/ME but I'm disregarding that for now */
-               if ( i2->port_type & PORT_TYPE_REDIRECTED ) {
+               if (r->port_type & SPOOLSS_PORT_TYPE_REDIRECTED) {
                        printf( "%sRedirected", comma ? ", " : "" );
                        comma = 1;
                }
-               if ( i2->port_type & PORT_TYPE_NET_ATTACHED ) {
+               if (r->port_type & SPOOLSS_PORT_TYPE_NET_ATTACHED) {
                        printf( "%sNet-Attached", comma ? ", " : "" );
                }
                printf( "]\n" );
        } else {
                printf( "[Unset]\n" );
        }
-       printf("\tReserved:\t[%d]\n", i2->reserved);
+       printf("\tReserved:\t[%d]\n", r->reserved);
        printf("\n");
 }
 
@@ -419,37 +365,40 @@ static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
                                       const char **argv)
 {
        WERROR                  result;
-       uint32                  info_level = 1;
-       PORT_INFO_CTR           ctr;
-       uint32                  returned;
+       uint32_t                level = 1;
+       uint32_t                count;
+       union spoolss_PortInfo *info;
 
        if (argc > 2) {
                printf("Usage: %s [level]\n", argv[0]);
                return WERR_OK;
        }
 
-       if (argc == 2)
-               info_level = atoi(argv[1]);
+       if (argc == 2) {
+               level = atoi(argv[1]);
+       }
 
        /* Enumerate ports */
 
-       ZERO_STRUCT(ctr);
-
-       result = rpccli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr);
-
+       result = rpccli_spoolss_enumports(cli, mem_ctx,
+                                         cli->srv_name_slash,
+                                         level,
+                                         0,
+                                         &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(&ctr.port.info_1[i]);
+                               display_port_info_1(&info[i].info1);
                                break;
                        case 2:
-                               display_port_info_2(&ctr.port.info_2[i]);
+                               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;
                        }
                }
@@ -465,7 +414,7 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx,
                                        int argc, const char **argv)
 {
-       POLICY_HND      pol;
+       struct policy_handle pol;
        WERROR          result;
        NTSTATUS        status;
        uint32          info_level = 2;
@@ -511,6 +460,8 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
 
        /* Modify the comment. */
        info.info2.comment = comment;
+       info.info2.secdesc = NULL;
+       info.info2.devmode = NULL;
 
        info_ctr.level = 2;
        info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
@@ -539,7 +490,7 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx,
                                        int argc, const char **argv)
 {
-       POLICY_HND      pol;
+       struct policy_handle pol;
        WERROR          result;
        NTSTATUS        status;
        uint32          info_level = 2;
@@ -615,9 +566,9 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx,
                                        int argc, const char **argv)
 {
-       POLICY_HND      pol;
+       struct policy_handle pol;
        WERROR          result;
-       uint32          info_level = 1;
+       uint32_t        level = 1;
        const char      *printername;
        union spoolss_PrinterInfo info;
 
@@ -628,7 +579,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]);
@@ -639,45 +590,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;
 }
@@ -731,6 +683,7 @@ static void display_reg_value(REGISTRY_VALUE value)
                        break;
                }
 
+               printf("%s: REG_MULTI_SZ: \n", value.valuename);
                for (i=0; i<num_values; i++) {
                        d_printf("%s\n", values[i]);
                }
@@ -746,15 +699,64 @@ static void display_reg_value(REGISTRY_VALUE value)
 /****************************************************************************
 ****************************************************************************/
 
+static void display_printer_data(const char *v,
+                                enum winreg_Type type,
+                                union spoolss_PrinterData *r)
+{
+       int i;
+
+       switch (type) {
+       case REG_DWORD:
+               printf("%s: REG_DWORD: 0x%08x\n", v, r->value);
+               break;
+       case REG_SZ:
+               printf("%s: REG_SZ: %s\n", v, r->string);
+               break;
+       case REG_BINARY: {
+               char *hex = hex_encode_talloc(NULL,
+                       r->binary.data, r->binary.length);
+               size_t len;
+               printf("%s: REG_BINARY:", v);
+               len = strlen(hex);
+               for (i=0; i<len; i++) {
+                       if (hex[i] == '\0') {
+                               break;
+                       }
+                       if (i%40 == 0) {
+                               putchar('\n');
+                       }
+                       putchar(hex[i]);
+               }
+               TALLOC_FREE(hex);
+               putchar('\n');
+               break;
+       }
+       case REG_MULTI_SZ:
+               printf("%s: REG_MULTI_SZ: ", v);
+               for (i=0; r->string_array[i] != NULL; i++) {
+                       printf("%s ", r->string_array[i]);
+               }
+               printf("\n");
+               break;
+       default:
+               printf("%s: unknown type 0x%02x:\n", v, type);
+               break;
+       }
+}
+
+/****************************************************************************
+****************************************************************************/
+
 static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
                                           TALLOC_CTX *mem_ctx,
                                           int argc, const char **argv)
 {
-       POLICY_HND      pol;
+       struct policy_handle pol;
        WERROR          result;
        fstring         printername;
        const char *valuename;
-       REGISTRY_VALUE value;
+       enum winreg_Type type;
+       union spoolss_PrinterData data;
 
        if (argc != 3) {
                printf("Usage: %s <printername> <valuename>\n", argv[0]);
@@ -782,16 +784,18 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
 
        /* Get printer info */
 
-       result = rpccli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value);
-
+       result = rpccli_spoolss_getprinterdata(cli, mem_ctx,
+                                              &pol,
+                                              valuename,
+                                              0,
+                                              &type,
+                                              &data);
        if (!W_ERROR_IS_OK(result))
                goto done;
 
        /* Display printer data */
 
-       fstrcpy(value.valuename, valuename);
-       display_reg_value(value);
-
+       display_printer_data(valuename, type, &data);
 
  done:
        if (is_valid_policy_hnd(&pol))
@@ -807,14 +811,14 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
                                             TALLOC_CTX *mem_ctx,
                                             int argc, const char **argv)
 {
-       POLICY_HND      pol;
+       struct policy_handle pol;
        WERROR          result;
        NTSTATUS        status;
        fstring         printername;
        const char *valuename, *keyname;
        REGISTRY_VALUE value;
 
-       uint32_t type;
+       enum winreg_Type type;
        uint8_t *buffer = NULL;
        uint32_t offered = 0;
        uint32_t needed;
@@ -901,116 +905,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) {
@@ -1074,21 +968,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;
+       struct policy_handle 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;
        }
@@ -1097,8 +990,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 */
 
@@ -1118,23 +1012,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;
@@ -1145,18 +1040,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;
 }
@@ -1169,68 +1066,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;
                }
        }
@@ -1562,7 +1464,7 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
                                       TALLOC_CTX *mem_ctx,
                                       int argc, const char **argv)
 {
-       POLICY_HND              pol;
+       struct policy_handle    pol;
        WERROR                  result;
        NTSTATUS                status;
        uint32                  level = 2;
@@ -1608,6 +1510,9 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
        /* Set the printer driver */
 
        info.info2.drivername = argv[2];
+       info.info2.devmode = NULL;
+       info.info2.secdesc = NULL;
+
        info_ctr.level = 2;
        info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
 
@@ -1808,7 +1713,7 @@ static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
 static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                    int argc, const char **argv)
 {
-       POLICY_HND handle;
+       struct policy_handle handle;
        WERROR werror;
        NTSTATUS status;
        const char *printername;
@@ -1843,7 +1748,7 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
 
        switch (level) {
        case 1:
-               info1.flags             = FORM_USER;
+               info1.flags             = SPOOLSS_FORM_USER;
                info1.form_name         = argv[2];
                info1.size.width        = 100;
                info1.size.height       = 100;
@@ -1856,7 +1761,7 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
 
                break;
        case 2:
-               info2.flags             = FORM_USER;
+               info2.flags             = SPOOLSS_FORM_USER;
                info2.form_name         = argv[2];
                info2.size.width        = 100;
                info2.size.height       = 100;
@@ -1898,7 +1803,7 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
 static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                    int argc, const char **argv)
 {
-       POLICY_HND handle;
+       struct policy_handle handle;
        WERROR werror;
        NTSTATUS status;
        const char *printername;
@@ -1925,7 +1830,7 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
 
        /* Dummy up some values for the form data */
 
-       info1.flags             = FORM_PRINTER;
+       info1.flags             = SPOOLSS_FORM_PRINTER;
        info1.size.width        = 100;
        info1.size.height       = 100;
        info1.area.left         = 0;
@@ -1958,11 +1863,11 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
 static const char *get_form_flag(int form_flag)
 {
        switch (form_flag) {
-       case FORM_USER:
+       case SPOOLSS_FORM_USER:
                return "FORM_USER";
-       case FORM_BUILTIN:
+       case SPOOLSS_FORM_BUILTIN:
                return "FORM_BUILTIN";
-       case FORM_PRINTER:
+       case SPOOLSS_FORM_PRINTER:
                return "FORM_PRINTER";
        default:
                return "unknown";
@@ -1972,27 +1877,6 @@ static const char *get_form_flag(int form_flag)
 /****************************************************************************
 ****************************************************************************/
 
-static void display_form(FORM_1 *form)
-{
-       fstring form_name = "";
-
-       if (form->name.buffer)
-               rpcstr_pull(form_name, form->name.buffer,
-                           sizeof(form_name), -1, STR_TERMINATE);
-
-       printf("%s\n" \
-               "\tflag: %s (%d)\n" \
-               "\twidth: %d, length: %d\n" \
-               "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
-               form_name, get_form_flag(form->flag), form->flag,
-               form->width, form->length,
-               form->left, form->right,
-               form->top, form->bottom);
-}
-
-/****************************************************************************
-****************************************************************************/
-
 static void display_form_info1(struct spoolss_FormInfo1 *r)
 {
        printf("%s\n" \
@@ -2033,7 +1917,7 @@ static void display_form_info2(struct spoolss_FormInfo2 *r)
 static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                    int argc, const char **argv)
 {
-       POLICY_HND handle;
+       struct policy_handle handle;
        WERROR werror;
        NTSTATUS status;
        const char *printername;
@@ -2117,7 +2001,7 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
                                       TALLOC_CTX *mem_ctx, int argc,
                                       const char **argv)
 {
-       POLICY_HND handle;
+       struct policy_handle handle;
        WERROR werror;
        NTSTATUS status;
        const char *printername;
@@ -2164,16 +2048,16 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
                                       TALLOC_CTX *mem_ctx, int argc,
                                       const char **argv)
 {
-       POLICY_HND handle;
+       struct policy_handle handle;
        WERROR werror;
        const char *printername;
        uint32 num_forms, level = 1, i;
-       FORM_1 *forms;
+       union spoolss_FormInfo *forms;
 
        /* Parse the command arguments */
 
-       if (argc != 2) {
-               printf ("Usage: %s <printer>\n", argv[0]);
+       if (argc < 2 || argc > 4) {
+               printf ("Usage: %s <printer> [level]\n", argv[0]);
                return WERR_OK;
         }
 
@@ -2188,9 +2072,18 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
        if (!W_ERROR_IS_OK(werror))
                goto done;
 
+       if (argc == 3) {
+               level = atoi(argv[2]);
+       }
+
        /* Enumerate forms */
 
-       werror = rpccli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms);
+       werror = rpccli_spoolss_enumforms(cli, mem_ctx,
+                                         &handle,
+                                         level,
+                                         0,
+                                         &num_forms,
+                                         &forms);
 
        if (!W_ERROR_IS_OK(werror))
                goto done;
@@ -2198,9 +2091,14 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
        /* Display output */
 
        for (i = 0; i < num_forms; i++) {
-
-               display_form(&forms[i]);
-
+               switch (level) {
+               case 1:
+                       display_form_info1(&forms[i].info1);
+                       break;
+               case 2:
+                       display_form_info2(&forms[i].info2);
+                       break;
+               }
        }
 
  done:
@@ -2218,11 +2116,12 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
                                            int argc, const char **argv)
 {
        WERROR result;
+       NTSTATUS status;
        const char *printername;
-       POLICY_HND pol;
+       struct policy_handle pol;
        union spoolss_PrinterInfo info;
-       REGISTRY_VALUE value;
-       TALLOC_CTX *tmp_ctx = talloc_stackframe();
+       enum winreg_Type type;
+       union spoolss_PrinterData data;
 
        /* parse the command arguments */
        if (argc < 5) {
@@ -2235,25 +2134,25 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
 
        RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
 
-       value.type = REG_NONE;
+       type = REG_NONE;
 
        if (strequal(argv[2], "string")) {
-               value.type = REG_SZ;
+               type = REG_SZ;
        }
 
        if (strequal(argv[2], "binary")) {
-               value.type = REG_BINARY;
+               type = REG_BINARY;
        }
 
        if (strequal(argv[2], "dword")) {
-               value.type = REG_DWORD;
+               type = REG_DWORD;
        }
 
        if (strequal(argv[2], "multistring")) {
-               value.type = REG_MULTI_SZ;
+               type = REG_MULTI_SZ;
        }
 
-       if (value.type == REG_NONE) {
+       if (type == REG_NONE) {
                printf("Unknown data type: %s\n", argv[2]);
                result =  WERR_INVALID_PARAM;
                goto done;
@@ -2265,92 +2164,73 @@ static WERROR cmd_spoolss_setprinterdata(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;
+       }
 
        result = rpccli_spoolss_getprinter(cli, mem_ctx,
                                           &pol,
                                           0,
                                           0,
                                           &info);
-        if (!W_ERROR_IS_OK(result))
+        if (!W_ERROR_IS_OK(result)) {
                 goto done;
+       }
 
-       printf("%s\n", current_timestring(tmp_ctx, True));
+       printf("%s\n", current_timestring(mem_ctx, true));
        printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id);
 
        /* Set the printer data */
 
-       fstrcpy(value.valuename, argv[3]);
-
-       switch (value.type) {
-       case REG_SZ: {
-               UNISTR2 data;
-               init_unistr2(&data, argv[4], UNI_STR_TERMINATE);
-               value.size = data.uni_str_len * 2;
-               if (value.size) {
-                       value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, data.buffer,
-                                                     value.size);
-               } else {
-                       value.data_p = NULL;
-               }
+       switch (type) {
+       case REG_SZ:
+               data.string = talloc_strdup(mem_ctx, argv[4]);
+               W_ERROR_HAVE_NO_MEMORY(data.string);
                break;
-       }
-       case REG_DWORD: {
-               uint32 data = strtoul(argv[4], NULL, 10);
-               value.size = sizeof(data);
-               if (sizeof(data)) {
-                       value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, &data,
-                                                     sizeof(data));
-               } else {
-                       value.data_p = NULL;
-               }
+       case REG_DWORD:
+               data.value = strtoul(argv[4], NULL, 10);
                break;
-       }
-       case REG_BINARY: {
-               DATA_BLOB data = strhex_to_data_blob(mem_ctx, argv[4]);
-               value.data_p = data.data;
-               value.size = data.length;
+       case REG_BINARY:
+               data.binary = strhex_to_data_blob(mem_ctx, argv[4]);
                break;
-       }
        case REG_MULTI_SZ: {
-               int i;
-               size_t len = 0;
-               char *p;
+               int i, num_strings;
+               const char **strings = NULL;
 
                for (i=4; i<argc; i++) {
                        if (strcmp(argv[i], "NULL") == 0) {
                                argv[i] = "";
                        }
-                       len += strlen(argv[i])+1;
+                       if (!add_string_to_array(mem_ctx, argv[i],
+                                                &strings,
+                                                &num_strings)) {
+                               result = WERR_NOMEM;
+                               goto done;
+                       }
                }
-
-               value.size = len*2;
-               value.data_p = TALLOC_ARRAY(mem_ctx, unsigned char, value.size);
-               if (value.data_p == NULL) {
+               data.string_array = talloc_zero_array(mem_ctx, const char *, num_strings + 1);
+               if (!data.string_array) {
                        result = WERR_NOMEM;
                        goto done;
                }
-
-               p = (char *)value.data_p;
-               len = value.size;
-               for (i=4; i<argc; i++) {
-                       size_t l = (strlen(argv[i])+1)*2;
-                       rpcstr_push(p, argv[i], len, STR_TERMINATE);
-                       p += l;
-                       len -= l;
+               for (i=0; i < num_strings; i++) {
+                       data.string_array[i] = strings[i];
                }
-               SMB_ASSERT(len == 0);
                break;
-       }
+               }
        default:
                printf("Unknown data type: %s\n", argv[2]);
                result = WERR_INVALID_PARAM;
                goto done;
        }
 
-       result = rpccli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
-
+       status = rpccli_spoolss_SetPrinterData(cli, mem_ctx,
+                                              &pol,
+                                              argv[3], /* value_name */
+                                              type,
+                                              data,
+                                              0, /* autocalculated size */
+                                              &result);
        if (!W_ERROR_IS_OK(result)) {
                printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
                goto done;
@@ -2362,17 +2242,18 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
                                           0,
                                           0,
                                           &info);
-        if (!W_ERROR_IS_OK(result))
+        if (!W_ERROR_IS_OK(result)) {
                 goto done;
+       }
 
-       printf("%s\n", current_timestring(tmp_ctx, True));
+       printf("%s\n", current_timestring(mem_ctx, true));
        printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id);
 
 done:
        /* cleanup */
-       TALLOC_FREE(tmp_ctx);
-       if (is_valid_policy_hnd(&pol))
+       if (is_valid_policy_hnd(&pol)) {
                rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
+       }
 
        return result;
 }
@@ -2380,48 +2261,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,
@@ -2468,18 +2307,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;
+       struct policy_handle hnd;
+       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 */
 
@@ -2494,19 +2334,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);
@@ -2515,8 +2361,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;
 }
@@ -2601,14 +2448,22 @@ done:
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli,
-                                      TALLOC_CTX *mem_ctx, int argc,
-                                      const char **argv)
+static WERROR cmd_spoolss_enum_data(struct rpc_pipe_client *cli,
+                                   TALLOC_CTX *mem_ctx, int argc,
+                                   const char **argv)
 {
        WERROR result;
-       uint32 i=0, val_needed, data_needed;
+       NTSTATUS status;
+       uint32_t i = 0;
        const char *printername;
-       POLICY_HND hnd;
+       struct policy_handle hnd;
+       uint32_t value_offered = 0;
+       const char *value_name = NULL;
+       uint32_t value_needed;
+       enum winreg_Type type;
+       uint8_t *data = NULL;
+       uint32_t data_offered = 0;
+       uint32_t data_needed;
 
        if (argc != 2) {
                printf("Usage: %s printername\n", argv[0]);
@@ -2623,28 +2478,60 @@ static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli,
                                               printername,
                                               SEC_FLAG_MAXIMUM_ALLOWED,
                                               &hnd);
-       if (!W_ERROR_IS_OK(result))
+       if (!W_ERROR_IS_OK(result)) {
                goto done;
+       }
 
        /* Enumerate data */
 
-       result = rpccli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
-                                            &val_needed, &data_needed,
-                                            NULL);
-       while (W_ERROR_IS_OK(result)) {
-               REGISTRY_VALUE value;
-               result = rpccli_spoolss_enumprinterdata(
-                       cli, mem_ctx, &hnd, i++, val_needed,
-                       data_needed, 0, 0, &value);
-               if (W_ERROR_IS_OK(result))
-                       display_reg_value(value);
-       }
-       if (W_ERROR_V(result) == ERRnomoreitems)
+       status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
+                                               &hnd,
+                                               i,
+                                               value_name,
+                                               value_offered,
+                                               &value_needed,
+                                               &type,
+                                               data,
+                                               data_offered,
+                                               &data_needed,
+                                               &result);
+
+       data_offered    = data_needed;
+       value_offered   = value_needed;
+       data            = talloc_zero_array(mem_ctx, uint8_t, data_needed);
+       value_name      = talloc_zero_array(mem_ctx, char, value_needed);
+
+       while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
+
+               status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
+                                                       &hnd,
+                                                       i++,
+                                                       value_name,
+                                                       value_offered,
+                                                       &value_needed,
+                                                       &type,
+                                                       data,
+                                                       data_offered,
+                                                       &data_needed,
+                                                       &result);
+               if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
+                       REGISTRY_VALUE v;
+                       fstrcpy(v.valuename, value_name);
+                       v.type = type;
+                       v.size = data_offered;
+                       v.data_p = data;
+                       display_reg_value(v);
+               }
+       }
+
+       if (W_ERROR_V(result) == ERRnomoreitems) {
                result = W_ERROR(ERRsuccess);
+       }
 
 done:
-       if (is_valid_policy_hnd(&hnd))
+       if (is_valid_policy_hnd(&hnd)) {
                rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
+       }
 
        return result;
 }
@@ -2659,17 +2546,15 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
        WERROR result;
        uint32 i;
        const char *printername;
-       const char *keyname = NULL;
-       POLICY_HND hnd;
-       REGVAL_CTR *ctr = NULL;
+       struct policy_handle hnd;
+       uint32_t count;
+       struct spoolss_PrinterEnumValues *info;
 
        if (argc != 3) {
                printf("Usage: %s printername <keyname>\n", argv[0]);
                return WERR_OK;
        }
 
-       keyname = argv[2];
-
        /* Open printer handle */
 
        RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
@@ -2678,28 +2563,32 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
                                               printername,
                                               SEC_FLAG_MAXIMUM_ALLOWED,
                                               &hnd);
-       if (!W_ERROR_IS_OK(result))
+       if (!W_ERROR_IS_OK(result)) {
                goto done;
+       }
 
        /* Enumerate subkeys */
 
-       if ( !(ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
-               return WERR_NOMEM;
-
-       result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &hnd, keyname, ctr);
-
-       if (!W_ERROR_IS_OK(result))
+       result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx,
+                                                 &hnd,
+                                                 argv[2],
+                                                 0,
+                                                 &count,
+                                                 &info);
+       if (!W_ERROR_IS_OK(result)) {
                goto done;
-
-       for (i=0; i < ctr->num_values; i++) {
-               display_reg_value(*(ctr->values[i]));
        }
 
-       TALLOC_FREE( ctr );
+       for (i=0; i < count; i++) {
+               display_printer_data(info[i].value_name,
+                                    info[i].type,
+                                    info[i].data);
+       }
 
-done:
-       if (is_valid_policy_hnd(&hnd))
+ done:
+       if (is_valid_policy_hnd(&hnd)) {
                rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
+       }
 
        return result;
 }
@@ -2707,25 +2596,27 @@ done:
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli,
-                                            TALLOC_CTX *mem_ctx, int argc,
-                                            const char **argv)
+static WERROR cmd_spoolss_enum_printerkey(struct rpc_pipe_client *cli,
+                                         TALLOC_CTX *mem_ctx, int argc,
+                                         const char **argv)
 {
        WERROR result;
        const char *printername;
        const char *keyname = NULL;
-       POLICY_HND hnd;
-       uint16 *keylist = NULL, *curkey;
+       struct policy_handle hnd;
+       const char **key_buffer = NULL;
+       int i;
 
        if (argc < 2 || argc > 3) {
                printf("Usage: %s printername [keyname]\n", argv[0]);
                return WERR_OK;
        }
 
-       if (argc == 3)
+       if (argc == 3) {
                keyname = argv[2];
-       else
+       } else {
                keyname = "";
+       }
 
        /* Open printer handle */
 
@@ -2735,34 +2626,31 @@ static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli,
                                               printername,
                                               SEC_FLAG_MAXIMUM_ALLOWED,
                                               &hnd);
-       if (!W_ERROR_IS_OK(result))
+       if (!W_ERROR_IS_OK(result)) {
                goto done;
+       }
 
        /* Enumerate subkeys */
 
-       result = rpccli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, &keylist, NULL);
+       result = rpccli_spoolss_enumprinterkey(cli, mem_ctx,
+                                              &hnd,
+                                              keyname,
+                                              &key_buffer,
+                                              0);
 
-       if (!W_ERROR_IS_OK(result))
+       if (!W_ERROR_IS_OK(result)) {
                goto done;
-
-       curkey = keylist;
-       while (*curkey != 0) {
-               char *subkey = NULL;
-               rpcstr_pull_talloc(mem_ctx, &subkey, curkey, -1,
-                           STR_TERMINATE);
-               if (!subkey) {
-                       break;
-               }
-               printf("%s\n", subkey);
-               curkey += strlen(subkey) + 1;
        }
 
-done:
+       for (i=0; key_buffer && key_buffer[i]; i++) {
+               printf("%s\n", key_buffer[i]);
+       }
 
-       SAFE_FREE(keylist);
+ done:
 
-       if (is_valid_policy_hnd(&hnd))
+       if (is_valid_policy_hnd(&hnd)) {
                rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
+       }
 
        return result;
 }
@@ -2776,7 +2664,7 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
 {
        const char *printername;
        const char *clientname;
-       POLICY_HND hnd;
+       struct policy_handle hnd;
        WERROR result;
        NTSTATUS status;
        struct spoolss_NotifyOption option;
@@ -2813,21 +2701,21 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
 
        option.types[0].type = PRINTER_NOTIFY_TYPE;
        option.types[0].count = 1;
-       option.types[0].fields = talloc_array(mem_ctx, enum spoolss_Field, 1);
+       option.types[0].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
        if (option.types[0].fields == NULL) {
                result = WERR_NOMEM;
                goto done;
        }
-       option.types[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
+       option.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
 
        option.types[1].type = JOB_NOTIFY_TYPE;
        option.types[1].count = 1;
-       option.types[1].fields = talloc_array(mem_ctx, enum spoolss_Field, 1);
+       option.types[1].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
        if (option.types[1].fields == NULL) {
                result = WERR_NOMEM;
                goto done;
        }
-       option.types[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
+       option.types[1].fields[0].field = JOB_NOTIFY_FIELD_PRINTER_NAME;
 
        clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
        if (!clientname) {
@@ -2860,8 +2748,8 @@ done:
 /****************************************************************************
 ****************************************************************************/
 
-static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
-                             struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
+static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
+                             struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
 {
        union spoolss_PrinterInfo info1, info2;
        WERROR werror;
@@ -2901,8 +2789,8 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
 /****************************************************************************
 ****************************************************************************/
 
-static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
-                                     struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
+static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
+                                     struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
 {
        union spoolss_PrinterInfo info1, info2;
        WERROR werror;
@@ -2976,7 +2864,7 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
        char *printername_path = NULL;
        struct cli_state *cli_server2 = NULL;
        struct rpc_pipe_client *cli2 = NULL;
-       POLICY_HND hPrinter1, hPrinter2;
+       struct policy_handle hPrinter1, hPrinter2;
        NTSTATUS nt_status;
        WERROR werror;
 
@@ -3001,7 +2889,7 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
        if ( !NT_STATUS_IS_OK(nt_status) )
                return WERR_GENERAL_FAILURE;
 
-       nt_status = cli_rpc_pipe_open_noauth(cli_server2, &syntax_spoolss,
+       nt_status = cli_rpc_pipe_open_noauth(cli_server2, &ndr_table_spoolss.syntax_id,
                                             &cli2);
        if (!NT_STATUS_IS_OK(nt_status)) {
                printf("failed to open spoolss pipe on server %s (%s)\n",
@@ -3059,41 +2947,214 @@ done:
        return WERR_OK;
 }
 
+static void display_proc_info1(struct spoolss_PrintProcessorInfo1 *r)
+{
+       printf("print_processor_name: %s\n", r->print_processor_name);
+}
+
+static WERROR cmd_spoolss_enum_procs(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx, int argc,
+                                    const char **argv)
+{
+       WERROR werror;
+       const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
+       uint32_t num_procs, level = 1, i;
+       union spoolss_PrintProcessorInfo *procs;
+
+       /* Parse the command arguments */
+
+       if (argc < 1 || argc > 4) {
+               printf ("Usage: %s [environment] [level]\n", argv[0]);
+               return WERR_OK;
+        }
+
+       if (argc >= 2) {
+               environment = argv[1];
+       }
+
+       if (argc == 3) {
+               level = atoi(argv[2]);
+       }
+
+       /* Enumerate Print Processors */
+
+       werror = rpccli_spoolss_enumprintprocessors(cli, mem_ctx,
+                                                   cli->srv_name_slash,
+                                                   environment,
+                                                   level,
+                                                   0,
+                                                   &num_procs,
+                                                   &procs);
+       if (!W_ERROR_IS_OK(werror))
+               goto done;
+
+       /* Display output */
+
+       for (i = 0; i < num_procs; i++) {
+               switch (level) {
+               case 1:
+                       display_proc_info1(&procs[i].info1);
+                       break;
+               }
+       }
+
+ done:
+       return werror;
+}
+
+static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1 *r)
+{
+       printf("name_array: %s\n", r->name_array);
+}
+
+static WERROR cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client *cli,
+                                              TALLOC_CTX *mem_ctx, int argc,
+                                              const char **argv)
+{
+       WERROR werror;
+       const char *print_processor_name = "winprint";
+       uint32_t num_procs, level = 1, i;
+       union spoolss_PrintProcDataTypesInfo *procs;
+
+       /* Parse the command arguments */
+
+       if (argc < 1 || argc > 4) {
+               printf ("Usage: %s [environment] [level]\n", argv[0]);
+               return WERR_OK;
+        }
+
+       if (argc >= 2) {
+               print_processor_name = argv[1];
+       }
+
+       if (argc == 3) {
+               level = atoi(argv[2]);
+       }
+
+       /* Enumerate Print Processor Data Types */
+
+       werror = rpccli_spoolss_enumprintprocessordatatypes(cli, mem_ctx,
+                                                           cli->srv_name_slash,
+                                                           print_processor_name,
+                                                           level,
+                                                           0,
+                                                           &num_procs,
+                                                           &procs);
+       if (!W_ERROR_IS_OK(werror))
+               goto done;
+
+       /* Display output */
+
+       for (i = 0; i < num_procs; i++) {
+               switch (level) {
+               case 1:
+                       display_proc_data_types_info1(&procs[i].info1);
+                       break;
+               }
+       }
+
+ done:
+       return werror;
+}
+
+static void display_monitor1(const struct spoolss_MonitorInfo1 *r)
+{
+       printf("monitor_name: %s\n", r->monitor_name);
+}
+
+static void display_monitor2(const struct spoolss_MonitorInfo2 *r)
+{
+       printf("monitor_name: %s\n", r->monitor_name);
+       printf("environment: %s\n", r->environment);
+       printf("dll_name: %s\n", r->dll_name);
+}
+
+static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli,
+                                       TALLOC_CTX *mem_ctx, int argc,
+                                       const char **argv)
+{
+       WERROR werror;
+       uint32_t count, level = 1, i;
+       union spoolss_MonitorInfo *info;
+
+       /* Parse the command arguments */
+
+       if (argc > 2) {
+               printf("Usage: %s [level]\n", argv[0]);
+               return WERR_OK;
+       }
+
+       if (argc == 2) {
+               level = atoi(argv[1]);
+       }
+
+       /* Enumerate Print Monitors */
+
+       werror = rpccli_spoolss_enummonitors(cli, mem_ctx,
+                                            cli->srv_name_slash,
+                                            level,
+                                            0,
+                                            &count,
+                                            &info);
+       if (!W_ERROR_IS_OK(werror)) {
+               goto done;
+       }
+
+       /* Display output */
+
+       for (i = 0; i < count; i++) {
+               switch (level) {
+               case 1:
+                       display_monitor1(&info[i].info1);
+                       break;
+               case 2:
+                       display_monitor2(&info[i].info2);
+                       break;
+               }
+       }
+
+ done:
+       return werror;
+}
+
 /* List of commands exported by this module */
 struct cmd_set spoolss_commands[] = {
 
        { "SPOOLSS"  },
 
-       { "adddriver",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver,   &syntax_spoolss, NULL, "Add a print driver",                  "" },
-       { "addprinter",         RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex,       &syntax_spoolss, NULL, "Add a printer",                       "" },
-       { "deldriver",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver,       &syntax_spoolss, NULL, "Delete a printer driver",             "" },
-       { "deldriverex",        RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex,     &syntax_spoolss, NULL, "Delete a printer driver with files",  "" },
-       { "enumdata",           RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data,          &syntax_spoolss, NULL, "Enumerate printer data",              "" },
-       { "enumdataex",         RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex,       &syntax_spoolss, NULL, "Enumerate printer data for a key",    "" },
-       { "enumkey",            RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey,    &syntax_spoolss, NULL, "Enumerate printer keys",              "" },
-       { "enumjobs",           RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs,          &syntax_spoolss, NULL, "Enumerate print jobs",                "" },
-       { "getjob",             RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job,            &syntax_spoolss, NULL, "Get print job",                       "" },
-       { "enumports",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports,         &syntax_spoolss, NULL, "Enumerate printer ports",             "" },
-       { "enumdrivers",        RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers,       &syntax_spoolss, NULL, "Enumerate installed printer drivers", "" },
-       { "enumprinters",       RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers,      &syntax_spoolss, NULL, "Enumerate printers",                  "" },
-       { "getdata",            RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata,     &syntax_spoolss, NULL, "Get print driver data",               "" },
-       { "getdataex",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex,   &syntax_spoolss, NULL, "Get printer driver data with keyname", ""},
-       { "getdriver",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver,          &syntax_spoolss, NULL, "Get print driver information",        "" },
-       { "getdriverdir",       RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir,       &syntax_spoolss, NULL, "Get print driver upload directory",   "" },
-       { "getprinter",         RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter,         &syntax_spoolss, NULL, "Get printer info",                    "" },
-       { "openprinter",        RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex,    &syntax_spoolss, NULL, "Open printer handle",                 "" },
-       { "setdriver",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver,          &syntax_spoolss, NULL, "Set printer driver",                  "" },
-       { "getprintprocdir",    RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir,    &syntax_spoolss, NULL, "Get print processor directory",       "" },
-       { "addform",            RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform,            &syntax_spoolss, NULL, "Add form",                            "" },
-       { "setform",            RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform,            &syntax_spoolss, NULL, "Set form",                            "" },
-       { "getform",            RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform,            &syntax_spoolss, NULL, "Get form",                            "" },
-       { "deleteform",         RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform,         &syntax_spoolss, NULL, "Delete form",                         "" },
-       { "enumforms",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms,         &syntax_spoolss, NULL, "Enumerate forms",                     "" },
-       { "setprinter",         RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter,         &syntax_spoolss, NULL, "Set printer comment",                 "" },
-       { "setprintername",     RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername,     &syntax_spoolss, NULL, "Set printername",                 "" },
-       { "setprinterdata",     RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata,     &syntax_spoolss, NULL, "Set REG_SZ printer data",             "" },
-       { "rffpcnex",           RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex,           &syntax_spoolss, NULL, "Rffpcnex test", "" },
-       { "printercmp",         RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp,         &syntax_spoolss, NULL, "Printer comparison test", "" },
+       { "adddriver",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver,   &ndr_table_spoolss.syntax_id, NULL, "Add a print driver",                  "" },
+       { "addprinter",         RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex,       &ndr_table_spoolss.syntax_id, NULL, "Add a printer",                       "" },
+       { "deldriver",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver,       &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver",             "" },
+       { "deldriverex",        RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex,     &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver with files",  "" },
+       { "enumdata",           RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data,          &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data",              "" },
+       { "enumdataex",         RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex,       &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data for a key",    "" },
+       { "enumkey",            RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey,    &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer keys",              "" },
+       { "enumjobs",           RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs,          &ndr_table_spoolss.syntax_id, NULL, "Enumerate print jobs",                "" },
+       { "getjob",             RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job,            &ndr_table_spoolss.syntax_id, NULL, "Get print job",                       "" },
+       { "enumports",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports,         &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer ports",             "" },
+       { "enumdrivers",        RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers,       &ndr_table_spoolss.syntax_id, NULL, "Enumerate installed printer drivers", "" },
+       { "enumprinters",       RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers,      &ndr_table_spoolss.syntax_id, NULL, "Enumerate printers",                  "" },
+       { "getdata",            RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata,     &ndr_table_spoolss.syntax_id, NULL, "Get print driver data",               "" },
+       { "getdataex",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex,   &ndr_table_spoolss.syntax_id, NULL, "Get printer driver data with keyname", ""},
+       { "getdriver",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver,          &ndr_table_spoolss.syntax_id, NULL, "Get print driver information",        "" },
+       { "getdriverdir",       RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir,       &ndr_table_spoolss.syntax_id, NULL, "Get print driver upload directory",   "" },
+       { "getprinter",         RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter,         &ndr_table_spoolss.syntax_id, NULL, "Get printer info",                    "" },
+       { "openprinter",        RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex,    &ndr_table_spoolss.syntax_id, NULL, "Open printer handle",                 "" },
+       { "setdriver",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver,          &ndr_table_spoolss.syntax_id, NULL, "Set printer driver",                  "" },
+       { "getprintprocdir",    RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir,    &ndr_table_spoolss.syntax_id, NULL, "Get print processor directory",       "" },
+       { "addform",            RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform,            &ndr_table_spoolss.syntax_id, NULL, "Add form",                            "" },
+       { "setform",            RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform,            &ndr_table_spoolss.syntax_id, NULL, "Set form",                            "" },
+       { "getform",            RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform,            &ndr_table_spoolss.syntax_id, NULL, "Get form",                            "" },
+       { "deleteform",         RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform,         &ndr_table_spoolss.syntax_id, NULL, "Delete form",                         "" },
+       { "enumforms",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms,         &ndr_table_spoolss.syntax_id, NULL, "Enumerate forms",                     "" },
+       { "setprinter",         RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter,         &ndr_table_spoolss.syntax_id, NULL, "Set printer comment",                 "" },
+       { "setprintername",     RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername,     &ndr_table_spoolss.syntax_id, NULL, "Set printername",                 "" },
+       { "setprinterdata",     RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata,     &ndr_table_spoolss.syntax_id, NULL, "Set REG_SZ printer data",             "" },
+       { "rffpcnex",           RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex,           &ndr_table_spoolss.syntax_id, NULL, "Rffpcnex test", "" },
+       { "printercmp",         RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp,         &ndr_table_spoolss.syntax_id, NULL, "Printer comparison test", "" },
+       { "enumprocs",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs,         &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors",          "" },
+       { "enumprocdatatypes",  RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" },
+       { "enummonitors",       RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors,      &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" },
 
        { NULL }
 };
index 0f1d4221cab423bdbe2d8cf1e50ac2cea7fd9326..b7be038539dd69c431a0e8f720f84981ccd5ac1c 100644 (file)
@@ -26,7 +26,7 @@ static NTSTATUS cmd_testme(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 {
        struct rpc_pipe_client *lsa_pipe = NULL, *samr_pipe = NULL;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-       POLICY_HND pol;
+       struct policy_handle pol;
 
        d_printf("testme\n");
 
index 9a02c129b5486be1398247b3b619efce516651ad..a202dcc5f3528c2d3c0889576b2fd5c04bdbad70 100644 (file)
@@ -133,7 +133,7 @@ static char *next_command (char **cmdstr)
 
 static void fetch_machine_sid(struct cli_state *cli)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_OK;
        static bool got_domain_sid;
        TALLOC_CTX *mem_ctx;
@@ -868,12 +868,7 @@ out_free:
                goto done;
        }
 
-       if (!get_cmdline_auth_info_got_pass(rpcclient_auth_info)) {
-               char *pass = getpass("Password:");
-               if (pass) {
-                       set_cmdline_auth_info_password(rpcclient_auth_info, pass);
-               }
-       }
+       set_cmdline_auth_info_getpass(rpcclient_auth_info);
 
        if ((server[0] == '/' && server[1] == '/') ||
                        (server[0] == '\\' && server[1] ==  '\\')) {
index d11d3be2d50a371802dd0b31d4d14be79af4e97e..b5c7c74689ac740a896e8cd261399530440bbc59 100644 (file)
@@ -67,14 +67,16 @@ 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,
+m4_include(../source4/min_versions.m4)
+
+SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= $TALLOC_MIN_VERSION,
        [],
        [
                SMB_INCLUDE_MK(../lib/talloc/config.mk)
        ]
 )
 
-SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.3,
+SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= $TDB_MIN_VERSION,
        [],
        [
                m4_include(../lib/tdb/libtdb.m4)
@@ -84,13 +86,13 @@ 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 = $TEVENT_REQUIRED_VERSION,
        [],[m4_include(../lib/tevent/samba.m4)]
 )
 
 SMB_INCLUDE_MK(../lib/tevent/python.mk) 
 
-SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb = 0.9.3,
+SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb = $LDB_REQUIRED_VERSION,
        [
                SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk)
                SMB_INCLUDE_MK(lib/ldb/tools/config.mk)
@@ -152,6 +154,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 9c4ab1eefe628d5ca0b278a0a71f9e08d3e2f37a..5ca3371d80ecbbba993fc617d1ec0ddd731fc4b3 100644 (file)
@@ -35,7 +35,7 @@ for dir in $SRCDIR/locale/*; do
                if test "$mode" = 'install'; then
                        echo "Installing $f as $FNAME"
                        touch "$FNAME"
-                       $MSGFMT "$f" -f -o "$FNAME"
+                       $MSGFMT -f -o "$FNAME" "$f"
                        if test ! -f "$FNAME"; then
                                echo "Cannot install $FNAME. Does $USER have privileges?"
                                exit 1
index a55aafcd0c2c444b7354dfbb339dc09fd4c3df62..ce9d2af4c0d17d1cd1143649a91cc7cf61d5ea24 100755 (executable)
@@ -112,6 +112,7 @@ if test -n "${SAMBA_VERSION_VENDOR_SUFFIX}";then
     SAMBA_VERSION_STRING="${SAMBA_VERSION_STRING}-${SAMBA_VERSION_VENDOR_SUFFIX}"
     if test -n "${SAMBA_VERSION_VENDOR_PATCH}";then
         echo "#define SAMBA_VERSION_VENDOR_PATCH ${SAMBA_VERSION_VENDOR_PATCH}" >> $OUTPUT_FILE
+        echo "#define SAMBA_VERSION_VENDOR_PATCH_STRING \"${SAMBA_VERSION_VENDOR_PATCH}\"" >> $OUTPUT_FILE
         SAMBA_VERSION_STRING="${SAMBA_VERSION_STRING}-${SAMBA_VERSION_VENDOR_PATCH}"
     fi
 fi
@@ -130,7 +131,7 @@ cat >>$OUTPUT_FILE<<CEOF
 #else /* SAMBA_VERSION_VENDOR_FUNCTION */
 #  ifdef SAMBA_VERSION_VENDOR_SUFFIX
 #    ifdef SAMBA_VERSION_VENDOR_PATCH
-#      define SAMBA_VERSION_STRING SAMBA_VERSION_OFFICIAL_STRING "-" SAMBA_VERSION_VENDOR_SUFFIX "-" SAMBA_VERSION_VENDOR_PATCH
+#      define SAMBA_VERSION_STRING SAMBA_VERSION_OFFICIAL_STRING "-" SAMBA_VERSION_VENDOR_SUFFIX "-" SAMBA_VERSION_VENDOR_PATCH_STRING
 #    else /* SAMBA_VERSION_VENDOR_PATCH */
 #      define SAMBA_VERSION_STRING SAMBA_VERSION_OFFICIAL_STRING "-" SAMBA_VERSION_VENDOR_SUFFIX
 #    endif /* SAMBA_VERSION_VENDOR_SUFFIX */
index 94621841f55c1f1e60d7bab570f9dfd4c14e1cef..a430d01a0ee38e3270cc90412fc0ea47cc87c598 100755 (executable)
@@ -104,13 +104,14 @@ SAMBA4SHAREDDIR="$SAMBA4BINDIR/shared"
 export SAMBA4SHAREDDIR
 export SMBTORTURE4
 
-if test x"$LD_LIBRARY_PATH" != x""; then
-       LD_LIBRARY_PATH="$BINDIR:$SAMBA4SHAREDDIR:$LD_LIBRARY_PATH"
-else
-       LD_LIBRARY_PATH="$BINDIR:$SAMBA4SHAREDDIR"
+if [ -z "$LIB_PATH_VAR" ] ; then
+       echo "Warning: LIB_PATH_VAR not set. Using best guess LD_LIBRARY_PATH." >&2
+       LIB_PATH_VAR=LD_LIBRARY_PATH
+       export LIB_PATH_VAR
 fi
-echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
-export LD_LIBRARY_PATH
+
+eval $LIB_PATH_VAR=$BINDIR:$SAMBA4SHAREDDIR:\$$LIB_PATH_VAR
+export $LIB_PATH_VAR
 
 ##
 ## verify that we were built with --enable-socket-wrapper
index 842277b3577623e07b8a4dfdce039de31ee6984a..70c6d34c88566fb00744dd260d3d04e374fc2a8d 100755 (executable)
@@ -27,7 +27,7 @@ tests="$tests UNLINK BROWSE ATTR TRANS2 TORTURE "
 tests="$tests OPLOCK1 OPLOCK2 OPLOCK3"
 tests="$tests DIR DIR1 TCON TCONDEV RW1 RW2 RW3"
 tests="$tests OPEN XCOPY RENAME DELETE PROPERTIES W2K"
-tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE"
+tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE CHAIN1"
 
 skipped1="RANDOMIPC NEGNOWAIT NBENCH ERRMAPEXTRACT TRANS2SCAN NTTRANSSCAN"
 skipped2="DENY1 DENY2 OPENATTR CASETABLE EATEST"
index 6b19e098e5cf0e45fc6bb1d0b0ed1cb721a79c28..cfa4b430ebf271aafd654004c541f4bdc766ecc2 100644 (file)
@@ -347,7 +347,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
                /* If errno is ECANCELED then don't return anything to the
                 * client. */
                if (errno == ECANCELED) {
-                       srv_cancel_sign_response(aio_ex->req->mid);
+                       srv_cancel_sign_response(aio_ex->req->mid, false);
                        return 0;
                }
 
@@ -441,7 +441,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
                /* If errno is ECANCELED then don't return anything to the
                 * client. */
                if (errno == ECANCELED) {
-                       srv_cancel_sign_response(aio_ex->req->mid);
+                       srv_cancel_sign_response(aio_ex->req->mid, false);
                        return 0;
                }
 
@@ -534,7 +534,7 @@ void smbd_aio_complete_mid(unsigned int mid)
        if (!aio_ex) {
                DEBUG(3,("smbd_aio_complete_mid: Can't find record to "
                         "match mid %u.\n", mid));
-               srv_cancel_sign_response(mid);
+               srv_cancel_sign_response(mid, false);
                return;
        }
 
@@ -544,7 +544,7 @@ void smbd_aio_complete_mid(unsigned int mid)
                 * ignore. */
                DEBUG( 3,( "smbd_aio_complete_mid: file closed whilst "
                           "aio outstanding (mid[%u]).\n", mid));
-               srv_cancel_sign_response(mid);
+               srv_cancel_sign_response(mid, false);
                return;
        }
 
index 4b467b0312a5209863e3293ad20a9877ed34ec5f..a52f2d2e96915de7aaf12814f6c307b1bf12ec63 100644 (file)
@@ -140,6 +140,7 @@ find_again:
                return NULL;
        }
        conn->cnum = i;
+       conn->force_group_gid = (gid_t)-1;
 
        bitmap_set(bmap, i);
 
index fe7ba1cc466e2221958242e9c8632078036f1ad7..abffcd2f4fd6cd7305ac02a3ee7ccf22cbb5abac 100644 (file)
@@ -34,6 +34,11 @@ bool can_access_file_acl(struct connection_struct *conn,
        uint32_t access_granted;
        struct security_descriptor *secdesc = NULL;
 
+       if (conn->server_info->utok.uid == 0 || conn->admin_user) {
+               /* I'm sorry sir, I didn't know you were root... */
+               return true;
+       }
+
        status = SMB_VFS_GET_NT_ACL(conn, fname,
                                    (OWNER_SECURITY_INFORMATION |
                                     GROUP_SECURITY_INFORMATION |
index d18b5debe0da46acfeb7126e22e7bb38348f2f88..f20c8512975c573c6987896ce42fb36630aba271 100644 (file)
@@ -211,14 +211,14 @@ struct dcerpc_cmd_state {
        size_t max_read;
 };
 
-static void api_dcerpc_cmd_write_done(struct async_req *subreq);
-static void api_dcerpc_cmd_read_done(struct async_req *subreq);
+static void api_dcerpc_cmd_write_done(struct tevent_req *subreq);
+static void api_dcerpc_cmd_read_done(struct tevent_req *subreq);
 
 static void api_dcerpc_cmd(connection_struct *conn, struct smb_request *req,
                           files_struct *fsp, uint8_t *data, size_t length,
                           size_t max_read)
 {
-       struct async_req *subreq;
+       struct tevent_req *subreq;
        struct dcerpc_cmd_state *state;
 
        if (!fsp_is_np(fsp)) {
@@ -254,14 +254,14 @@ static void api_dcerpc_cmd(connection_struct *conn, struct smb_request *req,
                reply_nterror(req, NT_STATUS_NO_MEMORY);
                return;
        }
-       subreq->async.fn = api_dcerpc_cmd_write_done;
-       subreq->async.priv = talloc_move(conn, &req);
+       tevent_req_set_callback(subreq, api_dcerpc_cmd_write_done,
+                               talloc_move(conn, &req));
 }
 
-static void api_dcerpc_cmd_write_done(struct async_req *subreq)
+static void api_dcerpc_cmd_write_done(struct tevent_req *subreq)
 {
-       struct smb_request *req = talloc_get_type_abort(
-               subreq->async.priv, struct smb_request);
+       struct smb_request *req = tevent_req_callback_data(
+               subreq, struct smb_request);
        struct dcerpc_cmd_state *state = talloc_get_type_abort(
                req->async_priv, struct dcerpc_cmd_state);
        NTSTATUS status;
@@ -290,9 +290,7 @@ static void api_dcerpc_cmd_write_done(struct async_req *subreq)
                reply_nterror(req, NT_STATUS_NO_MEMORY);
                goto send;
        }
-
-       subreq->async.fn = api_dcerpc_cmd_read_done;
-       subreq->async.priv = req;
+       tevent_req_set_callback(subreq, api_dcerpc_cmd_read_done, req);
        return;
 
  send:
@@ -305,10 +303,10 @@ static void api_dcerpc_cmd_write_done(struct async_req *subreq)
        TALLOC_FREE(req);
 }
 
-static void api_dcerpc_cmd_read_done(struct async_req *subreq)
+static void api_dcerpc_cmd_read_done(struct tevent_req *subreq)
 {
-       struct smb_request *req = talloc_get_type_abort(
-               subreq->async.priv, struct smb_request);
+       struct smb_request *req = tevent_req_callback_data(
+               subreq, struct smb_request);
        struct dcerpc_cmd_state *state = talloc_get_type_abort(
                req->async_priv, struct dcerpc_cmd_state);
        NTSTATUS status;
index 86a46505a2f1e4ba228a856179fbdf0c15791a41..9c7fb1914e8716c6f27b90d1f2dd1878871fea26 100644 (file)
@@ -1131,7 +1131,7 @@ void reply_ntcancel(struct smb_request *req)
        START_PROFILE(SMBntcancel);
        remove_pending_change_notify_requests_by_mid(req->mid);
        remove_pending_lock_requests_by_mid(req->mid);
-       srv_cancel_sign_response(req->mid);
+       srv_cancel_sign_response(req->mid, true);
 
        DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", req->mid));
 
index 569c2603192f811aef1c35299bda198a5e0e02ab..d529b009d5086484c5a3727c19412fba4651ca8f 100644 (file)
@@ -76,6 +76,15 @@ static NTSTATUS check_open_rights(struct connection_struct *conn,
 
        *access_granted = 0;
 
+       if (conn->server_info->utok.uid == 0 || conn->admin_user) {
+               /* I'm sorry sir, I didn't know you were root... */
+               *access_granted = access_mask;
+               if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
+                       *access_granted |= FILE_GENERIC_ALL;
+               }
+               return NT_STATUS_OK;
+       }
+
        status = SMB_VFS_GET_NT_ACL(conn, fname,
                        (OWNER_SECURITY_INFORMATION |
                        GROUP_SECURITY_INFORMATION |
@@ -445,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
@@ -456,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));
@@ -2377,6 +2408,14 @@ static NTSTATUS open_directory(connection_struct *conn,
                return status;
        }
 
+       /* We need to support SeSecurityPrivilege for this. */
+       if (access_mask & SEC_RIGHT_SYSTEM_SECURITY) {
+               DEBUG(10, ("open_directory: open on %s "
+                       "failed - SEC_RIGHT_SYSTEM_SECURITY denied.\n",
+                       fname));
+               return NT_STATUS_PRIVILEGE_NOT_HELD;
+       }
+
        switch( create_disposition ) {
                case FILE_OPEN:
 
@@ -2710,7 +2749,7 @@ struct case_semantics_state *set_posix_case_semantics(TALLOC_CTX *mem_ctx,
  * If that works, delete them all by setting the delete on close and close.
  */
 
-static NTSTATUS open_streams_for_delete(connection_struct *conn,
+NTSTATUS open_streams_for_delete(connection_struct *conn,
                                        const char *fname)
 {
        struct stream_struct *stream_info;
@@ -2768,13 +2807,15 @@ static NTSTATUS open_streams_for_delete(connection_struct *conn,
                        goto fail;
                }
 
-               status = create_file_unixpath
-                       (conn,                  /* conn */
+               status = SMB_VFS_CREATE_FILE(
+                        conn,                  /* conn */
                         NULL,                  /* req */
+                        0,                     /* root_dir_fid */
                         streamname,            /* fname */
+                        0,                     /* create_file_flags */
                         DELETE_ACCESS,         /* access_mask */
-                        FILE_SHARE_READ | FILE_SHARE_WRITE
-                        | FILE_SHARE_DELETE,   /* share_access */
+                        (FILE_SHARE_READ |     /* share_access */
+                            FILE_SHARE_WRITE | FILE_SHARE_DELETE),
                         FILE_OPEN,             /* create_disposition*/
                         NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
                         FILE_ATTRIBUTE_NORMAL, /* file_attributes */
@@ -2920,6 +2961,20 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
                status = NT_STATUS_PRIVILEGE_NOT_HELD;
                goto fail;
        }
+#else
+       /* We need to support SeSecurityPrivilege for this. */
+       if (access_mask & SEC_RIGHT_SYSTEM_SECURITY) {
+               status = NT_STATUS_PRIVILEGE_NOT_HELD;
+               goto fail;
+       }
+       /* Don't allow a SACL set from an NTtrans create until we
+        * support SeSecurityPrivilege. */
+       if (!VALID_STAT(sbuf) &&
+                       lp_nt_acl_support(SNUM(conn)) &&
+                       sd && (sd->sacl != NULL)) {
+               status = NT_STATUS_PRIVILEGE_NOT_HELD;
+               goto fail;
+       }
 #endif
 
        if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
index 6fd4031f3d60ba4b9fe3e2068f97f2354a5b6c0b..2686cf41d93a30137e44c260270a49f66bf323bd 100644 (file)
@@ -148,14 +148,14 @@ struct pipe_write_state {
        size_t numtowrite;
 };
 
-static void pipe_write_done(struct async_req *subreq);
+static void pipe_write_done(struct tevent_req *subreq);
 
 void reply_pipe_write(struct smb_request *req)
 {
        files_struct *fsp = file_fsp(req, SVAL(req->vwv+0, 0));
        const uint8_t *data;
        struct pipe_write_state *state;
-       struct async_req *subreq;
+       struct tevent_req *subreq;
 
        if (!fsp_is_np(fsp)) {
                reply_doserror(req, ERRDOS, ERRbadfid);
@@ -188,14 +188,14 @@ void reply_pipe_write(struct smb_request *req)
                reply_nterror(req, NT_STATUS_NO_MEMORY);
                return;
        }
-       subreq->async.fn = pipe_write_done;
-       subreq->async.priv = talloc_move(req->conn, &req);
+       tevent_req_set_callback(subreq, pipe_write_done,
+                               talloc_move(req->conn, &req));
 }
 
-static void pipe_write_done(struct async_req *subreq)
+static void pipe_write_done(struct tevent_req *subreq)
 {
-       struct smb_request *req = talloc_get_type_abort(
-               subreq->async.priv, struct smb_request);
+       struct smb_request *req = tevent_req_callback_data(
+               subreq, struct smb_request);
        struct pipe_write_state *state = talloc_get_type_abort(
                req->async_priv, struct pipe_write_state);
        NTSTATUS status;
@@ -235,7 +235,7 @@ struct pipe_write_andx_state {
        size_t numtowrite;
 };
 
-static void pipe_write_andx_done(struct async_req *subreq);
+static void pipe_write_andx_done(struct tevent_req *subreq);
 
 void reply_pipe_write_and_X(struct smb_request *req)
 {
@@ -243,7 +243,7 @@ void reply_pipe_write_and_X(struct smb_request *req)
        int smb_doff = SVAL(req->vwv+11, 0);
        uint8_t *data;
        struct pipe_write_andx_state *state;
-       struct async_req *subreq;
+       struct tevent_req *subreq;
 
        if (!fsp_is_np(fsp)) {
                reply_doserror(req, ERRDOS, ERRbadfid);
@@ -297,14 +297,14 @@ void reply_pipe_write_and_X(struct smb_request *req)
                reply_nterror(req, NT_STATUS_NO_MEMORY);
                return;
        }
-       subreq->async.fn = pipe_write_andx_done;
-       subreq->async.priv = talloc_move(req->conn, &req);
+       tevent_req_set_callback(subreq, pipe_write_andx_done,
+                               talloc_move(req->conn, &req));
 }
 
-static void pipe_write_andx_done(struct async_req *subreq)
+static void pipe_write_andx_done(struct tevent_req *subreq)
 {
-       struct smb_request *req = talloc_get_type_abort(
-               subreq->async.priv, struct smb_request);
+       struct smb_request *req = tevent_req_callback_data(
+               subreq, struct smb_request);
        struct pipe_write_andx_state *state = talloc_get_type_abort(
                req->async_priv, struct pipe_write_andx_state);
        NTSTATUS status;
@@ -340,14 +340,14 @@ struct pipe_read_andx_state {
        int smb_maxcnt;
 };
 
-static void pipe_read_andx_done(struct async_req *subreq);
+static void pipe_read_andx_done(struct tevent_req *subreq);
 
 void reply_pipe_read_and_X(struct smb_request *req)
 {
        files_struct *fsp = file_fsp(req, SVAL(req->vwv+0, 0));
        uint8_t *data;
        struct pipe_read_andx_state *state;
-       struct async_req *subreq;
+       struct tevent_req *subreq;
 
        /* we don't use the offset given to use for pipe reads. This
            is deliberate, instead we always return the next lump of
@@ -392,14 +392,14 @@ void reply_pipe_read_and_X(struct smb_request *req)
                reply_nterror(req, NT_STATUS_NO_MEMORY);
                return;
        }
-       subreq->async.fn = pipe_read_andx_done;
-       subreq->async.priv = talloc_move(req->conn, &req);
+       tevent_req_set_callback(subreq, pipe_read_andx_done,
+                               talloc_move(req->conn, &req));
 }
 
-static void pipe_read_andx_done(struct async_req *subreq)
+static void pipe_read_andx_done(struct tevent_req *subreq)
 {
-       struct smb_request *req = talloc_get_type_abort(
-               subreq->async.priv, struct smb_request);
+       struct smb_request *req = tevent_req_callback_data(
+               subreq, struct smb_request);
        struct pipe_read_andx_state *state = talloc_get_type_abort(
                req->async_priv, struct pipe_read_andx_state);
        NTSTATUS status;
index 22e4c1aad7fb6b50ef9f0bb633f9b68e3933f6da..8b560bd8ca64b87dd098e3bc1b274cfd19859fb6 100644 (file)
@@ -72,11 +72,16 @@ static NTSTATUS check_path_syntax_internal(char *path,
                        }
                }
 
-               if (!stream_started && *s == ':') {
+               if (!posix_path && !stream_started && *s == ':') {
                        if (*p_last_component_contains_wcard) {
                                return NT_STATUS_OBJECT_NAME_INVALID;
                        }
-                       /* stream names allow more characters than file names */
+                       /* Stream names allow more characters than file names.
+                          We're overloading posix_path here to allow a wider
+                          range of characters. If stream_started is true this
+                          is still a Windows path even if posix_path is true.
+                          JRA.
+                       */
                        stream_started = true;
                        start_of_name_component = false;
                        posix_path = true;
@@ -2859,6 +2864,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 +2965,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 +3000,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 +3132,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 +3174,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 +3189,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 +3202,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 +3404,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 +3492,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 +3504,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 +3546,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 +3608,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 +3631,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 +3641,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 +3699,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 +3721,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 +3729,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 +3751,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 +3775,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 +3802,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 +3828,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 +3846,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 +3857,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 +3881,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 +3916,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 +3939,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 +3956,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 +3975,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 +4075,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 +4178,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 +4200,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 +4208,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 +4228,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 +4481,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 +4508,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 +4541,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 538e04938e917c6e7434783ba35a67acf643917f..d27f98281b388c527638eef087137a9be55f7731 100644 (file)
@@ -654,52 +654,16 @@ static void smbd_parent_loop(struct smbd_parent_context *parent)
 {
        /* now accept incoming connections - forking a new process
           for each incoming connection */
-       DEBUG(2,("waiting for a connection\n"));
+       DEBUG(2,("waiting for connections\n"));
        while (1) {
-               struct timeval now, idle_timeout;
-               fd_set r_fds, w_fds;
-               int maxfd = 0;
-               int num;
+               int ret;
                TALLOC_CTX *frame = talloc_stackframe();
 
-               if (run_events(smbd_event_context(), 0, NULL, NULL)) {
-                       TALLOC_FREE(frame);
-                       continue;
-               }
-
-               idle_timeout = timeval_zero();
-
-               FD_ZERO(&w_fds);
-               FD_ZERO(&r_fds);
-               GetTimeOfDay(&now);
-
-               event_add_to_select_args(smbd_event_context(), &now,
-                                        &r_fds, &w_fds, &idle_timeout,
-                                        &maxfd);
-
-               num = sys_select(maxfd+1,&r_fds,&w_fds,NULL,
-                                timeval_is_zero(&idle_timeout) ?
-                                NULL : &idle_timeout);
-
-               /* check if we need to reload services */
-               check_reload(time(NULL));
-
-               if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) {
-                       TALLOC_FREE(frame);
-                       continue;
+               ret = tevent_loop_once(smbd_event_context());
+               if (ret != 0) {
+                       exit_server_cleanly("tevent_loop_once() error");
                }
 
-               /* socket error */
-               if (num < 0)
-                       exit_server_cleanly("socket error");
-
-               /* If the idle timeout fired and we don't have any connected
-                * users, exit gracefully. We should be running under a process
-                * controller that will restart us if necessry.
-                */
-               if (num == 0 && count_all_current_connections() == 0) {
-                       exit_server_cleanly("idle timeout");
-               }
                TALLOC_FREE(frame);
        } /* end while 1 */
 
index dcdd69f997cea0861ec7c539751ab31740331384..eb16a2601e312e76d90e63f3401fe781cf42c356 100644 (file)
@@ -833,6 +833,14 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
                        *pstatus = status;
                        return NULL;
                }
+
+               /*
+                * We need to cache this gid, to use within
+                * change_to_user() separately from the conn->server_info
+                * struct. We only use conn->server_info directly if
+                * "force_user" was set.
+                */
+               conn->force_group_gid = conn->server_info->utok.gid;
        }
 
        conn->vuid = (vuser != NULL) ? vuser->vuid : UID_FIELD_INVALID;
index 4f059bdb59894f9efd00ce94e3b9dc2a4f7c786d..f8c55b1b8f8fbe4e6b19c2149a1a28ec9f5410ec 100644 (file)
@@ -254,6 +254,8 @@ bool change_to_user(connection_struct *conn, uint16 vuid)
 
        if((group_c = *lp_force_group(snum))) {
 
+               SMB_ASSERT(conn->force_group_gid != (gid_t)-1);
+
                if(group_c == '+') {
 
                        /*
@@ -266,15 +268,18 @@ bool change_to_user(connection_struct *conn, uint16 vuid)
                        int i;
                        for (i = 0; i < num_groups; i++) {
                                if (group_list[i]
-                                   == conn->server_info->utok.gid) {
-                                       gid = conn->server_info->utok.gid;
+                                   == conn->force_group_gid) {
+                                       conn->server_info->utok.gid =
+                                               conn->force_group_gid;
+                                       gid = conn->force_group_gid;
                                        gid_to_sid(&conn->server_info->ptok
                                                   ->user_sids[1], gid);
                                        break;
                                }
                        }
                } else {
-                       gid = conn->server_info->utok.gid;
+                       conn->server_info->utok.gid = conn->force_group_gid;
+                       gid = conn->force_group_gid;
                        gid_to_sid(&conn->server_info->ptok->user_sids[1],
                                   gid);
                }
index db89b05603aea293f5c6a079b6b28599eed4ec9f..6029eb072781d8cc1670385009b2ad0f1d3644ae 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,
@@ -5496,11 +5613,11 @@ static bool run_local_memcache(int dummy)
        return ret;
 }
 
-static void wbclient_done(struct async_req *req)
+static void wbclient_done(struct tevent_req *req)
 {
        wbcErr wbc_err;
        struct winbindd_response *wb_resp;
-       int *i = (int *)req->async.priv;
+       int *i = (int *)tevent_req_callback_data_void(req);
 
        wbc_err = wb_trans_recv(req, req, &wb_resp);
        TALLOC_FREE(req);
@@ -5537,14 +5654,13 @@ static bool run_local_wbclient(int dummy)
                        goto fail;
                }
                for (j=0; j<5; j++) {
-                       struct async_req *req;
+                       struct tevent_req *req;
                        req = wb_trans_send(ev, ev, wb_ctx[i],
                                            (j % 2) == 0, &wb_req);
                        if (req == NULL) {
                                goto fail;
                        }
-                       req->async.fn = wbclient_done;
-                       req->async.priv = &i;
+                       tevent_req_set_callback(req, wbclient_done, &i);
                }
        }
 
@@ -5690,6 +5806,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 d483198a9ed5807d43ef8a541d2f7d2bcddff09f..7823a982195f232b45b5a7adef804c9f5dfd63e7 100644 (file)
@@ -272,7 +272,7 @@ static bool search_maxrid(struct pdb_search *search, const char *type,
        num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
        for (i=0; i<num_entries; i++)
                *max_rid = MAX(*max_rid, entries[i].rid);
-       pdb_search_destroy(search);
+       TALLOC_FREE(search);
        return true;
 }
 
@@ -280,13 +280,14 @@ static uint32 get_maxrid(void)
 {
        uint32 max_rid = 0;
 
-       if (!search_maxrid(pdb_search_users(0), "users", &max_rid))
+       if (!search_maxrid(pdb_search_users(talloc_tos(), 0), "users", &max_rid))
                return 0;
 
-       if (!search_maxrid(pdb_search_groups(), "groups", &max_rid))
+       if (!search_maxrid(pdb_search_groups(talloc_tos()), "groups", &max_rid))
                return 0;
 
-       if (!search_maxrid(pdb_search_aliases(get_global_sam_sid()),
+       if (!search_maxrid(pdb_search_aliases(talloc_tos(),
+                                             get_global_sam_sid()),
                           "aliases", &max_rid))
                return 0;
 
index 58bbb70ce67824c8daaf47439f2bf81275b7914a..2a666194381cd8fa3da5941ac893023485125526 100644 (file)
@@ -1662,7 +1662,7 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char *
        SAFE_FREE(srv_cn_escaped);
        SAFE_FREE(printername_escaped);
 
-       nt_status = cli_rpc_pipe_open_noauth(cli, &syntax_spoolss, &pipe_hnd);
+       nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_spoolss.syntax_id, &pipe_hnd);
        if (!NT_STATUS_IS_OK(nt_status)) {
                d_fprintf(stderr, "Unable to open a connnection to the spoolss pipe on %s\n",
                         servername);
index 05b552c00def11f67cdfb313ac7c719c2a814a43..38a2553e53a1280e51aeec563f95937e42c9886b 100644 (file)
@@ -331,12 +331,6 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
                         "would import the following configuration:\n\n");
        }
 
-       werr = smbconf_transaction_start(conf_ctx);
-       if (!W_ERROR_IS_OK(werr)) {
-               d_printf("error starting transaction: %s\n", win_errstr(werr));
-               goto done;
-       }
-
        if (servicename != NULL) {
                struct smbconf_service *service = NULL;
 
@@ -366,12 +360,45 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
                                goto cancel;
                        }
                }
+
+               /*
+                * Wrap the importing of shares into a transaction,
+                * but only 100 at a time, in order to serve memory.
+                * The allocated memory accumulates across the actions
+                * within the transaction, and for me, some 1500
+                * imported shares, the MAX_TALLOC_SIZE of 256 MB
+                * was exceeded.
+                */
+               werr = smbconf_transaction_start(conf_ctx);
+               if (!W_ERROR_IS_OK(werr)) {
+                       d_printf("error starting transaction: %s\n",
+                                win_errstr(werr));
+                       goto done;
+               }
+
                for (sidx = 0; sidx < num_shares; sidx++) {
                        werr = import_process_service(c, conf_ctx,
                                                      services[sidx]);
                        if (!W_ERROR_IS_OK(werr)) {
                                goto cancel;
                        }
+
+                       if (sidx % 100) {
+                               continue;
+                       }
+
+                       werr = smbconf_transaction_commit(conf_ctx);
+                       if (!W_ERROR_IS_OK(werr)) {
+                               d_printf("error committing transaction: %s\n",
+                                        win_errstr(werr));
+                               goto done;
+                       }
+                       werr = smbconf_transaction_start(conf_ctx);
+                       if (!W_ERROR_IS_OK(werr)) {
+                               d_printf("error starting transaction: %s\n",
+                                        win_errstr(werr));
+                               goto done;
+                       }
                }
        }
 
index c54d4794133950c0292ad48276071acce9931608..d83fb44abad7cef5fcb86b3683bed498e3313fc4 100644 (file)
@@ -55,7 +55,7 @@ NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                                   const char **domain_name)
 {
        struct rpc_pipe_client *lsa_pipe;
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_OK;
        union lsa_PolicyInformation *info = NULL;
 
@@ -470,7 +470,7 @@ NTSTATUS rpc_info_internals(struct net_context *c,
                        int argc,
                        const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        union samr_DomainInfo *info = NULL;
        fstring sid_str;
@@ -989,10 +989,10 @@ static NTSTATUS rpc_sh_handle_user(struct net_context *c,
                                           TALLOC_CTX *mem_ctx,
                                           struct rpc_sh_ctx *ctx,
                                           struct rpc_pipe_client *pipe_hnd,
-                                          POLICY_HND *user_hnd,
+                                          struct policy_handle *user_hnd,
                                           int argc, const char **argv))
 {
-       POLICY_HND connect_pol, domain_pol, user_pol;
+       struct policy_handle connect_pol, domain_pol, user_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        DOM_SID sid;
        uint32 rid;
@@ -1073,7 +1073,7 @@ static NTSTATUS rpc_sh_user_show_internals(struct net_context *c,
                                           TALLOC_CTX *mem_ctx,
                                           struct rpc_sh_ctx *ctx,
                                           struct rpc_pipe_client *pipe_hnd,
-                                          POLICY_HND *user_hnd,
+                                          struct policy_handle *user_hnd,
                                           int argc, const char **argv)
 {
        NTSTATUS result;
@@ -1124,7 +1124,7 @@ static NTSTATUS rpc_sh_user_str_edit_internals(struct net_context *c,
                                               TALLOC_CTX *mem_ctx,
                                               struct rpc_sh_ctx *ctx,
                                               struct rpc_pipe_client *pipe_hnd,
-                                              POLICY_HND *user_hnd,
+                                              struct policy_handle *user_hnd,
                                               int argc, const char **argv)
 {
        NTSTATUS result;
@@ -1209,7 +1209,7 @@ static NTSTATUS rpc_sh_user_flag_edit_internals(struct net_context *c,
                                                TALLOC_CTX *mem_ctx,
                                                struct rpc_sh_ctx *ctx,
                                                struct rpc_pipe_client *pipe_hnd,
-                                               POLICY_HND *user_hnd,
+                                               struct policy_handle *user_hnd,
                                                int argc, const char **argv)
 {
        NTSTATUS result;
@@ -1386,7 +1386,7 @@ static NTSTATUS rpc_group_delete_internals(struct net_context *c,
                                        int argc,
                                        const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, group_pol, user_pol;
+       struct policy_handle connect_pol, domain_pol, group_pol, user_pol;
        bool group_is_primary = false;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32_t group_rid;
@@ -1658,7 +1658,7 @@ static NTSTATUS get_sid_from_name(struct cli_state *cli,
        DOM_SID *sids = NULL;
        enum lsa_SidType *types = NULL;
        struct rpc_pipe_client *pipe_hnd;
-       POLICY_HND lsa_pol;
+       struct policy_handle lsa_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
 
        result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
@@ -1710,10 +1710,10 @@ static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
                                const DOM_SID *group_sid,
                                const char *member)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result;
        uint32 group_rid;
-       POLICY_HND group_pol;
+       struct policy_handle group_pol;
 
        struct samr_Ids rids, rid_types;
        struct lsa_String lsa_acct_name;
@@ -1784,10 +1784,10 @@ static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
                                const DOM_SID *alias_sid,
                                const char *member)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result;
        uint32 alias_rid;
-       POLICY_HND alias_pol;
+       struct policy_handle alias_pol;
 
        DOM_SID member_sid;
        enum lsa_SidType member_type;
@@ -1918,10 +1918,10 @@ static NTSTATUS rpc_del_groupmem(struct net_context *c,
                                const DOM_SID *group_sid,
                                const char *member)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result;
        uint32 group_rid;
-       POLICY_HND group_pol;
+       struct policy_handle group_pol;
 
        struct samr_Ids rids, rid_types;
        struct lsa_String lsa_acct_name;
@@ -1986,10 +1986,10 @@ static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
                                const DOM_SID *alias_sid,
                                const char *member)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result;
        uint32 alias_rid;
-       POLICY_HND alias_pol;
+       struct policy_handle alias_pol;
 
        DOM_SID member_sid;
        enum lsa_SidType member_type;
@@ -2136,7 +2136,7 @@ static NTSTATUS rpc_group_list_internals(struct net_context *c,
                                        int argc,
                                        const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
        struct samr_SamArray *groups = NULL;
@@ -2259,7 +2259,7 @@ static NTSTATUS rpc_group_list_internals(struct net_context *c,
 
                        if (c->opt_long_list_entries) {
 
-                               POLICY_HND alias_pol;
+                               struct policy_handle alias_pol;
                                union samr_AliasInfo *info = NULL;
 
                                if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
@@ -2318,7 +2318,7 @@ static NTSTATUS rpc_group_list_internals(struct net_context *c,
 
                        if (c->opt_long_list_entries) {
 
-                               POLICY_HND alias_pol;
+                               struct policy_handle alias_pol;
                                union samr_AliasInfo *info = NULL;
 
                                if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
@@ -2362,11 +2362,11 @@ static NTSTATUS rpc_list_group_members(struct net_context *c,
                                        TALLOC_CTX *mem_ctx,
                                        const char *domain_name,
                                        const DOM_SID *domain_sid,
-                                       POLICY_HND *domain_pol,
+                                       struct policy_handle *domain_pol,
                                        uint32 rid)
 {
        NTSTATUS result;
-       POLICY_HND group_pol;
+       struct policy_handle group_pol;
        uint32 num_members, *group_rids;
        int i;
        struct samr_RidTypeArray *rids = NULL;
@@ -2437,12 +2437,12 @@ static NTSTATUS rpc_list_group_members(struct net_context *c,
 static NTSTATUS rpc_list_alias_members(struct net_context *c,
                                        struct rpc_pipe_client *pipe_hnd,
                                        TALLOC_CTX *mem_ctx,
-                                       POLICY_HND *domain_pol,
+                                       struct policy_handle *domain_pol,
                                        uint32 rid)
 {
        NTSTATUS result;
        struct rpc_pipe_client *lsa_pipe;
-       POLICY_HND alias_pol, lsa_pol;
+       struct policy_handle alias_pol, lsa_pol;
        uint32 num_members;
        DOM_SID *alias_sids;
        char **domains;
@@ -2545,7 +2545,7 @@ static NTSTATUS rpc_group_members_internals(struct net_context *c,
                                        const char **argv)
 {
        NTSTATUS result;
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        struct samr_Ids rids, rid_types;
        struct lsa_String lsa_acct_name;
 
@@ -3299,7 +3299,7 @@ static bool sync_files(struct copy_clistate *cp_clistate, const char *mask)
 
        DEBUG(3,("calling cli_list with mask: %s\n", mask));
 
-       if ( !cli_resolve_path(talloc_tos(), "", cp_clistate->cli_share_src,
+       if ( !cli_resolve_path(talloc_tos(), "", NULL, cp_clistate->cli_share_src,
                                mask, &targetcli, &targetpath ) ) {
                d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n", 
                        mask, cli_errstr(cp_clistate->cli_share_src));
@@ -3752,13 +3752,13 @@ static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
 
 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
                                        TALLOC_CTX *mem_ctx,
-                                       POLICY_HND *connect_pol,
+                                       struct policy_handle *connect_pol,
                                        const DOM_SID *domain_sid)
 {
        uint32 start_idx, max_entries, num_entries, i;
        struct samr_SamArray *groups = NULL;
        NTSTATUS result;
-       POLICY_HND domain_pol;
+       struct policy_handle domain_pol;
 
        /* Get domain policy handle */
 
@@ -3782,7 +3782,7 @@ static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
                                                       &num_entries);
                for (i = 0; i < num_entries; i++) {
 
-                       POLICY_HND alias_pol;
+                       struct policy_handle alias_pol;
                        struct full_alias alias;
                        struct lsa_SidArray sid_array;
                        int j;
@@ -3847,7 +3847,7 @@ static NTSTATUS rpc_aliaslist_dump(struct net_context *c,
 {
        int i;
        NTSTATUS result;
-       POLICY_HND lsa_pol;
+       struct policy_handle lsa_pol;
 
        result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true,
                                     SEC_RIGHTS_MAXIMUM_ALLOWED,
@@ -3912,7 +3912,7 @@ static NTSTATUS rpc_aliaslist_internals(struct net_context *c,
                                        const char **argv)
 {
        NTSTATUS result;
-       POLICY_HND connect_pol;
+       struct policy_handle connect_pol;
 
        result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
                                      pipe_hnd->desthost,
@@ -5149,7 +5149,7 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c,
                                                int argc,
                                                const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, user_pol;
+       struct policy_handle connect_pol, domain_pol, user_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        char *acct_name;
        struct lsa_String lsa_acct_name;
@@ -5306,7 +5306,7 @@ static NTSTATUS rpc_trustdom_del_internals(struct net_context *c,
                                        int argc,
                                        const char **argv)
 {
-       POLICY_HND connect_pol, domain_pol, user_pol;
+       struct policy_handle connect_pol, domain_pol, user_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        char *acct_name;
        DOM_SID trust_acct_sid;
@@ -5495,7 +5495,7 @@ static int rpc_trustdom_establish(struct net_context *c, int argc,
        struct cli_state *cli = NULL;
        struct sockaddr_storage server_ss;
        struct rpc_pipe_client *pipe_hnd = NULL;
-       POLICY_HND connect_hnd;
+       struct policy_handle connect_hnd;
        TALLOC_CTX *mem_ctx;
        NTSTATUS nt_status;
        DOM_SID *domain_sid;
@@ -5731,7 +5731,7 @@ static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name)
 
 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
                                      TALLOC_CTX *mem_ctx,
-                                     POLICY_HND *pol,
+                                     struct policy_handle *pol,
                                      DOM_SID dom_sid,
                                      const char *trusted_dom_name)
 {
@@ -5797,7 +5797,7 @@ static int rpc_trustdom_vampire(struct net_context *c, int argc,
        NTSTATUS nt_status;
        const char *domain_name = NULL;
        DOM_SID *queried_dom_sid;
-       POLICY_HND connect_hnd;
+       struct policy_handle connect_hnd;
        union lsa_PolicyInformation *info = NULL;
 
        /* trusted domains listing variables */
@@ -5950,7 +5950,7 @@ static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv)
        DOM_SID *queried_dom_sid;
        fstring padding;
        int ascii_dom_name_len;
-       POLICY_HND connect_hnd;
+       struct policy_handle connect_hnd;
        union lsa_PolicyInformation *info = NULL;
 
        /* trusted domains listing variables */
@@ -5960,7 +5960,7 @@ static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv)
        fstring pdc_name;
 
        /* trusting domains listing variables */
-       POLICY_HND domain_hnd;
+       struct policy_handle domain_hnd;
        struct samr_SamArray *trusts = NULL;
 
        if (c->display_usage) {
@@ -6421,30 +6421,30 @@ static int rpc_printer_migrate_all(struct net_context *c, int argc,
                return -1;
        }
 
-       ret = run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                              rpc_printer_migrate_printers_internals, argc,
                              argv);
        if (ret)
                return ret;
 
-       ret = run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                              rpc_printer_migrate_drivers_internals, argc,
                              argv);
        if (ret)
                return ret;
 
-       ret = run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                              rpc_printer_migrate_forms_internals, argc, argv);
        if (ret)
                return ret;
 
-       ret = run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                              rpc_printer_migrate_settings_internals, argc,
                              argv);
        if (ret)
                return ret;
 
-       return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_migrate_security_internals, argc,
                               argv);
 
@@ -6475,7 +6475,7 @@ static int rpc_printer_migrate_drivers(struct net_context *c, int argc,
                return -1;
        }
 
-       return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_migrate_drivers_internals,
                               argc, argv);
 }
@@ -6505,7 +6505,7 @@ static int rpc_printer_migrate_forms(struct net_context *c, int argc,
                return -1;
        }
 
-       return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_migrate_forms_internals,
                               argc, argv);
 }
@@ -6535,7 +6535,7 @@ static int rpc_printer_migrate_printers(struct net_context *c, int argc,
                return -1;
        }
 
-       return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_migrate_printers_internals,
                               argc, argv);
 }
@@ -6565,7 +6565,7 @@ static int rpc_printer_migrate_security(struct net_context *c, int argc,
                return -1;
        }
 
-       return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_migrate_security_internals,
                               argc, argv);
 }
@@ -6595,7 +6595,7 @@ static int rpc_printer_migrate_settings(struct net_context *c, int argc,
                return -1;
        }
 
-       return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_migrate_settings_internals,
                               argc, argv);
 }
@@ -6691,7 +6691,7 @@ static int rpc_printer_list(struct net_context *c, int argc, const char **argv)
                return 0;
        }
 
-       return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_list_internals,
                               argc, argv);
 }
@@ -6716,7 +6716,7 @@ static int rpc_printer_driver_list(struct net_context *c, int argc,
                return 0;
        }
 
-       return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_driver_list_internals,
                               argc, argv);
 }
@@ -6741,7 +6741,7 @@ static int rpc_printer_publish_publish(struct net_context *c, int argc,
                return 0;
        }
 
-       return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_publish_publish_internals,
                               argc, argv);
 }
@@ -6765,7 +6765,7 @@ static int rpc_printer_publish_update(struct net_context *c, int argc, const cha
                return 0;
        }
 
-       return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_publish_update_internals,
                               argc, argv);
 }
@@ -6790,7 +6790,7 @@ static int rpc_printer_publish_unpublish(struct net_context *c, int argc,
                return 0;
        }
 
-       return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_publish_unpublish_internals,
                               argc, argv);
 }
@@ -6815,7 +6815,7 @@ static int rpc_printer_publish_list(struct net_context *c, int argc,
                return 0;
        }
 
-       return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+       return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_publish_list_internals,
                               argc, argv);
 }
@@ -6880,7 +6880,7 @@ static int rpc_printer_publish(struct net_context *c, int argc,
                        net_display_usage_from_functable(func);
                        return 0;
                }
-               return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+               return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_publish_list_internals,
                               argc, argv);
        }
@@ -6983,7 +6983,7 @@ int net_rpc_printer(struct net_context *c, int argc, const char **argv)
                        net_display_usage_from_functable(func);
                        return 0;
                }
-               return run_rpc_command(c, NULL, &syntax_spoolss, 0,
+               return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
                               rpc_printer_list_internals,
                               argc, argv);
        }
index dc4c796c178bdab843ad60dbd16cd43866f407e4..aa7fc7c394dd28a37a3c843326ecfe17110ee6cf 100644 (file)
@@ -70,7 +70,7 @@ static NTSTATUS rpc_audit_get_internal(struct net_context *c,
                                       int argc,
                                       const char **argv)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        union lsa_PolicyInformation *info = NULL;
        int i;
@@ -138,7 +138,7 @@ static NTSTATUS rpc_audit_set_internal(struct net_context *c,
                                       int argc,
                                       const char **argv)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        union lsa_PolicyInformation *info = NULL;
        uint32_t audit_policy, audit_category;
@@ -224,7 +224,7 @@ static NTSTATUS rpc_audit_enable_internal_ext(struct rpc_pipe_client *pipe_hnd,
                                              const char **argv,
                                              bool enable)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        union lsa_PolicyInformation *info = NULL;
 
@@ -308,7 +308,7 @@ static NTSTATUS rpc_audit_list_internal(struct net_context *c,
                                        int argc,
                                        const char **argv)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        union lsa_PolicyInformation *info = NULL;
        int i;
index 1c45d0c51589cf1aa41199eb315119a9715bed61..7f3515ce751ea2e9c0d90f551429aef4de33d3de 100644 (file)
@@ -141,7 +141,7 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
 
        /* rpc variables */
 
-       POLICY_HND lsa_pol, sam_pol, domain_pol, user_pol;
+       struct policy_handle lsa_pol, sam_pol, domain_pol, user_pol;
        DOM_SID *domain_sid;
        uint32 user_rid;
 
index 8116764d9b34f8d4c7accca3d040213b41ae952a..b25c8977703aee63bbb2178e474b1c6b52334a4e 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Samba Unix/Linux SMB client library
    Distributed SMB/CIFS Server Management Utility
-   Copyright (C) 2004 Guenther Deschner (gd@samba.org)
+   Copyright (C) 2004,2009 Guenther Deschner (gd@samba.org)
 
    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
@@ -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;
@@ -734,7 +683,7 @@ static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd,
                                        const char *printername,
                                        uint32 access_required,
                                        const char *username,
-                                       POLICY_HND *hnd)
+                                       struct policy_handle *hnd)
 {
        WERROR result;
        fstring printername2;
@@ -773,7 +722,7 @@ static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd,
 
 static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd,
                                TALLOC_CTX *mem_ctx,
-                               POLICY_HND *hnd,
+                               struct policy_handle *hnd,
                                uint32 level,
                                union spoolss_PrinterInfo *info)
 {
@@ -795,7 +744,7 @@ static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd,
 
 static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd,
                                TALLOC_CTX *mem_ctx,
-                               POLICY_HND *hnd,
+                               struct policy_handle *hnd,
                                uint32 level,
                                union spoolss_PrinterInfo *info)
 {
@@ -866,14 +815,23 @@ static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd,
 
 
 static bool net_spoolss_setprinterdata(struct rpc_pipe_client *pipe_hnd,
-                                       TALLOC_CTX *mem_ctx,
-                                       POLICY_HND *hnd,
-                                       REGISTRY_VALUE *value)
+                                      TALLOC_CTX *mem_ctx,
+                                      struct policy_handle *hnd,
+                                      const char *value_name,
+                                      enum winreg_Type type,
+                                      union spoolss_PrinterData data)
 {
        WERROR result;
+       NTSTATUS status;
 
        /* setprinterdata call */
-       result = rpccli_spoolss_setprinterdata(pipe_hnd, mem_ctx, hnd, value);
+       status = rpccli_spoolss_SetPrinterData(pipe_hnd, mem_ctx,
+                                              hnd,
+                                              value_name,
+                                              type,
+                                              data,
+                                              0, /* autocalculated */
+                                              &result);
 
        if (!W_ERROR_IS_OK(result)) {
                printf ("unable to set printerdata: %s\n", win_errstr(result));
@@ -886,14 +844,14 @@ static bool net_spoolss_setprinterdata(struct rpc_pipe_client *pipe_hnd,
 
 static bool net_spoolss_enumprinterkey(struct rpc_pipe_client *pipe_hnd,
                                        TALLOC_CTX *mem_ctx,
-                                       POLICY_HND *hnd,
+                                       struct policy_handle *hnd,
                                        const char *keyname,
-                                       uint16 **keylist)
+                                       const char ***keylist)
 {
        WERROR result;
 
        /* enumprinterkey call */
-       result = rpccli_spoolss_enumprinterkey(pipe_hnd, mem_ctx, hnd, keyname, keylist, NULL);
+       result = rpccli_spoolss_enumprinterkey(pipe_hnd, mem_ctx, hnd, keyname, keylist, 0);
 
        if (!W_ERROR_IS_OK(result)) {
                printf("enumprinterkey failed: %s\n", win_errstr(result));
@@ -906,14 +864,20 @@ static bool net_spoolss_enumprinterkey(struct rpc_pipe_client *pipe_hnd,
 static bool net_spoolss_enumprinterdataex(struct rpc_pipe_client *pipe_hnd,
                                        TALLOC_CTX *mem_ctx,
                                        uint32 offered,
-                                       POLICY_HND *hnd,
+                                       struct policy_handle *hnd,
                                        const char *keyname,
-                                       REGVAL_CTR *ctr)
+                                       uint32_t *count,
+                                       struct spoolss_PrinterEnumValues **info)
 {
        WERROR result;
 
        /* enumprinterdataex call */
-       result = rpccli_spoolss_enumprinterdataex(pipe_hnd, mem_ctx, hnd, keyname, ctr);
+       result = rpccli_spoolss_enumprinterdataex(pipe_hnd, mem_ctx,
+                                                 hnd,
+                                                 keyname,
+                                                 0, /* offered */
+                                                 count,
+                                                 info);
 
        if (!W_ERROR_IS_OK(result)) {
                printf("enumprinterdataex failed: %s\n", win_errstr(result));
@@ -926,8 +890,8 @@ static bool net_spoolss_enumprinterdataex(struct rpc_pipe_client *pipe_hnd,
 
 static bool net_spoolss_setprinterdataex(struct rpc_pipe_client *pipe_hnd,
                                        TALLOC_CTX *mem_ctx,
-                                       POLICY_HND *hnd,
-                                       char *keyname,
+                                       struct policy_handle *hnd,
+                                       const char *keyname,
                                        REGISTRY_VALUE *value)
 {
        WERROR result;
@@ -953,16 +917,20 @@ static bool net_spoolss_setprinterdataex(struct rpc_pipe_client *pipe_hnd,
 
 static bool net_spoolss_enumforms(struct rpc_pipe_client *pipe_hnd,
                                TALLOC_CTX *mem_ctx,
-                               POLICY_HND *hnd,
+                               struct policy_handle *hnd,
                                int level,
-                               uint32 *num_forms,
-                               FORM_1 **forms)
+                               uint32_t *num_forms,
+                               union spoolss_FormInfo **forms)
 {
        WERROR result;
 
        /* enumforms call */
-       result = rpccli_spoolss_enumforms(pipe_hnd, mem_ctx, hnd, level, num_forms, forms);
-
+       result = rpccli_spoolss_enumforms(pipe_hnd, mem_ctx,
+                                         hnd,
+                                         level,
+                                         0,
+                                         num_forms,
+                                         forms);
        if (!W_ERROR_IS_OK(result)) {
                printf("could not enum forms: %s\n", win_errstr(result));
                return false;
@@ -974,16 +942,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;
@@ -994,7 +965,7 @@ static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd,
 
 static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd,
                             TALLOC_CTX *mem_ctx,
-                            POLICY_HND *hnd, uint32 level,
+                            struct policy_handle *hnd, uint32 level,
                             const char *env, int version,
                             union spoolss_DriverInfo *info)
 {
@@ -1078,26 +1049,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;
+       struct policy_handle hnd;
 
        /* 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,
@@ -1105,7 +1071,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;
        }
@@ -1150,26 +1116,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",
@@ -1209,11 +1168,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++) {
@@ -1223,7 +1180,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;
                }
@@ -1240,7 +1197,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);
                }
        }
 
@@ -1273,31 +1230,24 @@ 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;
        struct sec_desc_buf secdesc_ctr;
-       POLICY_HND hnd;
+       struct policy_handle hnd;
        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;
                }
@@ -1425,29 +1375,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;
+       struct policy_handle 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;
                }
@@ -1526,26 +1468,24 @@ 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;
+       struct policy_handle hnd_src, hnd_dst;
+       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 */
        nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
-                                    &syntax_spoolss);
+                                    &ndr_table_spoolss.syntax_id);
        if (!NT_STATUS_IS_OK(nt_status))
                return nt_status;
 
 
        /* 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;
        }
@@ -1558,17 +1498,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;
@@ -1680,27 +1614,25 @@ 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;
+       struct policy_handle hnd_src, hnd_dst;
+       union spoolss_PrinterInfo *info_enum;
        union spoolss_PrinterInfo info_dst;
-       uint32 num_forms;
-       FORM_1 *forms;
+       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 */
        nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
-                                    &syntax_spoolss);
+                                    &ndr_table_spoolss.syntax_id);
        if (!NT_STATUS_IS_OK(nt_status))
                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;
        }
@@ -1713,17 +1645,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;
@@ -1760,34 +1686,19 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c,
                for (f = 0; f < num_forms; f++) {
 
                        union spoolss_AddFormInfo info;
-                       struct spoolss_AddFormInfo1 info1;
-                       fstring form_name;
                        NTSTATUS status;
 
                        /* only migrate FORM_PRINTER types, according to jerry
                           FORM_BUILTIN-types are hard-coded in samba */
-                       if (forms[f].flag != FORM_PRINTER)
+                       if (forms[f].info1.flags != SPOOLSS_FORM_PRINTER)
                                continue;
 
-                       if (forms[f].name.buffer)
-                               rpcstr_pull(form_name, forms[f].name.buffer,
-                                       sizeof(form_name), -1, STR_TERMINATE);
-
                        if (c->opt_verbose)
                                d_printf("\tmigrating form # %d [%s] of type [%d]\n",
-                                       f, form_name, forms[f].flag);
+                                       f, forms[f].info1.form_name,
+                                       forms[f].info1.flags);
 
-                       /* is there a more elegant way to do that ? */
-                       info1.flags             = FORM_PRINTER;
-                       info1.size.width        = forms[f].width;
-                       info1.size.height       = forms[f].length;
-                       info1.area.left         = forms[f].left;
-                       info1.area.top          = forms[f].top;
-                       info1.area.right        = forms[f].right;
-                       info1.area.bottom       = forms[f].bottom;
-                       info1.form_name         = form_name;
-
-                       info.info1 = &info1;
+                       info.info1 = (struct spoolss_AddFormInfo1 *)&forms[f].info1;
 
                        /* FIXME: there might be something wrong with samba's
                           builtin-forms */
@@ -1798,11 +1709,12 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c,
                                                        &result);
                        if (!W_ERROR_IS_OK(result)) {
                                d_printf("\tAddForm form %d: [%s] refused.\n",
-                                       f, form_name);
+                                       f, forms[f].info1.form_name);
                                continue;
                        }
 
-                       DEBUGADD(1,("\tAddForm of [%s] succeeded\n", form_name));
+                       DEBUGADD(1,("\tAddForm of [%s] succeeded\n",
+                               forms[f].info1.form_name));
                }
 
 
@@ -1862,26 +1774,23 @@ 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;
+       struct policy_handle 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,
-                                    &syntax_spoolss);
+                                    &ndr_table_spoolss.syntax_id);
        if (!NT_STATUS_IS_OK(nt_status))
                return nt_status;
 
@@ -1904,7 +1813,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;
        }
@@ -1918,17 +1827,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;
@@ -2082,11 +1985,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;
+       struct policy_handle hnd_dst, hnd_src;
+       const char *printername, *sharename;
        struct rpc_pipe_client *pipe_hnd_dst = NULL;
        struct spoolss_SetPrinterInfoCtr info_ctr;
 
@@ -2094,12 +1997,12 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c,
 
        /* connect destination PI_SPOOLSS */
        nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
-                                    &syntax_spoolss);
+                                    &ndr_table_spoolss.syntax_id);
        if (!NT_STATUS_IS_OK(nt_status))
                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;
        }
@@ -2112,17 +2015,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;
@@ -2243,21 +2140,19 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
        WERROR result;
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        uint32 i = 0, p = 0, j = 0;
-       uint32 num_printers, val_needed, data_needed;
+       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_enum;
-       union spoolss_PrinterInfo info_dst_publish, info_dst;
-       REGVAL_CTR *reg_ctr;
+       struct policy_handle hnd_src, hnd_dst;
+       union spoolss_PrinterInfo *info_enum;
+       union spoolss_PrinterInfo info_dst_publish;
+       union spoolss_PrinterInfo info_dst;
        struct cli_state *cli_dst = NULL;
        char *devicename = NULL, *unc_name = NULL, *url = NULL;
        const char *longname;
+       const char **keylist = NULL;
 
-       uint16 *keylist = NULL, *curkey;
-
-       ZERO_STRUCT(ctr_enum);
        /* FIXME GD */
        ZERO_STRUCT(info_dst_publish);
 
@@ -2265,12 +2160,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
 
        /* connect destination PI_SPOOLSS */
        nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
-                                    &syntax_spoolss);
+                                    &ndr_table_spoolss.syntax_id);
        if (!NT_STATUS_IS_OK(nt_status))
                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;
        }
@@ -2291,17 +2186,17 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
 
        /* do something for all printers */
        for (i = 0; i < num_printers; i++) {
+
+               uint32_t value_offered = 0, value_needed;
+               uint32_t data_offered = 0, data_needed;
+               enum winreg_Type type;
+               uint8_t *buffer = NULL;
+               const char *value_name = NULL;
+
                /* 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;
@@ -2329,20 +2224,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))
@@ -2356,13 +2250,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) */
@@ -2384,7 +2275,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
@@ -2394,32 +2285,69 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
                */
 
                /* enumerate data on src handle */
-               result = rpccli_spoolss_enumprinterdata(pipe_hnd, mem_ctx, &hnd_src, p, 0, 0,
-                       &val_needed, &data_needed, NULL);
+               nt_status = rpccli_spoolss_EnumPrinterData(pipe_hnd, mem_ctx,
+                                                          &hnd_src,
+                                                          p,
+                                                          value_name,
+                                                          value_offered,
+                                                          &value_needed,
+                                                          &type,
+                                                          buffer,
+                                                          data_offered,
+                                                          &data_needed,
+                                                          &result);
+
+               data_offered    = data_needed;
+               value_offered   = value_needed;
+               buffer          = talloc_zero_array(mem_ctx, uint8_t, data_needed);
+               value_name      = talloc_zero_array(mem_ctx, char, value_needed);
 
                /* loop for all printerdata of "PrinterDriverData" */
-               while (W_ERROR_IS_OK(result)) {
-
-                       REGISTRY_VALUE value;
-
-                       result = rpccli_spoolss_enumprinterdata(
-                               pipe_hnd, mem_ctx, &hnd_src, p++, val_needed,
-                               data_needed, 0, 0, &value);
-
+               while (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(result)) {
+
+                       nt_status = rpccli_spoolss_EnumPrinterData(pipe_hnd, mem_ctx,
+                                                                  &hnd_src,
+                                                                  p++,
+                                                                  value_name,
+                                                                  value_offered,
+                                                                  &value_needed,
+                                                                  &type,
+                                                                  buffer,
+                                                                  data_offered,
+                                                                  &data_needed,
+                                                                  &result);
                        /* loop for all reg_keys */
-                       if (W_ERROR_IS_OK(result)) {
+                       if (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(result)) {
+
+                               REGISTRY_VALUE v;
+                               DATA_BLOB blob;
+                               union spoolss_PrinterData printer_data;
 
                                /* display_value */
-                               if (c->opt_verbose)
-                                       display_reg_value(SPOOL_PRINTERDATA_KEY, value);
+                               if (c->opt_verbose) {
+                                       fstrcpy(v.valuename, value_name);
+                                       v.type = type;
+                                       v.size = data_offered;
+                                       v.data_p = buffer;
+                                       display_reg_value(SPOOL_PRINTERDATA_KEY, v);
+                               }
+
+                               result = pull_spoolss_PrinterData(mem_ctx,
+                                                                 &blob,
+                                                                 &printer_data,
+                                                                 type);
+                               if (!W_ERROR_IS_OK(result)) {
+                                       goto done;
+                               }
 
                                /* set_value */
                                if (!net_spoolss_setprinterdata(pipe_hnd_dst, mem_ctx,
-                                                               &hnd_dst, &value))
+                                                               &hnd_dst, value_name,
+                                                               type, printer_data))
                                        goto done;
 
                                DEBUGADD(1,("\tSetPrinterData of [%s] succeeded\n",
-                                       value.valuename));
+                                       v.valuename));
                        }
                }
 
@@ -2443,30 +2371,20 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
                if (keylist == NULL)
                        continue;
 
-               curkey = keylist;
-               while (*curkey != 0) {
-                       char *subkey;
-                       rpcstr_pull_talloc(mem_ctx,
-                                       &subkey,
-                                       curkey,
-                                       -1,
-                                       STR_TERMINATE);
-                       if (!subkey) {
-                               return NT_STATUS_NO_MEMORY;
-                       }
-
-                       curkey += strlen(subkey) + 1;
+               for (i=0; keylist && keylist[i] != NULL; i++) {
 
-                       if ( !(reg_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
-                               return NT_STATUS_NO_MEMORY;
+                       const char *subkey = keylist[i];
+                       uint32_t count;
+                       struct spoolss_PrinterEnumValues *info;
 
                        /* enumerate all src subkeys */
                        if (!net_spoolss_enumprinterdataex(pipe_hnd, mem_ctx, 0,
                                                           &hnd_src, subkey,
-                                                          reg_ctr))
+                                                          &count, &info)) {
                                goto done;
+                       }
 
-                       for (j=0; j < reg_ctr->num_values; j++) {
+                       for (j=0; j < count; j++) {
 
                                REGISTRY_VALUE value;
                                UNISTR2 data;
@@ -2474,20 +2392,20 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
                                /* although samba replies with sane data in most cases we
                                   should try to avoid writing wrong registry data */
 
-                               if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_PORTNAME) ||
-                                   strequal(reg_ctr->values[j]->valuename, SPOOL_REG_UNCNAME) ||
-                                   strequal(reg_ctr->values[j]->valuename, SPOOL_REG_URL) ||
-                                   strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SHORTSERVERNAME) ||
-                                   strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SERVERNAME)) {
+                               if (strequal(info[j].value_name, SPOOL_REG_PORTNAME) ||
+                                   strequal(info[j].value_name, SPOOL_REG_UNCNAME) ||
+                                   strequal(info[j].value_name, SPOOL_REG_URL) ||
+                                   strequal(info[j].value_name, SPOOL_REG_SHORTSERVERNAME) ||
+                                   strequal(info[j].value_name, SPOOL_REG_SERVERNAME)) {
 
-                                       if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_PORTNAME)) {
+                                       if (strequal(info[j].value_name, SPOOL_REG_PORTNAME)) {
 
                                                /* although windows uses a multi-sz, we use a sz */
                                                init_unistr2(&data, SAMBA_PRINTER_PORT_NAME, UNI_STR_TERMINATE);
                                                fstrcpy(value.valuename, SPOOL_REG_PORTNAME);
                                        }
 
-                                       if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_UNCNAME)) {
+                                       if (strequal(info[j].value_name, SPOOL_REG_UNCNAME)) {
 
                                                if (asprintf(&unc_name, "\\\\%s\\%s", longname, sharename) < 0) {
                                                        nt_status = NT_STATUS_NO_MEMORY;
@@ -2497,7 +2415,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
                                                fstrcpy(value.valuename, SPOOL_REG_UNCNAME);
                                        }
 
-                                       if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_URL)) {
+                                       if (strequal(info[j].value_name, SPOOL_REG_URL)) {
 
                                                continue;
 
@@ -2512,13 +2430,13 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
 #endif
                                        }
 
-                                       if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SERVERNAME)) {
+                                       if (strequal(info[j].value_name, SPOOL_REG_SERVERNAME)) {
 
                                                init_unistr2(&data, longname, UNI_STR_TERMINATE);
                                                fstrcpy(value.valuename, SPOOL_REG_SERVERNAME);
                                        }
 
-                                       if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SHORTSERVERNAME)) {
+                                       if (strequal(info[j].value_name, SPOOL_REG_SHORTSERVERNAME)) {
 
                                                init_unistr2(&data, global_myname(), UNI_STR_TERMINATE);
                                                fstrcpy(value.valuename, SPOOL_REG_SHORTSERVERNAME);
@@ -2542,25 +2460,40 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
 
                                } else {
 
-                                       if (c->opt_verbose)
-                                               display_reg_value(subkey, *(reg_ctr->values[j]));
+                                       REGISTRY_VALUE v;
+                                       DATA_BLOB blob;
+
+                                       result = push_spoolss_PrinterData(mem_ctx, &blob,
+                                                                         info[j].type,
+                                                                         info[j].data);
+                                       if (!W_ERROR_IS_OK(result)) {
+                                               goto done;
+                                       }
+
+                                       fstrcpy(v.valuename, info[j].value_name);
+                                       v.type = info[j].type;
+                                       v.data_p = blob.data;
+                                       v.size = blob.length;
+
+                                       if (c->opt_verbose) {
+                                               display_reg_value(subkey, v);
+                                       }
 
                                        /* here we have to set all subkeys on the dst server */
                                        if (!net_spoolss_setprinterdataex(pipe_hnd_dst, mem_ctx, &hnd_dst,
-                                                       subkey, reg_ctr->values[j]))
+                                                       subkey, &v)) {
                                                goto done;
+                                       }
 
                                }
 
                                DEBUGADD(1,("\tSetPrinterDataEx of key [%s\\%s] succeeded\n",
-                                               subkey, reg_ctr->values[j]->valuename));
+                                               subkey, info[j].value_name));
 
                        }
-
-                       TALLOC_FREE( reg_ctr );
                }
 
-               SAFE_FREE(keylist);
+               TALLOC_FREE(keylist);
 
                /* close printer handles here */
                if (is_valid_policy_hnd(&hnd_src)) {
index 00c827928eac1a4b06f2ac9b54d50b08b6ddfe08..60274728f3f2f6b5a132a576eadd7c45f23184f9 100644 (file)
@@ -767,7 +767,7 @@ static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
                                                int argc,
                                                const char **argv )
 {
-       POLICY_HND pol_hive, pol_key;
+       struct policy_handle pol_hive, pol_key;
        NTSTATUS status;
        uint32 num_subkeys = 0;
        uint32 num_values = 0;
@@ -843,7 +843,7 @@ static NTSTATUS rpc_registry_save_internal(struct net_context *c,
                                        const char **argv )
 {
        WERROR result = WERR_GENERAL_FAILURE;
-       POLICY_HND pol_hive, pol_key;
+       struct policy_handle pol_hive, pol_key;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
        struct winreg_String filename;
 
@@ -1139,7 +1139,7 @@ static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
                                            int argc,
                                            const char **argv)
 {
-       POLICY_HND pol_hive, pol_key;
+       struct policy_handle pol_hive, pol_key;
        NTSTATUS status;
        enum ndr_err_code ndr_err;
        struct KeySecurityData *sd = NULL;
index ddcfff3685f517f586b06f19c44be919de86c2df..10166b6d2b704f29e139082ec9f13f28dc4ee9be 100644 (file)
@@ -28,7 +28,7 @@ static NTSTATUS sid_to_name(struct rpc_pipe_client *pipe_hnd,
                                DOM_SID *sid,
                                fstring name)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        enum lsa_SidType *sid_types = NULL;
        NTSTATUS result;
        char **domains = NULL, **names = NULL;
@@ -59,7 +59,7 @@ static NTSTATUS name_to_sid(struct rpc_pipe_client *pipe_hnd,
                            TALLOC_CTX *mem_ctx,
                            DOM_SID *sid, const char *name)
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        enum lsa_SidType *sid_types;
        NTSTATUS result;
        DOM_SID *sids;
@@ -90,7 +90,7 @@ static NTSTATUS name_to_sid(struct rpc_pipe_client *pipe_hnd,
 
 static NTSTATUS enum_privileges(struct rpc_pipe_client *pipe_hnd,
                                TALLOC_CTX *ctx,
-                               POLICY_HND *pol )
+                               struct policy_handle *pol )
 {
        NTSTATUS result;
        uint32 enum_context = 0;
@@ -148,7 +148,7 @@ static NTSTATUS enum_privileges(struct rpc_pipe_client *pipe_hnd,
 
 static NTSTATUS check_privilege_for_user(struct rpc_pipe_client *pipe_hnd,
                                        TALLOC_CTX *ctx,
-                                       POLICY_HND *pol,
+                                       struct policy_handle *pol,
                                        DOM_SID *sid,
                                        const char *right)
 {
@@ -183,7 +183,7 @@ static NTSTATUS check_privilege_for_user(struct rpc_pipe_client *pipe_hnd,
 
 static NTSTATUS enum_privileges_for_user(struct rpc_pipe_client *pipe_hnd,
                                        TALLOC_CTX *ctx,
-                                       POLICY_HND *pol,
+                                       struct policy_handle *pol,
                                        DOM_SID *sid )
 {
        NTSTATUS result;
@@ -214,7 +214,7 @@ static NTSTATUS enum_privileges_for_user(struct rpc_pipe_client *pipe_hnd,
 
 static NTSTATUS enum_accounts_for_privilege(struct rpc_pipe_client *pipe_hnd,
                                                TALLOC_CTX *ctx,
-                                               POLICY_HND *pol,
+                                               struct policy_handle *pol,
                                                const char *privilege)
 {
        NTSTATUS result;
@@ -265,7 +265,7 @@ static NTSTATUS enum_accounts_for_privilege(struct rpc_pipe_client *pipe_hnd,
 
 static NTSTATUS enum_privileges_for_accounts(struct rpc_pipe_client *pipe_hnd,
                                                TALLOC_CTX *ctx,
-                                               POLICY_HND *pol)
+                                               struct policy_handle *pol)
 {
        NTSTATUS result;
        uint32 enum_context=0;
@@ -317,7 +317,7 @@ static NTSTATUS rpc_rights_list_internal(struct net_context *c,
                                        int argc,
                                        const char **argv )
 {
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result;
        DOM_SID sid;
        fstring privname;
@@ -436,7 +436,7 @@ static NTSTATUS rpc_rights_grant_internal(struct net_context *c,
                                        int argc,
                                        const char **argv )
 {
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct lsa_RightSet rights;
        int i;
@@ -506,7 +506,7 @@ static NTSTATUS rpc_rights_revoke_internal(struct net_context *c,
                                        int argc,
                                        const char **argv )
 {
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct lsa_RightSet rights;
        DOM_SID sid;
index 236414222c6221a248eda03431d36fa428940e02..bcb1a00dab8697b06670dfac7100ac301a9a2084 100644 (file)
@@ -61,11 +61,11 @@ const char *svc_status_string( uint32 state )
 
 static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
                                TALLOC_CTX *mem_ctx,
-                               POLICY_HND *hSCM,
+                               struct policy_handle *hSCM,
                                const char *service,
                                uint32 *state )
 {
-       POLICY_HND hService;
+       struct policy_handle hService;
        struct SERVICE_STATUS service_status;
        WERROR result = WERR_GENERAL_FAILURE;
        NTSTATUS status;
@@ -102,7 +102,7 @@ static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
 
 static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
                                TALLOC_CTX *mem_ctx,
-                               POLICY_HND *hSCM,
+                               struct policy_handle *hSCM,
                                const char *service,
                                uint32 watch_state,
                                uint32 *final_state )
@@ -137,12 +137,12 @@ static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
 
 static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
                                TALLOC_CTX *mem_ctx,
-                               POLICY_HND *hSCM,
+                               struct policy_handle *hSCM,
                                const char *service,
                                uint32 control,
                                uint32 watch_state )
 {
-       POLICY_HND hService;
+       struct policy_handle hService;
        WERROR result = WERR_GENERAL_FAILURE;
        NTSTATUS status;
        struct SERVICE_STATUS service_status;
@@ -199,7 +199,7 @@ static NTSTATUS rpc_service_list_internal(struct net_context *c,
                                        int argc,
                                        const char **argv )
 {
-       POLICY_HND hSCM;
+       struct policy_handle hSCM;
        struct ENUM_SERVICE_STATUSW *services = NULL;
        WERROR result = WERR_GENERAL_FAILURE;
        NTSTATUS status;
@@ -309,7 +309,7 @@ static NTSTATUS rpc_service_status_internal(struct net_context *c,
                                                int argc,
                                                const char **argv )
 {
-       POLICY_HND hSCM, hService;
+       struct policy_handle hSCM, hService;
        WERROR result = WERR_GENERAL_FAILURE;
        NTSTATUS status;
        struct SERVICE_STATUS service_status;
@@ -433,7 +433,7 @@ static NTSTATUS rpc_service_stop_internal(struct net_context *c,
                                        int argc,
                                        const char **argv )
 {
-       POLICY_HND hSCM;
+       struct policy_handle hSCM;
        WERROR result = WERR_GENERAL_FAILURE;
        NTSTATUS status;
        fstring servicename;
@@ -477,7 +477,7 @@ static NTSTATUS rpc_service_pause_internal(struct net_context *c,
                                        int argc,
                                        const char **argv )
 {
-       POLICY_HND hSCM;
+       struct policy_handle hSCM;
        WERROR result = WERR_GENERAL_FAILURE;
        NTSTATUS status;
        fstring servicename;
@@ -521,7 +521,7 @@ static NTSTATUS rpc_service_resume_internal(struct net_context *c,
                                        int argc,
                                        const char **argv )
 {
-       POLICY_HND hSCM;
+       struct policy_handle hSCM;
        WERROR result = WERR_GENERAL_FAILURE;
        NTSTATUS status;
        fstring servicename;
@@ -565,7 +565,7 @@ static NTSTATUS rpc_service_start_internal(struct net_context *c,
                                        int argc,
                                        const char **argv )
 {
-       POLICY_HND hSCM, hService;
+       struct policy_handle hSCM, hService;
        WERROR result = WERR_GENERAL_FAILURE;
        NTSTATUS status;
        uint32 state = 0;
index 977e1e2a0a7d6ca98cc84a8fa58a53af03b96b4a..af0b426bbcd103d2e661c4a39e24727a1b0d4654 100644 (file)
@@ -38,7 +38,7 @@ static NTSTATUS rpc_sh_acct_do(struct net_context *c,
                                          struct samr_DomInfo12 *i12,
                                          int argc, const char **argv))
 {
-       POLICY_HND connect_pol, domain_pol;
+       struct policy_handle connect_pol, domain_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        union samr_DomainInfo *info1 = NULL;
        union samr_DomainInfo *info3 = NULL;
index e8ebb6020579848885dd9b6cc49e0edfc9ca8f3d..eea22c0dc2038514f4f03b922e05d7ca0474373a 100644 (file)
@@ -1269,28 +1269,31 @@ static int net_sam_do_list(struct net_context *c, int argc, const char **argv,
                }
        }
 
-       pdb_search_destroy(search);
+       TALLOC_FREE(search);
        return 0;
 }
 
 static int net_sam_list_users(struct net_context *c, int argc,
                              const char **argv)
 {
-       return net_sam_do_list(c, argc, argv, pdb_search_users(ACB_NORMAL),
+       return net_sam_do_list(c, argc, argv,
+                              pdb_search_users(talloc_tos(), ACB_NORMAL),
                               "users");
 }
 
 static int net_sam_list_groups(struct net_context *c, int argc,
                               const char **argv)
 {
-       return net_sam_do_list(c, argc, argv, pdb_search_groups(), "groups");
+       return net_sam_do_list(c, argc, argv, pdb_search_groups(talloc_tos()),
+                              "groups");
 }
 
 static int net_sam_list_localgroups(struct net_context *c, int argc,
                                    const char **argv)
 {
        return net_sam_do_list(c, argc, argv,
-                              pdb_search_aliases(get_global_sam_sid()),
+                              pdb_search_aliases(talloc_tos(),
+                                                 get_global_sam_sid()),
                               "localgroups");
 }
 
@@ -1298,7 +1301,8 @@ static int net_sam_list_builtin(struct net_context *c, int argc,
                                const char **argv)
 {
        return net_sam_do_list(c, argc, argv,
-                              pdb_search_aliases(&global_sid_Builtin),
+                              pdb_search_aliases(talloc_tos(),
+                                                 &global_sid_Builtin),
                               "builtin");
 }
 
@@ -1306,7 +1310,7 @@ static int net_sam_list_workstations(struct net_context *c, int argc,
                                     const char **argv)
 {
        return net_sam_do_list(c, argc, argv,
-                              pdb_search_users(ACB_WSTRUST),
+                              pdb_search_users(talloc_tos(), ACB_WSTRUST),
                               "workstations");
 }
 
index 7fbfdbab44ffdf99d7a2dc893547c642bcaa38bd..c6b6ee9e809d0b35a063f5ab64ec97cdc84832d7 100644 (file)
@@ -29,7 +29,7 @@ NTSTATUS net_rpc_lookup_name(struct net_context *c,
                             enum lsa_SidType *ret_type)
 {
        struct rpc_pipe_client *lsa_pipe;
-       POLICY_HND pol;
+       struct policy_handle pol;
        NTSTATUS result = NT_STATUS_OK;
        const char **dom_names;
        DOM_SID *sids;
index 14f2dddebcf9b9504c1550c9e72128a094440eca..dd0efa4142299755f8ede7d5cacc789be55842ed 100644 (file)
@@ -31,7 +31,7 @@ struct con_struct {
        NTSTATUS err;
        struct cli_state *cli;
        struct rpc_pipe_client *lsapipe;
-       POLICY_HND pol;
+       struct policy_handle pol;
 };
 
 static struct con_struct *cs;
index 50cbc43d6de71bcec959b524932168d7eb506c86..a5bc0c9bd41a50fe3969fb348828146176857bff 100644 (file)
@@ -67,7 +67,7 @@ static int export_database (struct pdb_methods *in,
 
        DEBUG(3, ("export_database: username=\"%s\"\n", username ? username : "(NULL)"));
 
-       u_search = pdb_search_init(PDB_USER_SEARCH);
+       u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH);
        if (u_search == NULL) {
                DEBUG(0, ("pdb_search_init failed\n"));
                return 1;
@@ -75,7 +75,7 @@ static int export_database (struct pdb_methods *in,
 
        if (!in->search_users(in, u_search, 0)) {
                DEBUG(0, ("Could not start searching users\n"));
-               pdb_search_destroy(u_search);
+               TALLOC_FREE(u_search);
                return 1;
        }
 
@@ -116,7 +116,7 @@ static int export_database (struct pdb_methods *in,
                        fprintf(stderr, "export_database: Memory allocation "
                                "failure!\n");
                        TALLOC_FREE( user );
-                       pdb_search_destroy(u_search);
+                       TALLOC_FREE(u_search);
                        return 1;
                }
 
@@ -139,7 +139,7 @@ static int export_database (struct pdb_methods *in,
                TALLOC_FREE( user );
        }
 
-       pdb_search_destroy(u_search);
+       TALLOC_FREE(u_search);
 
        return 0;
 }
@@ -352,7 +352,7 @@ static int print_users_list (struct pdb_methods *in, bool verbosity, bool smbpwd
        struct pdb_search *u_search;
        struct samr_displayentry userentry;
 
-       u_search = pdb_search_init(PDB_USER_SEARCH);
+       u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH);
        if (u_search == NULL) {
                DEBUG(0, ("pdb_search_init failed\n"));
                return 1;
@@ -360,7 +360,7 @@ static int print_users_list (struct pdb_methods *in, bool verbosity, bool smbpwd
 
        if (!in->search_users(in, u_search, 0)) {
                DEBUG(0, ("Could not start searching users\n"));
-               pdb_search_destroy(u_search);
+               TALLOC_FREE(u_search);
                return 1;
        }
 
@@ -391,7 +391,7 @@ static int print_users_list (struct pdb_methods *in, bool verbosity, bool smbpwd
                print_sam_info (sam_pwent, verbosity, smbpwdstyle);
                TALLOC_FREE(sam_pwent);
        }
-       pdb_search_destroy(u_search);
+       TALLOC_FREE(u_search);
 
        return 0;
 }
@@ -404,7 +404,7 @@ static int fix_users_list (struct pdb_methods *in)
        struct pdb_search *u_search;
        struct samr_displayentry userentry;
 
-       u_search = pdb_search_init(PDB_USER_SEARCH);
+       u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH);
        if (u_search == NULL) {
                DEBUG(0, ("pdb_search_init failed\n"));
                return 1;
@@ -412,7 +412,7 @@ static int fix_users_list (struct pdb_methods *in)
 
        if (!in->search_users(in, u_search, 0)) {
                DEBUG(0, ("Could not start searching users\n"));
-               pdb_search_destroy(u_search);
+               TALLOC_FREE(u_search);
                return 1;
        }
 
@@ -444,7 +444,7 @@ static int fix_users_list (struct pdb_methods *in)
                }
                TALLOC_FREE(sam_pwent);
        }
-       pdb_search_destroy(u_search);
+       TALLOC_FREE(u_search);
        return 0;
 }
 
index c12778f8c71f820c1badf1af1828bb771e76739d..85b7baad007cf42d2a3de6e3e837b6571c925ca8 100644 (file)
@@ -973,12 +973,7 @@ static struct cli_state *connect_one(struct user_auth_info *auth_info,
                return NULL;
        }
 
-       if (!get_cmdline_auth_info_got_pass(auth_info)) {
-               char *pass = getpass("Password: ");
-               if (pass) {
-                       set_cmdline_auth_info_password(auth_info, pass);
-               }
-       }
+       set_cmdline_auth_info_getpass(auth_info);
 
        nt_status = cli_full_connection(&c, global_myname(), server, 
                                &ss, 0,
index 6ea200bfec5dcfb3d2771f101c5e851bc9a8d196..fc7d0aa360f87ef1364be37440b8b4d6caef664a 100644 (file)
@@ -669,11 +669,11 @@ static bool do_printnotify(struct messaging_context *msg_ctx,
                }
 
                if (strcmp(argv[3], "comment") == 0) {
-                       attribute = PRINTER_NOTIFY_COMMENT;
+                       attribute = PRINTER_NOTIFY_FIELD_COMMENT;
                } else if (strcmp(argv[3], "port") == 0) {
-                       attribute = PRINTER_NOTIFY_PORT_NAME;
+                       attribute = PRINTER_NOTIFY_FIELD_PORT_NAME;
                } else if (strcmp(argv[3], "driver") == 0) {
-                       attribute = PRINTER_NOTIFY_DRIVER_NAME;
+                       attribute = PRINTER_NOTIFY_FIELD_DRIVER_NAME;
                } else {
                        fprintf(stderr, "Invalid printer command '%s'\n",
                                argv[3]);
index a95394b125ced5349f90e261175cfa94bf6bce6a..78260acf76b6857bca23e167993b4a98a80f4774 100644 (file)
@@ -35,7 +35,7 @@ enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR};
 
 static struct cli_state *cli_ipc;
 static struct rpc_pipe_client *global_pipe_hnd;
-static POLICY_HND pol;
+static struct policy_handle pol;
 static bool got_policy_hnd;
 static struct user_auth_info *smbcquotas_auth_info;
 
@@ -385,12 +385,7 @@ static struct cli_state *connect_one(const char *share)
 
        }
 
-       if (!get_cmdline_auth_info_got_pass(smbcquotas_auth_info)) {
-               char *pass = getpass("Password: ");
-               if (pass) {
-                       set_cmdline_auth_info_password(smbcquotas_auth_info, pass);
-               }
-       }
+       set_cmdline_auth_info_getpass(smbcquotas_auth_info);
 
        nt_status = cli_full_connection(&c, global_myname(), server, 
                                            &ss, 0,
index 6c69300e85b205c6125749f6a8a850c5d5600f09..02001f0abbdfce1dddfbce21346bd97dc3b214b2 100644 (file)
@@ -315,12 +315,7 @@ static bool print_tree(struct user_auth_info *user_info)
                return 1;
        }
 
-       if (!get_cmdline_auth_info_got_pass(auth_info)) {
-               char *pass = getpass("Password: ");
-               if (pass) {
-                       set_cmdline_auth_info_password(auth_info, pass);
-               }
-       }
+       set_cmdline_auth_info_getpass(auth_info);
 
        /* Now do our stuff */
 
index b22e5af94aece5bcc7975232c6816e81c26003a2..5c29ba0b223dfd9aa604aaa11a9038634b0e7549 100644 (file)
@@ -304,6 +304,11 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map
        char *u_filter = NULL;
        char *g_filter = NULL;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        /* Only do query if we are online */
        if (idmap_is_offline()) {
                return NT_STATUS_FILE_IS_OFFLINE;
@@ -516,6 +521,11 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map
        int i;
        char *sidstr;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+
        /* Only do query if we are online */
        if (idmap_is_offline()) {
                return NT_STATUS_FILE_IS_OFFLINE;
index 7e186ca8a124b68e19ae496363339ed2411398e6..e2fcda83d329571a9708e2ca162a1bc2adf6d350 100644 (file)
@@ -159,6 +159,11 @@ static NTSTATUS _idmap_adex_get_sid_from_id(struct
        NTSTATUS nt_status;
         struct likewise_cell *cell;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        nt_status = _idmap_adex_init(dom, NULL);
        if (!NT_STATUS_IS_OK(nt_status))
                return nt_status;
@@ -207,6 +212,11 @@ static NTSTATUS _idmap_adex_get_id_from_sid(struct
        NTSTATUS nt_status;
         struct likewise_cell *cell;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        nt_status = _idmap_adex_init(dom, NULL);
        if (!NT_STATUS_IS_OK(nt_status))
                return nt_status;
index 7dd94aede0d1a94b6b762b2179dbb7106806c943..42830720f3c5ba32892a5806975f6da560040f86 100644 (file)
@@ -160,6 +160,11 @@ static NTSTATUS unixids_to_sids(struct idmap_domain *dom,
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        int i;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        nt_status = be_init(dom, NULL);
        BAIL_ON_NTSTATUS_ERROR(nt_status);
 
@@ -206,6 +211,11 @@ static NTSTATUS sids_to_unixids(struct idmap_domain *dom,
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        int i;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        nt_status = be_init(dom, NULL);
        BAIL_ON_NTSTATUS_ERROR(nt_status);
 
index 156fdc7cc9fc91bbf04adf570e4c79b23ad9e098..f50e6172baa117c0abb507205862a29db6773697 100644 (file)
@@ -44,6 +44,11 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
        TALLOC_CTX *ctx;
        int i;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        ctx = talloc_new(dom);
        if ( ! ctx) {
                DEBUG(0, ("Out of memory!\n"));
@@ -130,6 +135,11 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
        TALLOC_CTX *ctx;
        int i;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        ctx = talloc_new(dom);
        if ( ! ctx) {
                DEBUG(0, ("Out of memory!\n"));
index 9d1898708cb9f5bf4fa3ad763a686a1c147a5231..359bbfd4119e3fe59088e890e262ee43bfc89bb9 100644 (file)
@@ -171,6 +171,11 @@ static NTSTATUS idmap_rid_unixids_to_sids(struct idmap_domain *dom, struct id_ma
        NTSTATUS ret;
        int i;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
 
        ctx = talloc_new(dom);
@@ -205,6 +210,11 @@ static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_ma
        NTSTATUS ret;
        int i;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
 
        ctx = talloc_new(dom);
index 3a64979f339d7426834b355dd41beca5ab3a93ca..22c17578e6b8a99f839fec72c8c6855e942a4d83 100644 (file)
@@ -775,6 +775,11 @@ static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma
        NTSTATUS ret;
        int i;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
 
        for (i = 0; ids[i]; i++) {
@@ -813,6 +818,11 @@ static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma
        NTSTATUS ret;
        int i;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
 
        for (i = 0; ids[i]; i++) {
index fb90dd097ec53b5d447119e6454cb494a0ff8873..b2723270ebc532da512d261c5dbf5ce3797e8bec 100644 (file)
@@ -655,6 +655,11 @@ static NTSTATUS idmap_tdb2_unixids_to_sids(struct idmap_domain *dom, struct id_m
        NTSTATUS ret;
        int i;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
 
        for (i = 0; ids[i]; i++) {
@@ -692,6 +697,11 @@ static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_m
        NTSTATUS ret;
        int i;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
 
        for (i = 0; ids[i]; i++) {
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 dbe83152dd3baec9bec712f12331896752198909..66271068d26e493e9e622208c6182d87c61ff80c 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;
@@ -320,7 +320,7 @@ static bool winbindd_setup_sig_usr2_handler(void)
 
        se = tevent_add_signal(winbind_event_context(),
                               winbind_event_context(),
-                              SIGCHLD, 0,
+                              SIGUSR2, 0,
                               winbindd_sig_usr2_handler,
                               NULL);
        if (!se) {
@@ -927,6 +927,97 @@ static bool remove_idle_client(void)
        return False;
 }
 
+struct winbindd_listen_state {
+       bool privileged;
+       int fd;
+       struct tevent_fd *fde;
+};
+
+static void winbindd_listen_fde_handler(struct tevent_context *ev,
+                                       struct tevent_fd *fde,
+                                       uint16_t flags,
+                                       void *private_data)
+{
+       struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
+                                         struct winbindd_listen_state);
+
+       while (winbindd_num_clients() >
+              WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
+               DEBUG(5,("winbindd: Exceeding %d client "
+                        "connections, removing idle "
+                        "connection.\n",
+                        WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
+               if (!remove_idle_client()) {
+                       DEBUG(0,("winbindd: Exceeding %d "
+                                "client connections, no idle "
+                                "connection found\n",
+                                WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
+                       break;
+               }
+       }
+
+       /* new, non-privileged connection */
+       new_connection(s->fd, s->privileged);
+}
+
+static bool winbindd_setup_listeners(void)
+{
+       struct winbindd_listen_state *pub_state = NULL;
+       struct winbindd_listen_state *priv_state = NULL;
+
+       pub_state = talloc(winbind_event_context(),
+                          struct winbindd_listen_state);
+       if (!pub_state) {
+               goto failed;
+       }
+
+       pub_state->privileged = false;
+       pub_state->fd = open_winbindd_socket();
+       if (pub_state->fd == -1) {
+               goto failed;
+       }
+
+       pub_state->fde = tevent_add_fd(winbind_event_context(),
+                                      pub_state, pub_state->fd,
+                                      TEVENT_FD_READ,
+                                      winbindd_listen_fde_handler,
+                                      pub_state);
+       if (!pub_state->fde) {
+               close(pub_state->fd);
+               goto failed;
+       }
+       tevent_fd_set_auto_close(pub_state->fde);
+
+       priv_state = talloc(winbind_event_context(),
+                           struct winbindd_listen_state);
+       if (!priv_state) {
+               goto failed;
+       }
+
+       priv_state->privileged = true;
+       priv_state->fd = open_winbindd_priv_socket();
+       if (priv_state->fd == -1) {
+               goto failed;
+       }
+
+       priv_state->fde = tevent_add_fd(winbind_event_context(),
+                                       priv_state, priv_state->fd,
+                                       TEVENT_FD_READ,
+                                       winbindd_listen_fde_handler,
+                                       priv_state);
+       if (!priv_state->fde) {
+               close(priv_state->fd);
+               goto failed;
+       }
+       tevent_fd_set_auto_close(priv_state->fde);
+
+       return true;
+failed:
+       TALLOC_FREE(pub_state);
+       TALLOC_FREE(priv_state);
+       return false;
+}
+
 /* Process incoming clients on listen_sock.  We use a tricky non-blocking,
    non-forking, non-threaded model which allows us to handle many
    simultaneous connections while remaining impervious to many denial of
@@ -934,35 +1025,17 @@ static bool remove_idle_client(void)
 
 static void process_loop(void)
 {
-       struct winbindd_cli_state *state;
        struct winbindd_fd_event *ev;
        fd_set r_fds, w_fds;
-       int maxfd, listen_sock, listen_priv_sock, selret;
+       int maxfd = 0, selret;
        struct timeval timeout, ev_timeout;
 
-       /* Open Sockets here to get stuff going ASAP */
-       listen_sock = open_winbindd_socket();
-       listen_priv_sock = open_winbindd_priv_socket();
-
-       if (listen_sock == -1 || listen_priv_sock == -1) {
-               perror("open_winbind_socket");
-               exit(1);
-       }
-
        run_events(winbind_event_context(), 0, NULL, NULL);
 
-       /* refresh the trusted domain cache */
-
-       rescan_trusted_domains();
-
        /* Initialise fd lists for select() */
 
-       maxfd = MAX(listen_sock, listen_priv_sock);
-
        FD_ZERO(&r_fds);
        FD_ZERO(&w_fds);
-       FD_SET(listen_sock, &r_fds);
-       FD_SET(listen_priv_sock, &r_fds);
 
        timeout.tv_sec = WINBINDD_ESTABLISH_LOOP;
        timeout.tv_usec = 0;
@@ -979,23 +1052,6 @@ static void process_loop(void)
                timeout = timeval_min(&timeout, &ev_timeout);
        }
 
-       /* Set up client readers and writers */
-
-       state = winbindd_client_list();
-
-       while (state) {
-
-               struct winbindd_cli_state *next = state->next;
-
-               /* Dispose of client connection if it is marked as 
-                  finished */ 
-
-               if (state->finished)
-                       remove_client(state);
-
-               state = next;
-       }
-
        for (ev = fd_events; ev; ev = ev->next) {
                if (ev->flags & EVENT_FD_READ) {
                        FD_SET(ev->fd, &r_fds);
@@ -1043,43 +1099,7 @@ static void process_loop(void)
                ev = next;
        }
 
-       if (FD_ISSET(listen_sock, &r_fds)) {
-               while (winbindd_num_clients() >
-                      WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
-                       DEBUG(5,("winbindd: Exceeding %d client "
-                                "connections, removing idle "
-                                "connection.\n",
-                                WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
-                       if (!remove_idle_client()) {
-                               DEBUG(0,("winbindd: Exceeding %d "
-                                        "client connections, no idle "
-                                        "connection found\n",
-                                        WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
-                               break;
-                       }
-               }
-               /* new, non-privileged connection */
-               new_connection(listen_sock, False);
-       }
-
-       if (FD_ISSET(listen_priv_sock, &r_fds)) {
-               while (winbindd_num_clients() >
-                      WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
-                       DEBUG(5,("winbindd: Exceeding %d client "
-                                "connections, removing idle "
-                                "connection.\n",
-                                WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
-                       if (!remove_idle_client()) {
-                               DEBUG(0,("winbindd: Exceeding %d "
-                                        "client connections, no idle "
-                                        "connection found\n",
-                                        WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
-                               break;
-                       }
-               }
-               /* new, privileged connection */
-               new_connection(listen_priv_sock, True);
-       }
+       return;
 
  no_fds_ready:
 
@@ -1090,6 +1110,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)
@@ -1356,12 +1386,39 @@ int main(int argc, char **argv, char **envp)
        smb_nscd_flush_user_cache();
        smb_nscd_flush_group_cache();
 
-       /* Loop waiting for requests */
+       /* setup listen sockets */
+
+       if (!winbindd_setup_listeners()) {
+               DEBUG(0,("winbindd_setup_listeners() failed\n"));
+               exit(1);
+       }
 
        TALLOC_FREE(frame);
+       /* Loop waiting for requests */
        while (1) {
+               struct winbindd_cli_state *state;
+
                frame = talloc_stackframe();
+
+               /* refresh the trusted domain cache */
+
+               rescan_trusted_domains();
+
+               /* Dispose of client connection if it is marked as
+                  finished */
+               state = winbindd_client_list();
+               while (state) {
+                       struct winbindd_cli_state *next = state->next;
+
+                       if (state->finished) {
+                               remove_client(state);
+                       }
+
+                       state = next;
+               }
+
                process_loop();
+
                TALLOC_FREE(frame);
        }
 
index 5ebbb72cf5eb24492cd3c25f6fe854edcb79e3bf..f3733dc131d996dff6d15812df525817bfea11d6 100644 (file)
@@ -119,10 +119,10 @@ struct winbindd_cm_conn {
        struct cli_state *cli;
 
        struct rpc_pipe_client *samr_pipe;
-       POLICY_HND sam_connect_handle, sam_domain_handle;
+       struct policy_handle sam_connect_handle, sam_domain_handle;
 
        struct rpc_pipe_client *lsa_pipe;
-       POLICY_HND lsa_policy;
+       struct policy_handle lsa_policy;
 
        struct rpc_pipe_client *netlogon_pipe;
 };
index a508682e5ebc9d189b9197116f6975e2dfd64ab2..a76faa7a25298cb1dbfa0c99bd3aa0ce1d7d3c0c 100644 (file)
@@ -978,7 +978,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
        size_t num_members = 0;
        ads_control args;
         struct rpc_pipe_client *cli;
-        POLICY_HND lsa_policy;
+        struct policy_handle lsa_policy;
        DOM_SID *sid_mem_nocache = NULL;
        char **names_nocache = NULL;
        enum lsa_SidType *name_types_nocache = NULL;
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 35768fe7f2492c21fcd28be01b88fb818d6c8650..ed0a33a5f22cc9610734551616716d6f0d15c27f 100644 (file)
@@ -821,8 +821,6 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
                }
        }
 
-       cli_setup_signing_state(*cli, Undefined);
-
        result = cli_negprot(*cli);
 
        if (!NT_STATUS_IS_OK(result)) {
@@ -868,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;
                        }
                }
@@ -893,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;
                }
        }
@@ -919,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",
@@ -937,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;
        }
 
@@ -972,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;
@@ -1759,8 +1772,8 @@ static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
        NTSTATUS                result;
        WERROR werr;
        TALLOC_CTX              *mem_ctx = NULL;
-       struct rpc_pipe_client  *cli;
-       POLICY_HND pol;
+       struct rpc_pipe_client  *cli = NULL;
+       struct policy_handle pol;
        union dssetup_DsRoleInfo info;
        union lsa_PolicyInformation *lsa_info = NULL;
 
@@ -1977,11 +1990,10 @@ static bool cm_get_schannel_dcinfo(struct winbindd_domain *domain,
 }
 
 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
-                       struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
+                       struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
 {
        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;
@@ -2006,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);
@@ -2020,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;
        }
@@ -2145,11 +2156,10 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
 }
 
 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
-                       struct rpc_pipe_client **cli, POLICY_HND *lsa_policy)
+                       struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
 {
        struct winbindd_cm_conn *conn;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       fstring conn_pwd;
        struct dcinfo *p_dcinfo;
 
        result = init_dc_connection(domain);
@@ -2162,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;
@@ -2176,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 597d48aad0b88e545fb0f9098cedb27f831a9e28..15d1b7e2bf342c534fec63c420e20c8567eefae4 100644 (file)
@@ -1396,7 +1396,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
            NT_STATUS_IS_OK(result) && (my_info3->base.acct_flags == 0)) {
 
                struct rpc_pipe_client *samr_pipe;
-               POLICY_HND samr_domain_handle, user_pol;
+               struct policy_handle samr_domain_handle, user_pol;
                union samr_UserInfo *info = NULL;
                NTSTATUS status_tmp;
                uint32 acct_flags;
@@ -2066,7 +2066,7 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
 {
        char *oldpass;
        char *newpass = NULL;
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        struct rpc_pipe_client *cli;
        bool got_info = false;
        struct samr_DomInfo1 *info = NULL;
@@ -2394,7 +2394,7 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
        DATA_BLOB new_lm_password;
        DATA_BLOB old_lm_hash_enc;
        fstring  domain,user;
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        struct winbindd_domain *contact_domain = domainSt;
        struct rpc_pipe_client *cli;
 
index d704ca0fd35414235019e089580fdfa906875d5c..1a358b2b440ce6621c1d7cdebe37d09f5868afae 100644 (file)
@@ -40,9 +40,9 @@ static NTSTATUS enum_groups_internal(struct winbindd_domain *domain,
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
 
        if (sidtype == SID_NAME_ALIAS) {
-               search = pdb_search_aliases(&domain->sid);
+               search = pdb_search_aliases(talloc_tos(), &domain->sid);
        } else {
-               search = pdb_search_groups();
+               search = pdb_search_groups(talloc_tos());
        }
 
        if (search == NULL) goto done;
@@ -68,7 +68,7 @@ static NTSTATUS enum_groups_internal(struct winbindd_domain *domain,
 
        result = NT_STATUS_OK;
  done:
-       pdb_search_destroy(search);
+       TALLOC_FREE(search);
        return result;
 }
 
@@ -456,7 +456,7 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
                                uint32 *num_entries,
                                WINBIND_USERINFO **info)
 {
-       struct pdb_search *ps = pdb_search_users(ACB_NORMAL);
+       struct pdb_search *ps = pdb_search_users(talloc_tos(), ACB_NORMAL);
        struct samr_displayentry *entries = NULL;
        uint32 i;
 
@@ -473,7 +473,7 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
 
        *info = TALLOC_ZERO_ARRAY(mem_ctx, WINBIND_USERINFO, *num_entries);
        if (!(*info)) {
-               pdb_search_destroy(ps);
+               TALLOC_FREE(ps);
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -498,7 +498,7 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
                                DOMAIN_GROUP_RID_USERS);
        }
 
-       pdb_search_destroy(ps);
+       TALLOC_FREE(ps);
        return NT_STATUS_OK;
 }
 
index c6e8803ce863b015f78418eb0b066b78176289eb..384395f89648b06fc8da5fb69a1c304bec1566ed 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  */
@@ -206,9 +208,9 @@ void invalidate_cm_connection(struct winbindd_cm_conn *conn);
 void close_conns_after_fork(void);
 NTSTATUS init_dc_connection(struct winbindd_domain *domain);
 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
-                       struct rpc_pipe_client **cli, POLICY_HND *sam_handle);
+                       struct rpc_pipe_client **cli, struct policy_handle *sam_handle);
 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
-                       struct rpc_pipe_client **cli, POLICY_HND *lsa_policy);
+                       struct rpc_pipe_client **cli, struct policy_handle *lsa_policy);
 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
                             struct rpc_pipe_client **cli);
 
@@ -547,7 +549,6 @@ const char *get_winbind_pipe_dir(void) ;
 char *get_winbind_priv_pipe_dir(void) ;
 int open_winbindd_socket(void);
 int open_winbindd_priv_socket(void);
-void close_winbindd_socket(void);
 struct winbindd_cli_state *winbindd_client_list(void);
 void winbindd_add_client(struct winbindd_cli_state *cli);
 void winbindd_remove_client(struct winbindd_cli_state *cli);
index 0070bde2cc2cf478ceb46c601792238fdd5b60b9..5edb0d98b0508423be0e9ccf045480d54e0e739d 100644 (file)
@@ -38,7 +38,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
                               WINBIND_USERINFO **info)
 {
        NTSTATUS result;
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        unsigned int i, start_idx;
        uint32 loop_count;
        struct rpc_pipe_client *cli;
@@ -130,7 +130,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
                                uint32 *num_entries, 
                                struct acct_info **info)
 {
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        NTSTATUS status;
        uint32 start = 0;
        struct rpc_pipe_client *cli;
@@ -201,7 +201,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
                                uint32 *num_entries, 
                                struct acct_info **info)
 {
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        NTSTATUS result;
        struct rpc_pipe_client *cli;
 
@@ -278,7 +278,7 @@ static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
        enum lsa_SidType *types = NULL;
        char *full_name = NULL;
        struct rpc_pipe_client *cli;
-       POLICY_HND lsa_policy;
+       struct policy_handle lsa_policy;
        NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
        char *mapped_name = NULL;
 
@@ -343,7 +343,7 @@ static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
        enum lsa_SidType *types = NULL;
        NTSTATUS result;
        struct rpc_pipe_client *cli;
-       POLICY_HND lsa_policy;
+       struct policy_handle lsa_policy;
        NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
        char *mapped_name = NULL;
 
@@ -396,7 +396,7 @@ static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
        char **domains;
        NTSTATUS result;
        struct rpc_pipe_client *cli;
-       POLICY_HND lsa_policy;
+       struct policy_handle lsa_policy;
        DOM_SID *sids;
        size_t i;
        char **ret_names;
@@ -461,7 +461,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
                           WINBIND_USERINFO *user_info)
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       POLICY_HND dom_pol, user_pol;
+       struct policy_handle dom_pol, user_pol;
        union samr_UserInfo *info = NULL;
        uint32 user_rid;
        struct netr_SamInfo3 *user;
@@ -564,7 +564,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
                                  uint32 *num_groups, DOM_SID **user_grpsids)
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       POLICY_HND dom_pol, user_pol;
+       struct policy_handle dom_pol, user_pol;
        uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
        struct samr_RidWithAttributeArray *rid_array = NULL;
        unsigned int i;
@@ -645,7 +645,7 @@ static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
                                         uint32 **alias_rids)
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        uint32 num_query_sids = 0;
        int i;
        struct rpc_pipe_client *cli;
@@ -745,7 +745,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 {
         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
         uint32 i, total_names = 0;
-        POLICY_HND dom_pol, group_pol;
+        struct policy_handle dom_pol, group_pol;
         uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
        uint32 *rid_mem = NULL;
        uint32 group_rid;
@@ -857,14 +857,15 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
                }
 
                for (r=0; r<tmp_names.count; r++) {
-                       (*names)[i+r] = fill_domain_username_talloc(mem_ctx,
-                                               domain->name,
-                                               tmp_names.names[r].string,
-                                               true);
-                       (*name_types)[i+r] = tmp_types.ids[r];
+                       if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
+                               continue;
+                       }
+                       (*names)[total_names] = fill_domain_username_talloc(
+                               mem_ctx, domain->name,
+                               tmp_names.names[r].string, true);
+                       (*name_types)[total_names] = tmp_types.ids[r];
+                       total_names += 1;
                }
-
-               total_names += tmp_names.count;
         }
 
         *num_names = total_names;
@@ -952,7 +953,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
        TALLOC_CTX *mem_ctx;
        union samr_DomainInfo *info = NULL;
        NTSTATUS result;
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        bool got_seq_num = False;
        struct rpc_pipe_client *cli;
 
@@ -1053,7 +1054,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 enum_ctx = 0;
        struct rpc_pipe_client *cli;
-       POLICY_HND lsa_policy;
+       struct policy_handle lsa_policy;
 
        DEBUG(3,("rpc: trusted_domains\n"));
 
@@ -1111,7 +1112,7 @@ static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
 {
        NTSTATUS result;
        struct rpc_pipe_client *cli;
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        union samr_DomainInfo *info = NULL;
 
        DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
@@ -1152,7 +1153,7 @@ static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
 {
        NTSTATUS result;
        struct rpc_pipe_client *cli;
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        union samr_DomainInfo *info = NULL;
 
        DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
index 2d87015fec0ab249797436ac23ed7005aac6efd3..a2c1c85e0b357b4537123643f4fc231e7e07e502 100644 (file)
@@ -1316,24 +1316,6 @@ int open_winbindd_priv_socket(void)
        return _winbindd_priv_socket;
 }
 
-/* Close the winbindd socket */
-
-void close_winbindd_socket(void)
-{
-       if (_winbindd_socket != -1) {
-               DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
-                          _winbindd_socket));
-               close(_winbindd_socket);
-               _winbindd_socket = -1;
-       }
-       if (_winbindd_priv_socket != -1) {
-               DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
-                          _winbindd_priv_socket));
-               close(_winbindd_priv_socket);
-               _winbindd_priv_socket = -1;
-       }
-}
-
 /*
  * Client list accessor functions
  */
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 240a994f9df6de71a30bfe63236a0b76aae48665..8ad8f47cd6960c8721ba52738a5cec9434eab736 100644 (file)
@@ -31,11 +31,17 @@ AC_DEFUN(LIB_REMOVE_USR_LIB,[
     case [$]l[$]i in
     -L/usr/lib) ;;
     -L/usr/lib/) ;;
-    -Wl,-rpath,/usr/lib) ;;
-    -Wl,-rpath,/usr/lib/) ;;
+    -L/usr/lib64) ;;
+    -L/usr/lib64/) ;;
+    -Wl,-rpath,/usr/lib) l="";;
+    -Wl,-rpath,/usr/lib/) l="";;
+    -Wl,-rpath,/usr/lib64) l="";;
+    -Wl,-rpath,/usr/lib64/) l="";;
     -Wl,-rpath) l=[$]i;;
     -Wl,-rpath-Wl,/usr/lib) l="";;
     -Wl,-rpath-Wl,/usr/lib/) l="";;
+    -Wl,-rpath-Wl,/usr/lib64) l="";;
+    -Wl,-rpath-Wl,/usr/lib64/) l="";;
     *)
        s=" "
         if test x"[$]ac_new_flags" = x""; then
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..bd98a400be488e4af6ac5c0c86bd9c24126e0f9b 100644 (file)
@@ -82,7 +82,8 @@ AC_DEFUN([SMB_EXT_LIB_FROM_PKGCONFIG],
                echo "*** Or see http://pkg-config.freedesktop.org/ to get pkg-config."
                        ac_cv_$1_found=no
        else
-               if $PKG_CONFIG --atleast-pkgconfig-version 0.9.0; then
+               SAMBA_PKG_CONFIG_MIN_VERSION="0.9.0"
+               if $PKG_CONFIG --atleast-pkgconfig-version $SAMBA_PKG_CONFIG_MIN_VERSION; then
                        AC_MSG_CHECKING(for $2)
 
                        if $PKG_CONFIG --exists '$2' ; then
@@ -99,11 +100,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
@@ -112,7 +115,7 @@ AC_DEFUN([SMB_EXT_LIB_FROM_PKGCONFIG],
                                ac_cv_$1_found=no
                        fi
                else
-                       echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
+                       echo "*** Your version of pkg-config is too old. You need version $SAMBA_PKG_CONFIG_MIN_VERSION or newer."
                        echo "*** See http://pkg-config.freedesktop.org/"
                        ac_cv_$1_found=no
                fi
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 240f2b1dc23d3cb5ba9ea5d94e2ed8d9ac3bf2db..1a08cd21f90d2b871d02a329710b419e0228075a 100644 (file)
@@ -20,8 +20,8 @@
 */
 
 #include "includes.h"
+#include <talloc.h>
 #include "libcli/ldap/ldap.h"
-#include "lib/socket/socket.h"
 #include "lib/messaging/irpc.h"
 #include "smbd/service_task.h"
 #include "smbd/service.h"
 #include "ldb_wrap.h"
 #include "auth/auth.h"
 #include "param/param.h"
+#include "../lib/tsocket/tsocket.h"
 
 /*
   handle incoming cldap requests
 */
-static void cldapd_request_handler(struct cldap_socket *cldap, 
-                                  struct ldap_message *ldap_msg, 
-                                  struct socket_address *src)
+static void cldapd_request_handler(struct cldap_socket *cldap,
+                                  void *private_data,
+                                  struct cldap_incoming *in)
 {
+       struct cldapd_server *cldapd = talloc_get_type(private_data,
+                                      struct cldapd_server);
        struct ldap_SearchRequest *search;
-       if (ldap_msg->type != LDAP_TAG_SearchRequest) {
-               DEBUG(0,("Invalid CLDAP request type %d from %s:%d\n", 
-                        ldap_msg->type, src->addr, src->port));
-               cldap_error_reply(cldap, ldap_msg->messageid, src,
+
+       if (in->ldap_msg->type != LDAP_TAG_SearchRequest) {
+               DEBUG(0,("Invalid CLDAP request type %d from %s\n",
+                        in->ldap_msg->type,
+                        tsocket_address_string(in->src, in)));
+               cldap_error_reply(cldap, in->ldap_msg->messageid, in->src,
                                  LDAP_OPERATIONS_ERROR, "Invalid CLDAP request");
+               talloc_free(in);
                return;
        }
 
-       search = &ldap_msg->r.SearchRequest;
+       search = &in->ldap_msg->r.SearchRequest;
 
        if (strcmp("", search->basedn) != 0) {
-               DEBUG(0,("Invalid CLDAP basedn '%s' from %s:%d\n", 
-                        search->basedn, src->addr, src->port));
-               cldap_error_reply(cldap, ldap_msg->messageid, src,
+               DEBUG(0,("Invalid CLDAP basedn '%s' from %s\n",
+                        search->basedn,
+                        tsocket_address_string(in->src, in)));
+               cldap_error_reply(cldap, in->ldap_msg->messageid, in->src,
                                  LDAP_OPERATIONS_ERROR, "Invalid CLDAP basedn");
+               talloc_free(in);
                return;
        }
 
        if (search->scope != LDAP_SEARCH_SCOPE_BASE) {
-               DEBUG(0,("Invalid CLDAP scope %d from %s:%d\n", 
-                        search->scope, src->addr, src->port));
-               cldap_error_reply(cldap, ldap_msg->messageid, src,
+               DEBUG(0,("Invalid CLDAP scope %d from %s\n",
+                        search->scope,
+                        tsocket_address_string(in->src, in)));
+               cldap_error_reply(cldap, in->ldap_msg->messageid, in->src,
                                  LDAP_OPERATIONS_ERROR, "Invalid CLDAP scope");
+               talloc_free(in);
                return;
        }
 
        if (search->num_attributes == 1 &&
            strcasecmp(search->attributes[0], "netlogon") == 0) {
-               cldapd_netlogon_request(cldap, ldap_msg->messageid,
-                                       search->tree, src);
+               cldapd_netlogon_request(cldap,
+                                       cldapd,
+                                       in,
+                                       in->ldap_msg->messageid,
+                                       search->tree,
+                                       in->src);
+               talloc_free(in);
                return;
        }
 
-       cldapd_rootdse_request(cldap, ldap_msg->messageid,
-                              search, src);
+       cldapd_rootdse_request(cldap, cldapd, in,
+                              in->ldap_msg->messageid,
+                              search, in->src);
+       talloc_free(in);
 }
 
 
@@ -88,28 +105,36 @@ static NTSTATUS cldapd_add_socket(struct cldapd_server *cldapd, struct loadparm_
                                  const char *address)
 {
        struct cldap_socket *cldapsock;
-       struct socket_address *socket_address;
+       struct tsocket_address *socket_address;
        NTSTATUS status;
-
-       /* listen for unicasts on the CLDAP port (389) */
-       cldapsock = cldap_socket_init(cldapd, cldapd->task->event_ctx, lp_iconv_convenience(cldapd->task->lp_ctx));
-       NT_STATUS_HAVE_NO_MEMORY(cldapsock);
-
-       socket_address = socket_address_from_strings(cldapsock, cldapsock->sock->backend_name, 
-                                                    address, lp_cldap_port(lp_ctx));
-       if (!socket_address) {
-               talloc_free(cldapsock);
-               return NT_STATUS_NO_MEMORY;
+       int ret;
+
+       ret = tsocket_address_inet_from_strings(cldapd,
+                                               "ip",
+                                               address,
+                                               lp_cldap_port(lp_ctx),
+                                               &socket_address);
+       if (ret != 0) {
+               status = map_nt_error_from_unix(errno);
+               DEBUG(0,("invalid address %s:%d - %s:%s\n",
+                        address, lp_cldap_port(lp_ctx),
+                        gai_strerror(ret), nt_errstr(status)));
+               return status;
        }
 
-       status = socket_listen(cldapsock->sock, socket_address, 0, 0);
+       /* listen for unicasts on the CLDAP port (389) */
+       status = cldap_socket_init(cldapd,
+                                  cldapd->task->event_ctx,
+                                  socket_address,
+                                  NULL,
+                                  &cldapsock);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("Failed to bind to %s:%d - %s\n", 
-                        address, lp_cldap_port(lp_ctx), nt_errstr(status)));
-               talloc_free(cldapsock);
+               DEBUG(0,("Failed to bind to %s - %s\n", 
+                        tsocket_address_string(socket_address, socket_address),
+                        nt_errstr(status)));
+               talloc_free(socket_address);
                return status;
        }
-
        talloc_free(socket_address);
 
        cldap_set_incoming_handler(cldapsock, cldapd_request_handler, cldapd);
@@ -117,7 +142,6 @@ static NTSTATUS cldapd_add_socket(struct cldapd_server *cldapd, struct loadparm_
        return NT_STATUS_OK;
 }
 
-
 /*
   setup our listening sockets on the configured network interfaces
 */
index 0df35be6fdd59da03084217c7ca52949e027f6cc..33c0adc3b18b6d34a2f8abfe968d91124282cefb 100644 (file)
@@ -24,7 +24,6 @@
 #include "lib/ldb/include/ldb.h"
 #include "lib/ldb/include/ldb_errors.h"
 #include "lib/events/events.h"
-#include "lib/socket/socket.h"
 #include "smbd/service_task.h"
 #include "cldap_server/cldap_server.h"
 #include "librpc/gen_ndr/ndr_misc.h"
@@ -36,6 +35,8 @@
 #include "system/network.h"
 #include "lib/socket/netif.h"
 #include "param/param.h"
+#include "../lib/tsocket/tsocket.h"
+
 /*
   fill in the cldap netlogon union for a given version
 */
@@ -402,12 +403,13 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
 /*
   handle incoming cldap requests
 */
-void cldapd_netlogon_request(struct cldap_socket *cldap, 
+void cldapd_netlogon_request(struct cldap_socket *cldap,
+                            struct cldapd_server *cldapd,
+                            TALLOC_CTX *tmp_ctx,
                             uint32_t message_id,
                             struct ldb_parse_tree *tree,
-                            struct socket_address *src)
+                            struct tsocket_address *src)
 {
-       struct cldapd_server *cldapd = talloc_get_type(cldap->incoming.private_data, struct cldapd_server);
        int i;
        const char *domain = NULL;
        const char *host = NULL;
@@ -419,8 +421,6 @@ void cldapd_netlogon_request(struct cldap_socket *cldap,
        struct netlogon_samlogon_response netlogon;
        NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
 
-       TALLOC_CTX *tmp_ctx = talloc_new(cldap);
-
        if (tree->operation != LDB_OP_AND) goto failed;
 
        /* extract the query elements */
@@ -478,24 +478,25 @@ void cldapd_netlogon_request(struct cldap_socket *cldap,
                 domain, host, user, version, domain_guid));
 
        status = fill_netlogon_samlogon_response(cldapd->samctx, tmp_ctx, domain, NULL, NULL, domain_guid,
-                                                user, acct_control, src->addr, 
+                                                user, acct_control,
+                                                tsocket_address_inet_addr_string(src, tmp_ctx),
                                                 version, cldapd->task->lp_ctx, &netlogon);
        if (!NT_STATUS_IS_OK(status)) {
                goto failed;
        }
 
-       status = cldap_netlogon_reply(cldap, message_id, src, version,
+       status = cldap_netlogon_reply(cldap,
+                                     lp_iconv_convenience(cldapd->task->lp_ctx),
+                                     message_id, src, version,
                                      &netlogon);
        if (!NT_STATUS_IS_OK(status)) {
                goto failed;
        }
 
-       talloc_free(tmp_ctx);
        return;
        
 failed:
        DEBUG(2,("cldap netlogon query failed domain=%s host=%s version=%d - %s\n",
                 domain, host, version, nt_errstr(status)));
-       talloc_free(tmp_ctx);
-       cldap_empty_reply(cldap, message_id, src);      
+       cldap_empty_reply(cldap, message_id, src);
 }
index daa5060d07cf7ae1580f410711bec33c9a02488d..7e867deff29f2d244c6d82558d55dc4eb8310b16 100644 (file)
 */
 
 #include "includes.h"
+#include <tevent.h>
 #include "libcli/ldap/ldap.h"
 #include "lib/ldb/include/ldb.h"
 #include "lib/ldb/include/ldb_errors.h"
-#include "lib/events/events.h"
-#include "lib/socket/socket.h"
 #include "smbd/service_task.h"
 #include "cldap_server/cldap_server.h"
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "dsdb/samdb/samdb.h"
-#include "auth/auth.h"
 #include "ldb_wrap.h"
-#include "system/network.h"
-#include "lib/socket/netif.h"
 
 static void cldapd_rootdse_fill(struct cldapd_server *cldapd,
                                TALLOC_CTX *mem_ctx,
@@ -151,15 +147,15 @@ done:
   handle incoming cldap requests
 */
 void cldapd_rootdse_request(struct cldap_socket *cldap, 
+                           struct cldapd_server *cldapd,
+                           TALLOC_CTX *tmp_ctx,
                            uint32_t message_id,
                            struct ldap_SearchRequest *search,
-                           struct socket_address *src)
+                           struct tsocket_address *src)
 {
-       struct cldapd_server *cldapd = talloc_get_type(cldap->incoming.private_data, struct cldapd_server);
        NTSTATUS status;
        struct cldap_reply reply;
        struct ldap_Result result;
-       TALLOC_CTX *tmp_ctx = talloc_new(cldap);
 
        ZERO_STRUCT(result);
 
@@ -176,6 +172,5 @@ void cldapd_rootdse_request(struct cldap_socket *cldap,
                         ldb_filter_from_tree(tmp_ctx, search->tree), nt_errstr(status)));
        }
 
-       talloc_free(tmp_ctx);
        return;
 }
index 54ca9108b14d0d7857d34c06e772781f93a72188..065a3300cab5d82ffc142be8b8c97980424ee1aa 100644 (file)
@@ -42,14 +42,16 @@ AC_CONFIG_FILES(param/samba-hostconfig.pc)
 AC_CONFIG_FILES(librpc/dcerpc_samr.pc)
 AC_CONFIG_FILES(librpc/dcerpc_atsvc.pc)
 
-SMB_INCLUDED_LIB_PKGCONFIG(LIBTALLOC, talloc >= 1.2.0, [],
+m4_include(min_versions.m4)
+
+SMB_INCLUDED_LIB_PKGCONFIG(LIBTALLOC, talloc >= $TALLOC_MIN_VERSION, [],
        [
                m4_include(../lib/talloc/libtalloc.m4)
                SMB_INCLUDE_MK(../lib/talloc/config.mk)
        ]
 )
 
-SMB_INCLUDED_LIB_PKGCONFIG(LIBTDB, tdb >= 1.1.3,
+SMB_INCLUDED_LIB_PKGCONFIG(LIBTDB, tdb >= $TDB_MIN_VERSION,
        [],
        [
                m4_include(../lib/tdb/libtdb.m4)
@@ -59,13 +61,13 @@ 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 = TEVENT_REQUIRED_VERSION,
        [],[m4_include(../lib/tevent/samba.m4)]
 )
 
 SMB_INCLUDE_MK(../lib/tevent/python.mk) 
 
-SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = 0.9.3,
+SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = $LDB_REQUIRED_VERSION,
        [
                SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk)
                SMB_INCLUDE_MK(lib/ldb/tools/config.mk)
index 898d9139659598745acebe4ebb554e23aa4bdb7f..7883bccfe70e934f0df1c16c50f142cc13633912 100644 (file)
@@ -414,6 +414,7 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
        struct oc_context *ac;
        struct ldb_dn *parent_dn;
        int ret;
+       static const char * const parent_attrs[] = { "objectGUID", NULL };
 
        ldb = ldb_module_get_ctx(module);
 
@@ -449,7 +450,7 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
 
        ret = ldb_build_search_req(&search_req, ldb,
                                   ac, parent_dn, LDB_SCOPE_BASE,
-                                  "(objectClass=*)", NULL,
+                                  "(objectClass=*)", parent_attrs,
                                   NULL,
                                   ac, get_search_callback,
                                   req);
@@ -500,7 +501,8 @@ static int objectclass_do_add(struct oc_context *ac)
                        return LDB_ERR_UNWILLING_TO_PERFORM;
                }
        } else {
-               
+               const struct ldb_val *parent_guid;
+
                /* Fix up the DN to be in the standard form, taking particular care to match the parent DN */
                ret = fix_dn(msg, 
                             ac->req->op.add.message->dn,
@@ -514,10 +516,24 @@ static int objectclass_do_add(struct oc_context *ac)
                        return ret;
                }
 
+               parent_guid = ldb_msg_find_ldb_val(ac->search_res->message, "objectGUID");
+               if (parent_guid == NULL) {
+                       ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, parent does not have an objectGUID!", 
+                                              ldb_dn_get_linearized(msg->dn));
+                       talloc_free(mem_ctx);
+                       return LDB_ERR_UNWILLING_TO_PERFORM;                    
+               }
+
                /* TODO: Check this is a valid child to this parent,
                 * by reading the allowedChildClasses and
                 * allowedChildClasssesEffective attributes */
-
+               ret = ldb_msg_add_steal_value(msg, "parentGUID", discard_const(parent_guid));
+               if (ret != LDB_SUCCESS) {
+                       ldb_asprintf_errstring(ldb, "objectclass: Cannot add %s, failed to add parentGUID", 
+                                              ldb_dn_get_linearized(msg->dn));
+                       talloc_free(mem_ctx);
+                       return LDB_ERR_UNWILLING_TO_PERFORM;                                            
+               }
        }
 
        if (schema) {
@@ -974,7 +990,7 @@ static int objectclass_do_rename(struct oc_context *ac);
 
 static int objectclass_rename(struct ldb_module *module, struct ldb_request *req)
 {
-       static const char * const attrs[] = { NULL };
+       static const char * const attrs[] = { "objectGUID", NULL };
        struct ldb_context *ldb;
        struct ldb_request *search_req;
        struct oc_context *ac;
@@ -1007,6 +1023,9 @@ static int objectclass_rename(struct ldb_module *module, struct ldb_request *req
                ldb_oom(ldb);
                return LDB_ERR_OPERATIONS_ERROR;
        }
+
+       /* note that the results of this search are kept and used to
+          update the parentGUID in objectclass_rename_callback() */
        ret = ldb_build_search_req(&search_req, ldb,
                                   ac, parent_dn, LDB_SCOPE_BASE,
                                   "(objectClass=*)",
@@ -1022,6 +1041,66 @@ static int objectclass_rename(struct ldb_module *module, struct ldb_request *req
        return ldb_next_request(ac->module, search_req);
 }
 
+/* 
+   called after the rename happens. 
+   We now need to fix the parentGUID of the object to be the objectGUID of
+   the new parent 
+*/
+static int objectclass_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+       struct ldb_context *ldb;
+       struct oc_context *ac;
+       const struct ldb_val *parent_guid;
+       struct ldb_request *mod_req = NULL;
+       int ret;
+       struct ldb_message *msg;
+       struct ldb_message_element *el = NULL;
+
+       ac = talloc_get_type(req->context, struct oc_context);
+       ldb = ldb_module_get_ctx(ac->module);
+
+       /* make sure the rename succeeded */
+       if (!ares) {
+               return ldb_module_done(ac->req, NULL, NULL,
+                                       LDB_ERR_OPERATIONS_ERROR);
+       }
+       if (ares->error != LDB_SUCCESS) {
+               return ldb_module_done(ac->req, ares->controls,
+                                       ares->response, ares->error);
+       }
+
+
+       /* the ac->search_res should contain the new parents objectGUID */
+       parent_guid = ldb_msg_find_ldb_val(ac->search_res->message, "objectGUID");
+       if (parent_guid == NULL) {
+               ldb_asprintf_errstring(ldb, "objectclass: Cannot rename %s, new parent does not have an objectGUID!", 
+                                      ldb_dn_get_linearized(ac->req->op.rename.newdn));
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+
+       }
+
+       /* construct the modify message */
+       msg = ldb_msg_new(ac);
+       if (msg == NULL) {
+               ldb_oom(ldb);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       msg->dn = ac->req->op.rename.newdn;
+
+       ret = ldb_msg_add_value(msg, "parentGUID", parent_guid, &el);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+
+       el->flags = LDB_FLAG_MOD_REPLACE;
+
+       ret = ldb_build_mod_req(&mod_req, ldb, ac, msg,
+                               NULL, ac, oc_op_callback, req);
+
+       return ldb_next_request(ac->module, mod_req);
+}
+
 static int objectclass_do_rename(struct oc_context *ac)
 {
        struct ldb_context *ldb;
@@ -1055,7 +1134,7 @@ static int objectclass_do_rename(struct oc_context *ac)
        ret = ldb_build_rename_req(&rename_req, ldb, ac,
                                   ac->req->op.rename.olddn, fixed_dn,
                                   ac->req->controls,
-                                  ac, oc_op_callback,
+                                  ac, objectclass_rename_callback,
                                   ac->req);
        if (ret != LDB_SUCCESS) {
                return ret;
index 56d4c4fe36855f71e8d5b208347d1ee5f8fa2f02..5a9926b6d18c6e8113512e346b69b77941db3191 100644 (file)
@@ -1379,7 +1379,8 @@ static int setup_password_fields(struct setup_password_fields_io *io)
        if (io->n.cleartext_utf8) {
                struct samr_Password *lm_hash;
                char *cleartext_unix;
-               if (convert_string_talloc_convenience(io->ac, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), 
+               if (lp_lanman_auth(ldb_get_opaque(ldb, "loadparm")) &&
+                   convert_string_talloc_convenience(io->ac, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), 
                                                         CH_UTF8, CH_UNIX, io->n.cleartext_utf8->data, io->n.cleartext_utf8->length, 
                                                         (void **)&cleartext_unix, &converted_pw_len, false)) {
                        lm_hash = talloc(io->ac, struct samr_Password);
index fbd8946bb59f2a056dc217ab07edb9234182b2f4..a67aecd1e866289cf6e119eb8e74e3524ef9ab1e 100644 (file)
@@ -1202,6 +1202,34 @@ static struct drsuapi_DsReplicaAttribute *dsdb_find_object_attr_name(struct dsdb
        } \
 } while (0)
 
+#define GET_STRING_LIST_DS(s, r, attr, mem_ctx, p, elem, strict) do { \
+       int get_string_list_counter;                                    \
+       struct drsuapi_DsReplicaAttribute *_a; \
+       _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
+       if (strict && !_a) { \
+               d_printf("%s: %s == NULL\n", __location__, attr); \
+               return WERR_INVALID_PARAM; \
+       } \
+       (p)->elem = _a ? talloc_array(mem_ctx, const char *, _a->value_ctr.num_values + 1) : NULL; \
+        for (get_string_list_counter=0;                                        \
+            _a && get_string_list_counter < _a->value_ctr.num_values;  \
+            get_string_list_counter++) {                               \
+               size_t _ret;                                            \
+               if (!convert_string_talloc_convenience(mem_ctx, s->iconv_convenience, CH_UTF16, CH_UNIX, \
+                                            _a->value_ctr.values[get_string_list_counter].blob->data, \
+                                            _a->value_ctr.values[get_string_list_counter].blob->length, \
+                                                      (void **)discard_const(&(p)->elem[get_string_list_counter]), &_ret, false)) { \
+                       DEBUG(0,("%s: invalid data!\n", attr)); \
+                       dump_data(0, \
+                                    _a->value_ctr.values[get_string_list_counter].blob->data, \
+                                    _a->value_ctr.values[get_string_list_counter].blob->length); \
+                       return WERR_FOOBAR; \
+               } \
+               (p)->elem[get_string_list_counter+1] = NULL;            \
+       }                                                               \
+       talloc_steal(mem_ctx, (p)->elem);                               \
+} while (0)
+
 #define GET_DN_DS(s, r, attr, mem_ctx, p, elem, strict) do { \
        struct drsuapi_DsReplicaAttribute *_a; \
        _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
@@ -1412,17 +1440,18 @@ WERROR dsdb_class_from_drsuapi(struct dsdb_schema *schema,
 
        GET_STRING_DS(schema, r, "subClassOf", mem_ctx, obj, subClassOf, true);
 
-       obj->systemAuxiliaryClass       = NULL;
-       obj->systemPossSuperiors        = NULL;
-       obj->systemMustContain          = NULL;
-       obj->systemMayContain           = NULL;
 
-       obj->auxiliaryClass             = NULL;
-       obj->possSuperiors              = NULL;
-       obj->mustContain                = NULL;
-       obj->mayContain                 = NULL;
+       GET_STRING_LIST_DS(schema, r, "systemAuxiliaryClass", mem_ctx, obj, systemAuxiliaryClass, false);
+       GET_STRING_LIST_DS(schema, r, "auxiliaryClass", mem_ctx, obj, auxiliaryClass, false);
+
+       GET_STRING_LIST_DS(schema, r, "systemMustContain", mem_ctx, obj, systemMustContain, false);
+       GET_STRING_LIST_DS(schema, r, "systemMayContain", mem_ctx, obj, systemMayContain, false);
+       GET_STRING_LIST_DS(schema, r, "mustContain", mem_ctx, obj, mustContain, false);
+       GET_STRING_LIST_DS(schema, r, "mayContain", mem_ctx, obj, mayContain, false);
 
-       obj->possibleInferiors          = NULL;
+       GET_STRING_LIST_DS(schema, r, "systemPossSuperiors", mem_ctx, obj, systemPossSuperiors, false);
+       GET_STRING_LIST_DS(schema, r, "possSuperiors", mem_ctx, obj, possSuperiors, false);
+       GET_STRING_LIST_DS(schema, r, "possibleInferiors", mem_ctx, obj, possibleInferiors, false);
 
        GET_STRING_DS(schema, r, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, false);
 
index 82870446223ef7d715aa70b601e684af1ba31cfa..280d60beb2fb1f58f4a7ba9e71700340ff6391bc 100644 (file)
@@ -9,7 +9,9 @@
 ../lib/util/memory.h: util/memory.h
 ../lib/util/talloc_stack.h: util/talloc_stack.h
 ../lib/util/xfile.h: util/xfile.h
-lib/tdr/tdr.h: tdr.h
+../lib/tdr/tdr.h: tdr.h
+../lib/tsocket/tsocket.h: tsocket.h
+../lib/tsocket/tsocket_internal.h: tsocket_internal.h
 librpc/rpc/dcerpc.h: dcerpc.h
 lib/ldb/include/ldb.h: ldb.h
 lib/ldb/include/ldb_errors.h: ldb_errors.h
@@ -23,7 +25,7 @@ lib/registry/registry.h: registry.h
 libcli/util/werror.h: core/werror.h
 libcli/util/doserr.h: core/doserr.h
 libcli/util/ntstatus.h: core/ntstatus.h
-libcli/cldap/cldap.h: cldap.h
+../libcli/cldap/cldap.h: cldap.h
 auth/credentials/credentials.h: credentials.h
 auth/credentials/credentials_krb5.h: credentials/krb5.h
 rpc_server/dcerpc_server.h: dcerpc_server.h
index ddda21f9d8efa55c0ef350393828369995662d4a..d9b7759e7e9ee47807ce498b15706e69affc5d12 100644 (file)
 /* String routines */
 #include "../lib/util/safe_string.h"
 
-#ifndef CONST_DISCARD
-#define CONST_DISCARD(type, ptr)      ((type) ((void *) (ptr)))
-#endif
-
 #if 0
 /* darn, we can't do this now that we don't link the ldb tools to all the smb libs */
 #define TALLOC_ABORT(reason) smb_panic(reason)
index 733d12a443305c5caad6b4dfd3055a9a9b3770c0..2f4ab2c1786e84261e7ecfdea7b0e46619d9e197 100644 (file)
@@ -28,6 +28,10 @@ extern struct poptOption popt_common_connection[];
 extern struct poptOption popt_common_version[];
 extern struct poptOption popt_common_credentials[];
 
+#ifndef POPT_TABLEEND
+#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
+#endif
+
 #define POPT_COMMON_SAMBA { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_samba, 0, "Common samba options:", NULL },
 #define POPT_COMMON_CONNECTION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_connection, 0, "Connection options:", NULL },
 #define POPT_COMMON_VERSION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version, 0, "Common samba options:", NULL },
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 ad27c9a9a9a9d77f7b8a9b397f30451731852ca5..c99c2936d850236720c070fcfe0435b26f0581e7 100644 (file)
@@ -1055,7 +1055,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
 
                ret = ldb_module_send_entry(ac->req, msg, NULL);
                if (ret != LDB_SUCCESS) {
-                       ac->callback_failed = true;
+                       ac->request_terminated = true;
                        return ret;
                }
        }
index 0f595267fcbcfbf7fd07aeb7f548490da2677a8c..d395c28f287a922e45bd1b85c88032445ed8777d 100644 (file)
@@ -424,10 +424,10 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
 
        ret = ldb_module_send_entry(ac->req, msg, NULL);
        if (ret != LDB_SUCCESS) {
-               ac->callback_failed = true;
+               ac->request_terminated = true;
                /* the callback failed, abort the operation */
                return -1;
-       }       
+       }
 
        return 0;
 }
@@ -544,7 +544,7 @@ int ltdb_search(struct ltdb_context *ctx)
                /* Check if we got just a normal error.
                 * In that case proceed to a full search unless we got a
                 * callback error */
-               if ( ! ctx->callback_failed && ret != LDB_SUCCESS) {
+               if ( ! ctx->request_terminated && ret != LDB_SUCCESS) {
                        /* Not indexed, so we need to do a full scan */
                        ret = ltdb_search_full(ctx);
                        if (ret != LDB_SUCCESS) {
index 24ec06ea32056cfe1d9ef2a9b5cbc34097bff326..9df62be93631baad29a71c60aea97ad2d75a2761 100644 (file)
@@ -1019,7 +1019,16 @@ static void ltdb_timeout(struct tevent_context *ev,
        struct ltdb_context *ctx;
        ctx = talloc_get_type(private_data, struct ltdb_context);
 
-       ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED);
+       if (!ctx->request_terminated) {
+               /* request is done now */
+               ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED);
+       }
+
+       if (!ctx->request_terminated) {
+               /* neutralize the spy */
+               ctx->spy->ctx = NULL;
+       }
+       talloc_free(ctx);
 }
 
 static void ltdb_request_extended_done(struct ltdb_context *ctx,
@@ -1078,6 +1087,10 @@ static void ltdb_callback(struct tevent_context *ev,
 
        ctx = talloc_get_type(private_data, struct ltdb_context);
 
+       if (ctx->request_terminated) {
+               goto done;
+       }
+
        switch (ctx->req->operation) {
        case LDB_SEARCH:
                ret = ltdb_search(ctx);
@@ -1096,17 +1109,34 @@ static void ltdb_callback(struct tevent_context *ev,
                break;
        case LDB_EXTENDED:
                ltdb_handle_extended(ctx);
-               return;
+               goto done;
        default:
                /* no other op supported */
                ret = LDB_ERR_UNWILLING_TO_PERFORM;
        }
 
-       if (!ctx->callback_failed) {
-               /* Once we are done, we do not need timeout events */
-               talloc_free(ctx->timeout_event);
+       if (!ctx->request_terminated) {
+               /* request is done now */
                ltdb_request_done(ctx, ret);
        }
+
+done:
+       if (!ctx->request_terminated) {
+               /* neutralize the spy */
+               ctx->spy->ctx = NULL;
+       }
+       talloc_free(ctx);
+}
+
+static int ltdb_request_destructor(void *ptr)
+{
+       struct ltdb_req_spy *spy = talloc_get_type(ptr, struct ltdb_req_spy);
+
+       if (spy->ctx != NULL) {
+               spy->ctx->request_terminated = true;
+       }
+
+       return 0;
 }
 
 static int ltdb_handle_request(struct ldb_module *module,
@@ -1131,7 +1161,7 @@ static int ltdb_handle_request(struct ldb_module *module,
 
        ev = ldb_get_event_context(ldb);
 
-       ac = talloc_zero(req, struct ltdb_context);
+       ac = talloc_zero(ldb, struct ltdb_context);
        if (ac == NULL) {
                ldb_set_errstring(ldb, "Out of Memory");
                return LDB_ERR_OPERATIONS_ERROR;
@@ -1144,15 +1174,28 @@ static int ltdb_handle_request(struct ldb_module *module,
        tv.tv_usec = 0;
        te = tevent_add_timer(ev, ac, tv, ltdb_callback, ac);
        if (NULL == te) {
+               talloc_free(ac);
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
        tv.tv_sec = req->starttime + req->timeout;
        ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac);
        if (NULL == ac->timeout_event) {
+               talloc_free(ac);
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
+       /* set a spy so that we do not try to use the request context
+        * if it is freed before ltdb_callback fires */
+       ac->spy = talloc(req, struct ltdb_req_spy);
+       if (NULL == ac->spy) {
+               talloc_free(ac);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       ac->spy->ctx = ac;
+
+       talloc_set_destructor((TALLOC_CTX *)ac->spy, ltdb_request_destructor);
+
        return LDB_SUCCESS;
 }
 
index 0a06cdb1b0816583b5bf74f3266227948bdc7146..5a1c8fee2d7482948754bcc5e264c914e8da2d79 100644 (file)
@@ -36,11 +36,16 @@ struct ltdb_private {
   the async local context
   holds also internal search state during a full db search
 */
+struct ltdb_req_spy {
+       struct ltdb_context *ctx;
+};
+
 struct ltdb_context {
        struct ldb_module *module;
        struct ldb_request *req;
 
-       bool callback_failed;
+       bool request_terminated;
+       struct ltdb_req_spy *spy;
 
        /* search stuff */
        const struct ldb_parse_tree *tree;
index a30273fc66804ad5989dcc7759af8a685749860e..7d2c7d054723c431e391dffa1d8a306d1f5c536d 100755 (executable)
@@ -90,6 +90,36 @@ class BasicTests(unittest.TestCase):
         except LdbError, (num, _): 
             self.assertEquals(num, ERR_NO_SUCH_OBJECT)
 
+    def test_parentGUID(self):
+        """Test parentGUID behaviour"""
+        print "Testing parentGUID behaviour\n"
+        
+        self.ldb.add({
+            "dn": "cn=parentguidtest,cn=users," + self.base_dn,
+            "objectclass":"user",
+            "samaccountname":"parentguidtest"});
+        res1 = ldb.search(base="cn=parentguidtest,cn=users," + self.base_dn, scope=SCOPE_BASE,
+                          attrs=["parentGUID"]);
+        res2 = ldb.search(base="cn=users," + self.base_dn,scope=SCOPE_BASE,
+                          attrs=["objectGUID"]);
+        self.assertEquals(res1[0]["parentGUID"], res2[0]["objectGUID"]);
+
+        """Test parentGUID behaviour"""
+        print "Testing parentGUID behaviour on rename\n"
+
+        self.ldb.add({
+            "dn": "cn=testotherusers," + self.base_dn,
+            "objectclass":"container"});
+        res1 = ldb.search(base="cn=testotherusers," + self.base_dn,scope=SCOPE_BASE,
+                          attrs=["objectGUID"]);
+        ldb.rename("cn=parentguidtest,cn=users," + self.base_dn,
+                   "cn=parentguidtest,cn=testotherusers," + self.base_dn);
+        res2 = ldb.search(base="cn=parentguidtest,cn=testotherusers," + self.base_dn,
+                          scope=SCOPE_BASE,
+                          attrs=["parentGUID"]);
+        self.assertEquals(res1[0]["objectGUID"], res2[0]["parentGUID"]);
+        
+
     def test_all(self):
         """Basic tests"""
 
index 3473d62a16992102da356423d77cbed867ff9f54..45619ce496a7c8164bc35b0e4b8717d492e138f6 100644 (file)
@@ -50,5 +50,4 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const
                                        void (*usage)(void));
 
 
-struct ldb_control **parse_controls(void *mem_ctx, char **control_strings);
 int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request);
diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c
deleted file mode 100644 (file)
index b18ba12..0000000
+++ /dev/null
@@ -1,738 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-
-   cldap client library
-
-   Copyright (C) Andrew Tridgell 2005
-   
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
-  see RFC1798 for details of CLDAP
-
-  basic properties
-    - carried over UDP on port 389
-    - request and response matched by message ID
-    - request consists of only a single searchRequest element
-    - response can be in one of two forms
-       - a single searchResponse, followed by a searchResult
-       - a single searchResult
-*/
-
-#include "includes.h"
-#include "lib/events/events.h"
-#include "../lib/util/dlinklist.h"
-#include "libcli/ldap/ldap.h"
-#include "libcli/ldap/ldap_ndr.h"
-#include "libcli/cldap/cldap.h"
-#include "lib/socket/socket.h"
-#include "libcli/security/security.h"
-#include "librpc/gen_ndr/ndr_nbt.h"
-
-/*
-  destroy a pending request
-*/
-static int cldap_request_destructor(struct cldap_request *req)
-{
-       if (req->state == CLDAP_REQUEST_SEND) {
-               DLIST_REMOVE(req->cldap->send_queue, req);
-       }
-       if (!req->is_reply && req->message_id != 0) {
-               idr_remove(req->cldap->idr, req->message_id);
-               req->message_id = 0;
-       }
-       return 0;
-}
-
-/*
-  handle recv events on a cldap socket
-*/
-static void cldap_socket_recv(struct cldap_socket *cldap)
-{
-       TALLOC_CTX *tmp_ctx = talloc_new(cldap);
-       NTSTATUS status;
-       struct socket_address *src;
-       DATA_BLOB blob;
-       size_t nread, dsize;
-       struct asn1_data *asn1 = asn1_init(tmp_ctx);
-       struct ldap_message *ldap_msg;
-       struct cldap_request *req;
-
-       if (!asn1) return;
-
-       status = socket_pending(cldap->sock, &dsize);
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(tmp_ctx);
-               return;
-       }
-
-       blob = data_blob_talloc(tmp_ctx, NULL, dsize);
-       if (blob.data == NULL) {
-               talloc_free(tmp_ctx);
-               return;
-       }
-
-       status = socket_recvfrom(cldap->sock, blob.data, blob.length, &nread,
-                                tmp_ctx, &src);
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(tmp_ctx);
-               return;
-       }
-       blob.length = nread;
-
-       DEBUG(2,("Received cldap packet of length %d from %s:%d\n", 
-                (int)blob.length, src->addr, src->port));
-
-       if (!asn1_load(asn1, blob)) {
-               DEBUG(2,("Failed to setup for asn.1 decode\n"));
-               talloc_free(tmp_ctx);
-               return;
-       }
-
-       ldap_msg = talloc(tmp_ctx, struct ldap_message);
-       if (ldap_msg == NULL) {
-               talloc_free(tmp_ctx);
-               return;
-       }
-
-       /* this initial decode is used to find the message id */
-       status = ldap_decode(asn1, NULL, ldap_msg);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(2,("Failed to decode ldap message: %s\n", nt_errstr(status)));
-               talloc_free(tmp_ctx);
-               return;
-       }
-
-       /* find the pending request */
-       req = idr_find(cldap->idr, ldap_msg->messageid);
-       if (req == NULL) {
-               if (cldap->incoming.handler) {
-                       cldap->incoming.handler(cldap, ldap_msg, src);
-               } else {
-                       DEBUG(2,("Mismatched cldap reply %u from %s:%d\n",
-                                ldap_msg->messageid, src->addr, src->port));
-               }
-               talloc_free(tmp_ctx);
-               return;
-       }
-
-       req->asn1 = talloc_steal(req, asn1);
-       req->asn1->ofs = 0;
-
-       req->state = CLDAP_REQUEST_DONE;
-       talloc_free(req->te);
-
-       talloc_free(tmp_ctx);
-
-       if (req->async.fn) {
-               req->async.fn(req);
-       }
-}
-
-/*
-  handle request timeouts
-*/
-static void cldap_request_timeout(struct tevent_context *event_ctx, 
-                                 struct tevent_timer *te, struct timeval t,
-                                 void *private_data)
-{
-       struct cldap_request *req = talloc_get_type(private_data, struct cldap_request);
-
-       /* possibly try again */
-       if (req->num_retries != 0) {
-               size_t len = req->encoded.length;
-
-               req->num_retries--;
-
-               socket_sendto(req->cldap->sock, &req->encoded, &len, 
-                             req->dest);
-
-               req->te = event_add_timed(req->cldap->event_ctx, req, 
-                                         timeval_current_ofs(req->timeout, 0),
-                                         cldap_request_timeout, req);
-               return;
-       }
-
-       req->state = CLDAP_REQUEST_ERROR;
-       req->status = NT_STATUS_IO_TIMEOUT;
-       if (req->async.fn) {
-               req->async.fn(req);
-       }
-}
-
-/*
-  handle send events on a cldap socket
-*/
-static void cldap_socket_send(struct cldap_socket *cldap)
-{
-       struct cldap_request *req;
-       NTSTATUS status;
-
-       while ((req = cldap->send_queue)) {
-               size_t len;
-               
-               len = req->encoded.length;
-               status = socket_sendto(cldap->sock, &req->encoded, &len,
-                                      req->dest);
-               if (NT_STATUS_IS_ERR(status)) {
-                       DEBUG(0,("Failed to send cldap request of length %u to %s:%d\n",
-                                (unsigned)req->encoded.length, req->dest->addr, req->dest->port));
-                       DLIST_REMOVE(cldap->send_queue, req);
-                       req->state = CLDAP_REQUEST_ERROR;
-                       req->status = status;
-                       if (req->async.fn) {
-                               req->async.fn(req);
-                       }
-                       continue;
-               }
-
-               if (!NT_STATUS_IS_OK(status)) return;
-
-               DLIST_REMOVE(cldap->send_queue, req);
-
-               if (req->is_reply) {
-                       talloc_free(req);
-               } else {
-                       req->state = CLDAP_REQUEST_WAIT;
-
-                       req->te = event_add_timed(cldap->event_ctx, req, 
-                                                 timeval_current_ofs(req->timeout, 0),
-                                                 cldap_request_timeout, req);
-
-                       EVENT_FD_READABLE(cldap->fde);
-               }
-       }
-
-       EVENT_FD_NOT_WRITEABLE(cldap->fde);
-       return;
-}
-
-
-/*
-  handle fd events on a cldap_socket
-*/
-static void cldap_socket_handler(struct tevent_context *ev, struct tevent_fd *fde,
-                                uint16_t flags, void *private_data)
-{
-       struct cldap_socket *cldap = talloc_get_type(private_data, struct cldap_socket);
-       if (flags & EVENT_FD_WRITE) {
-               cldap_socket_send(cldap);
-       } 
-       if (flags & EVENT_FD_READ) {
-               cldap_socket_recv(cldap);
-       }
-}
-
-/*
-  initialise a cldap_socket. The event_ctx is optional, if provided
-  then operations will use that event context
-*/
-struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx, 
-                                      struct tevent_context *event_ctx,
-                                      struct smb_iconv_convenience *iconv_convenience)
-{
-       struct cldap_socket *cldap;
-       NTSTATUS status;
-
-       cldap = talloc(mem_ctx, struct cldap_socket);
-       if (cldap == NULL) goto failed;
-
-       cldap->event_ctx = talloc_reference(cldap, event_ctx);
-       if (cldap->event_ctx == NULL) goto failed;
-
-       cldap->idr = idr_init(cldap);
-       if (cldap->idr == NULL) goto failed;
-
-       status = socket_create("ip", SOCKET_TYPE_DGRAM, &cldap->sock, 0);
-       if (!NT_STATUS_IS_OK(status)) goto failed;
-
-       talloc_steal(cldap, cldap->sock);
-
-       cldap->fde = event_add_fd(cldap->event_ctx, cldap, 
-                                     socket_get_fd(cldap->sock), 0,
-                                     cldap_socket_handler, cldap);
-
-       cldap->send_queue = NULL;
-       cldap->incoming.handler = NULL;
-       cldap->iconv_convenience = iconv_convenience;
-       
-       return cldap;
-
-failed:
-       talloc_free(cldap);
-       return NULL;
-}
-
-
-/*
-  setup a handler for incoming requests
-*/
-NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap,
-                                 void (*handler)(struct cldap_socket *, struct ldap_message *, 
-                                                 struct socket_address *),
-                                 void *private_data)
-{
-       cldap->incoming.handler = handler;
-       cldap->incoming.private_data = private_data;
-       EVENT_FD_READABLE(cldap->fde);
-       return NT_STATUS_OK;
-}
-
-/*
-  queue a cldap request for send
-*/
-struct cldap_request *cldap_search_send(struct cldap_socket *cldap, 
-                                       struct cldap_search *io)
-{
-       struct ldap_message *msg;
-       struct cldap_request *req;
-       struct ldap_SearchRequest *search;
-
-       req = talloc_zero(cldap, struct cldap_request);
-       if (req == NULL) goto failed;
-
-       req->cldap       = cldap;
-       req->state       = CLDAP_REQUEST_SEND;
-       req->timeout     = io->in.timeout;
-       req->num_retries = io->in.retries;
-       req->is_reply    = false;
-       req->asn1        = asn1_init(req);
-       if (!req->asn1) {
-               goto failed;
-       }
-
-       req->dest = socket_address_from_strings(req, cldap->sock->backend_name,
-                                               io->in.dest_address, 
-                                               io->in.dest_port);
-       if (!req->dest) goto failed;
-
-       req->message_id = idr_get_new_random(cldap->idr, req, UINT16_MAX);
-       if (req->message_id == -1) goto failed;
-
-       talloc_set_destructor(req, cldap_request_destructor);
-
-       msg = talloc(req, struct ldap_message);
-       if (msg == NULL) goto failed;
-       msg->messageid       = req->message_id;
-       msg->type            = LDAP_TAG_SearchRequest;
-       msg->controls        = NULL;
-       search = &msg->r.SearchRequest;
-
-       search->basedn         = "";
-       search->scope          = LDAP_SEARCH_SCOPE_BASE;
-       search->deref          = LDAP_DEREFERENCE_NEVER;
-       search->timelimit      = 0;
-       search->sizelimit      = 0;
-       search->attributesonly = false;
-       search->num_attributes = str_list_length(io->in.attributes);
-       search->attributes     = io->in.attributes;
-       search->tree           = ldb_parse_tree(req, io->in.filter);
-       if (search->tree == NULL) {
-               goto failed;
-       }
-
-       if (!ldap_encode(msg, NULL, &req->encoded, req)) {
-               DEBUG(0,("Failed to encode cldap message to %s:%d\n",
-                        req->dest->addr, req->dest->port));
-               goto failed;
-       }
-
-       DLIST_ADD_END(cldap->send_queue, req, struct cldap_request *);
-
-       EVENT_FD_WRITEABLE(cldap->fde);
-
-       return req;
-
-failed:
-       talloc_free(req);
-       return NULL;
-}
-
-
-/*
-  queue a cldap reply for send
-*/
-NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io)
-{
-       struct ldap_message *msg;
-       struct cldap_request *req;
-       DATA_BLOB blob1, blob2;
-       NTSTATUS status = NT_STATUS_NO_MEMORY;
-
-       req = talloc_zero(cldap, struct cldap_request);
-       if (req == NULL) goto failed;
-
-       req->cldap       = cldap;
-       req->state       = CLDAP_REQUEST_SEND;
-       req->is_reply    = true;
-       req->asn1        = asn1_init(req);
-       if (!req->asn1) {
-               goto failed;
-       }
-
-       req->dest        = io->dest;
-       if (talloc_reference(req, io->dest) == NULL) goto failed;
-
-       talloc_set_destructor(req, cldap_request_destructor);
-
-       msg = talloc(req, struct ldap_message);
-       if (msg == NULL) goto failed;
-       msg->messageid       = io->messageid;
-       msg->controls        = NULL;
-       
-       if (io->response) {
-               msg->type = LDAP_TAG_SearchResultEntry;
-               msg->r.SearchResultEntry = *io->response;
-
-               if (!ldap_encode(msg, NULL, &blob1, req)) {
-                       DEBUG(0,("Failed to encode cldap message to %s:%d\n",
-                                req->dest->addr, req->dest->port));
-                       status = NT_STATUS_INVALID_PARAMETER;
-                       goto failed;
-               }
-       } else {
-               blob1 = data_blob(NULL, 0);
-       }
-
-       msg->type = LDAP_TAG_SearchResultDone;
-       msg->r.SearchResultDone = *io->result;
-
-       if (!ldap_encode(msg, NULL, &blob2, req)) {
-               DEBUG(0,("Failed to encode cldap message to %s:%d\n",
-                        req->dest->addr, req->dest->port));
-               status = NT_STATUS_INVALID_PARAMETER;
-               goto failed;
-       }
-
-       req->encoded = data_blob_talloc(req, NULL, blob1.length + blob2.length);
-       if (req->encoded.data == NULL) goto failed;
-
-       memcpy(req->encoded.data, blob1.data, blob1.length);
-       memcpy(req->encoded.data+blob1.length, blob2.data, blob2.length);
-
-       DLIST_ADD_END(cldap->send_queue, req, struct cldap_request *);
-
-       EVENT_FD_WRITEABLE(cldap->fde);
-
-       return NT_STATUS_OK;
-
-failed:
-       talloc_free(req);
-       return status;
-}
-
-/*
-  receive a cldap reply
-*/
-NTSTATUS cldap_search_recv(struct cldap_request *req, 
-                          TALLOC_CTX *mem_ctx, 
-                          struct cldap_search *io)
-{
-       struct ldap_message *ldap_msg;
-       NTSTATUS status;
-
-       if (req == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       while (req->state < CLDAP_REQUEST_DONE) {
-               if (event_loop_once(req->cldap->event_ctx) != 0) {
-                       talloc_free(req);
-                       return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
-               }
-       }
-
-       if (req->state == CLDAP_REQUEST_ERROR) {
-               status = req->status;
-               talloc_free(req);
-               return status;
-       }
-
-       ldap_msg = talloc(mem_ctx, struct ldap_message);
-       NT_STATUS_HAVE_NO_MEMORY(ldap_msg);
-
-       status = ldap_decode(req->asn1, NULL, ldap_msg);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(2,("Failed to decode cldap search reply: %s\n", nt_errstr(status)));
-               talloc_free(req);
-               return status;
-       }
-
-       ZERO_STRUCT(io->out);
-
-       /* the first possible form has a search result in first place */
-       if (ldap_msg->type == LDAP_TAG_SearchResultEntry) {
-               io->out.response = talloc(mem_ctx, struct ldap_SearchResEntry);
-               NT_STATUS_HAVE_NO_MEMORY(io->out.response);
-               *io->out.response = ldap_msg->r.SearchResultEntry;
-
-               /* decode the 2nd part */
-               status = ldap_decode(req->asn1, NULL, ldap_msg);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(2,("Failed to decode cldap search result entry: %s\n", nt_errstr(status)));
-                       talloc_free(req);
-                       return status;
-               }
-       }
-
-       if (ldap_msg->type != LDAP_TAG_SearchResultDone) {
-               talloc_free(req);
-               return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
-       }
-
-       io->out.result = talloc(mem_ctx, struct ldap_Result);
-       NT_STATUS_HAVE_NO_MEMORY(io->out.result);
-       *io->out.result = ldap_msg->r.SearchResultDone;
-
-       talloc_free(req);
-
-       if (io->out.result->resultcode != LDAP_SUCCESS) {
-               return NT_STATUS_LDAP(io->out.result->resultcode);
-       }
-       return NT_STATUS_OK;
-}
-
-
-/*
-  synchronous cldap search
-*/
-NTSTATUS cldap_search(struct cldap_socket *cldap, 
-                     TALLOC_CTX *mem_ctx, 
-                     struct cldap_search *io)
-{
-       struct cldap_request *req = cldap_search_send(cldap, io);
-       return cldap_search_recv(req, mem_ctx, io);
-}
-
-
-
-/*
-  queue a cldap netlogon for send
-*/
-struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, 
-                                         struct cldap_netlogon *io)
-{
-       struct cldap_search search;
-       char *filter;
-       struct cldap_request *req;
-       const char *attr[] = { "NetLogon", NULL };
-       TALLOC_CTX *tmp_ctx = talloc_new(cldap);
-
-       filter = talloc_asprintf(tmp_ctx, "(&(NtVer=%s)", 
-                                ldap_encode_ndr_uint32(tmp_ctx, io->in.version));
-       if (filter == NULL) goto failed;
-       if (io->in.user) {
-               filter = talloc_asprintf_append_buffer(filter, "(User=%s)", io->in.user);
-               if (filter == NULL) goto failed;
-       }
-       if (io->in.host) {
-               filter = talloc_asprintf_append_buffer(filter, "(Host=%s)", io->in.host);
-               if (filter == NULL) goto failed;
-       }
-       if (io->in.realm) {
-               filter = talloc_asprintf_append_buffer(filter, "(DnsDomain=%s)", io->in.realm);
-               if (filter == NULL) goto failed;
-       }
-       if (io->in.acct_control != -1) {
-               filter = talloc_asprintf_append_buffer(filter, "(AAC=%s)", 
-                                               ldap_encode_ndr_uint32(tmp_ctx, io->in.acct_control));
-               if (filter == NULL) goto failed;
-       }
-       if (io->in.domain_sid) {
-               struct dom_sid *sid = dom_sid_parse_talloc(tmp_ctx, io->in.domain_sid);
-               if (sid == NULL) goto failed;
-               filter = talloc_asprintf_append_buffer(filter, "(domainSid=%s)",
-                                               ldap_encode_ndr_dom_sid(tmp_ctx, sid));
-               if (filter == NULL) goto failed;
-       }
-       if (io->in.domain_guid) {
-               struct GUID guid;
-               NTSTATUS status;
-               status = GUID_from_string(io->in.domain_guid, &guid);
-               if (!NT_STATUS_IS_OK(status)) goto failed;
-               filter = talloc_asprintf_append_buffer(filter, "(DomainGuid=%s)",
-                                               ldap_encode_ndr_GUID(tmp_ctx, &guid));
-               if (filter == NULL) goto failed;
-       }
-       filter = talloc_asprintf_append_buffer(filter, ")");
-       if (filter == NULL) goto failed;
-
-       search.in.dest_address = io->in.dest_address;
-       search.in.dest_port    = io->in.dest_port;
-       search.in.filter       = filter;
-       search.in.attributes   = attr;
-       search.in.timeout      = 2;
-       search.in.retries      = 2;
-
-       req = cldap_search_send(cldap, &search);
-
-       talloc_free(tmp_ctx);
-       return req;
-failed:
-       talloc_free(tmp_ctx);
-       return NULL;
-}
-
-
-/*
-  receive a cldap netlogon reply
-*/
-NTSTATUS cldap_netlogon_recv(struct cldap_request *req, 
-                            TALLOC_CTX *mem_ctx, 
-                            struct cldap_netlogon *io)
-{
-       NTSTATUS status;
-       struct cldap_search search;
-       struct cldap_socket *cldap;
-       DATA_BLOB *data;
-
-       cldap = req->cldap;
-
-       status = cldap_search_recv(req, mem_ctx, &search);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       if (search.out.response == NULL) {
-               return NT_STATUS_NOT_FOUND;
-       }
-
-       if (search.out.response->num_attributes != 1 ||
-           strcasecmp(search.out.response->attributes[0].name, "netlogon") != 0 ||
-           search.out.response->attributes[0].num_values != 1 ||
-           search.out.response->attributes[0].values->length < 2) {
-               return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
-       }
-       data = search.out.response->attributes[0].values;
-
-       status = pull_netlogon_samlogon_response(data, mem_ctx, req->cldap->iconv_convenience,
-                                                &io->out.netlogon);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       
-       if (io->in.map_response) {
-               map_netlogon_samlogon_response(&io->out.netlogon);
-       }
-       return NT_STATUS_OK;
-}
-
-/*
-  sync cldap netlogon search
-*/
-NTSTATUS cldap_netlogon(struct cldap_socket *cldap, 
-                       TALLOC_CTX *mem_ctx, struct cldap_netlogon *io)
-{
-       struct cldap_request *req = cldap_netlogon_send(cldap, io);
-       return cldap_netlogon_recv(req, mem_ctx, io);
-}
-
-
-/*
-  send an empty reply (used on any error, so the client doesn't keep waiting
-  or send the bad request again)
-*/
-NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, 
-                          uint32_t message_id,
-                          struct socket_address *src)
-{
-       NTSTATUS status;
-       struct cldap_reply reply;
-       struct ldap_Result result;
-
-       reply.messageid    = message_id;
-       reply.dest         = src;
-       reply.response     = NULL;
-       reply.result       = &result;
-
-       ZERO_STRUCT(result);
-
-       status = cldap_reply_send(cldap, &reply);
-
-       return status;
-}
-
-/*
-  send an error reply (used on any error, so the client doesn't keep waiting
-  or send the bad request again)
-*/
-NTSTATUS cldap_error_reply(struct cldap_socket *cldap, 
-                          uint32_t message_id,
-                          struct socket_address *src,
-                          int resultcode,
-                          const char *errormessage)
-{
-       NTSTATUS status;
-       struct cldap_reply reply;
-       struct ldap_Result result;
-
-       reply.messageid    = message_id;
-       reply.dest         = src;
-       reply.response     = NULL;
-       reply.result       = &result;
-
-       ZERO_STRUCT(result);
-       result.resultcode       = resultcode;
-       result.errormessage     = errormessage;
-
-       status = cldap_reply_send(cldap, &reply);
-
-       return status;
-}
-
-
-/*
-  send a netlogon reply 
-*/
-NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, 
-                             uint32_t message_id,
-                             struct socket_address *src,
-                             uint32_t version,
-                             struct netlogon_samlogon_response *netlogon)
-{
-       NTSTATUS status;
-       struct cldap_reply reply;
-       struct ldap_SearchResEntry response;
-       struct ldap_Result result;
-       TALLOC_CTX *tmp_ctx = talloc_new(cldap);
-       DATA_BLOB blob;
-
-       status = push_netlogon_samlogon_response(&blob, tmp_ctx, cldap->iconv_convenience,
-                                                netlogon);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       reply.messageid    = message_id;
-       reply.dest         = src;
-       reply.response     = &response;
-       reply.result       = &result;
-
-       ZERO_STRUCT(result);
-
-       response.dn = "";
-       response.num_attributes = 1;
-       response.attributes = talloc(tmp_ctx, struct ldb_message_element);
-       NT_STATUS_HAVE_NO_MEMORY(response.attributes);
-       response.attributes->name = "netlogon";
-       response.attributes->num_values = 1;
-       response.attributes->values = &blob;
-
-       status = cldap_reply_send(cldap, &reply);
-
-       talloc_free(tmp_ctx);
-
-       return status;
-}
-
-
diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h
deleted file mode 100644 (file)
index 8951daa..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   a async CLDAP library
-
-   Copyright (C) Andrew Tridgell 2005
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "../lib/util/asn1.h"
-#include "../libcli/netlogon.h"
-
-struct ldap_message;
-
-enum cldap_request_state {CLDAP_REQUEST_SEND, 
-                         CLDAP_REQUEST_WAIT, 
-                         CLDAP_REQUEST_DONE,
-                         CLDAP_REQUEST_ERROR};
-
-/*
-  a cldap request packet
-*/
-struct cldap_request {
-       struct cldap_request *next, *prev;
-
-       struct cldap_socket *cldap;
-
-       enum cldap_request_state state;
-       NTSTATUS status;
-
-       /* where to send the request */
-       struct socket_address *dest;
-
-       /* timeout between retries (seconds) */
-       int timeout;
-       int num_retries;
-
-       bool is_reply;
-
-       /* the ldap message_id */
-       int message_id;
-
-       struct tevent_timer *te;
-
-       /* the encoded request */
-       DATA_BLOB encoded;
-
-       /* the reply data */
-       struct asn1_data *asn1;
-
-       /* information on what to do on completion */
-       struct {
-               void (*fn)(struct cldap_request *);
-               void *private_data;
-       } async;
-};
-
-/*
-  context structure for operations on cldap packets
-*/
-struct cldap_socket {
-       struct socket_context *sock;
-       struct tevent_context *event_ctx;
-       struct smb_iconv_convenience *iconv_convenience;
-
-       /* the fd event */
-       struct tevent_fd *fde;
-
-       /* a queue of outgoing requests */
-       struct cldap_request *send_queue;
-
-       /* mapping from message_id to pending request */
-       struct idr_context *idr;
-
-       /* what to do with incoming request packets */
-       struct {
-               void (*handler)(struct cldap_socket *, struct ldap_message *, 
-                               struct socket_address *);
-               void *private_data;
-       } incoming;
-};
-
-
-/*
- a general cldap search request  
-*/
-struct cldap_search {
-       struct {
-               const char *dest_address;
-               uint16_t dest_port;
-               const char *filter;
-               const char **attributes;
-               int timeout;
-               int retries;
-       } in;
-       struct {
-               struct ldap_SearchResEntry *response;
-               struct ldap_Result         *result;
-       } out;
-};
-
-struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx, 
-                                      struct tevent_context *event_ctx, 
-                                      struct smb_iconv_convenience *iconv_convenience);
-NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap,
-                                   void (*handler)(struct cldap_socket *, struct ldap_message *, 
-                                                   struct socket_address *),
-                                   void *private_data);
-struct cldap_request *cldap_search_send(struct cldap_socket *cldap, 
-                                       struct cldap_search *io);
-NTSTATUS cldap_search_recv(struct cldap_request *req, TALLOC_CTX *mem_ctx, 
-                          struct cldap_search *io);
-NTSTATUS cldap_search(struct cldap_socket *cldap, TALLOC_CTX *mem_ctx, 
-                     struct cldap_search *io);
-
-
-/*
-  a general cldap reply
-*/
-struct cldap_reply {
-       uint32_t messageid;
-       struct socket_address *dest;
-       struct ldap_SearchResEntry *response;
-       struct ldap_Result         *result;
-};
-
-NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io);
-
-NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, 
-                          uint32_t message_id,
-                          struct socket_address *src);
-NTSTATUS cldap_error_reply(struct cldap_socket *cldap, 
-                          uint32_t message_id,
-                          struct socket_address *src,
-                          int resultcode,
-                          const char *errormessage);
-
-/*
-  a netlogon cldap request  
-*/
-struct cldap_netlogon {
-       struct {
-               const char *dest_address;
-               uint16_t dest_port;
-               const char *realm;
-               const char *host;
-               const char *user;
-               const char *domain_guid;
-               const char *domain_sid;
-               int acct_control;
-               uint32_t version;
-               bool map_response;
-       } in;
-       struct {
-               struct netlogon_samlogon_response netlogon;
-       } out;
-};
-
-struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, 
-                                         struct cldap_netlogon *io);
-NTSTATUS cldap_netlogon_recv(struct cldap_request *req, 
-                            TALLOC_CTX *mem_ctx, 
-                            struct cldap_netlogon *io);
-NTSTATUS cldap_netlogon(struct cldap_socket *cldap, 
-                       TALLOC_CTX *mem_ctx, struct cldap_netlogon *io);
-NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, 
-                             uint32_t message_id,
-                             struct socket_address *src,
-                             uint32_t version,
-                             struct netlogon_samlogon_response *netlogon);
index dc3431ab9fc6d1121a48f5a5976b64ed7811b8f0..5b50bdfcbec2a8b793a5b652305bf6f714de25eb 100644 (file)
@@ -96,13 +96,6 @@ LIBCLI_DGRAM_OBJ_FILES = $(addprefix $(libclisrcdir)/dgram/, \
        netlogon.o \
        browse.o)
 
-[SUBSYSTEM::LIBCLI_CLDAP]
-PUBLIC_DEPENDENCIES = LIBCLI_LDAP
-PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB LIBCLI_NETLOGON
-
-LIBCLI_CLDAP_OBJ_FILES = $(libclisrcdir)/cldap/cldap.o
-# PUBLIC_HEADERS += $(libclisrcdir)/cldap/cldap.h
-
 [SUBSYSTEM::LIBCLI_WREPL]
 PUBLIC_DEPENDENCIES = NDR_WINSREPL samba_socket LIBEVENTS LIBPACKET
 
index 11bec42737d183a507f6892151ebb1f625e09851..b522a56239b2caebe5e0f534dabd015dfcf6e7cc 100644 (file)
@@ -108,6 +108,7 @@ static void continue_negprot(struct smb2_request *req)
        transport->negotiate.system_time = state->negprot.out.system_time;
        transport->negotiate.server_start_time = state->negprot.out.server_start_time;
        transport->negotiate.security_mode = state->negprot.out.security_mode;
+       transport->negotiate.dialect_revision = state->negprot.out.dialect_revision;
 
        switch (transport->options.signing) {
        case SMB_SIGNING_OFF:
@@ -161,7 +162,8 @@ static void continue_socket(struct composite_context *creq)
        struct smbcli_socket *sock;
        struct smb2_transport *transport;
        struct smb2_request *req;
-       uint16_t dialects[2];
+       uint16_t dialects[3] = { SMB2_DIALECT_REVISION, SMB21_DIALECT_REVISION,
+                                SMB2_LONGHORN_BETA_DIALECT_REVISION };
 
        c->status = smbcli_sock_connect_recv(creq, state, &sock);
        if (!composite_is_ok(c)) return;
@@ -170,7 +172,7 @@ static void continue_socket(struct composite_context *creq)
        if (composite_nomem(transport, c)) return;
 
        ZERO_STRUCT(state->negprot);
-       state->negprot.in.dialect_count = 2;
+       state->negprot.in.dialect_count = sizeof(dialects) / sizeof(dialects[0]);
        switch (transport->options.signing) {
        case SMB_SIGNING_OFF:
                state->negprot.in.security_mode = 0;
@@ -186,8 +188,6 @@ static void continue_socket(struct composite_context *creq)
        }
        state->negprot.in.capabilities  = 0;
        unix_to_nt_time(&state->negprot.in.start_time, time(NULL));
-       dialects[0] = SMB2_DIALECT_REVISION;
-       dialects[1] = 0;
        state->negprot.in.dialects = dialects;
 
        req = smb2_negprot_send(transport, &state->negprot);
index d1d5b842c337c30f05b3f6e3e21645d4e7076880..7c07c847403837ccdb7a9a0b6d35b084b09be303 100644 (file)
@@ -35,6 +35,7 @@ struct smb2_negotiate {
        NTTIME system_time;
        NTTIME server_start_time;
        uint16_t security_mode;
+       uint16_t dialect_revision;
 };
 
 /* this is the context for the smb2 transport layer */
@@ -226,8 +227,10 @@ struct smb2_request {
 
 #define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */
 
-/* the dialect we support */
+/* the dialects we support */
 #define SMB2_DIALECT_REVISION           0x202
+#define SMB21_DIALECT_REVISION          0x210
+#define SMB2_LONGHORN_BETA_DIALECT_REVISION    0x0 /* early beta dialect */
 
 /* SMB2 negotiate security_mode */
 #define SMB2_NEGOTIATE_SIGNING_ENABLED   0x01
index 0185e66c3905c2a565178453efce84e3a0fd8dc5..930e45b214e270043bc7224be705571f60d1eef9 100644 (file)
@@ -1356,6 +1356,10 @@ const struct unix_error_map unix_nt_errmap[] = {
 #ifdef ENOSYS
        { ENOSYS,       NT_STATUS_INVALID_SYSTEM_SERVICE },
 #endif
+#ifdef ECANCELED
+       { ECANCELED,    NT_STATUS_CANCELLED },
+#endif
+
        { 0, NT_STATUS_UNSUCCESSFUL }
 };
 
index 4e7cdf5c3aa61e07536aaf59cb8c725734dac7a3..7f544b59225a6a00faf82e3e52605739eb1bfeea 100644 (file)
@@ -549,6 +549,7 @@ static const nt_err_code_struct nt_errs[] =
        { "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND },
        { "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED },
        { "NT_STATUS_DS_BUSY", NT_STATUS_DS_BUSY },
+       { "XXX_INVALID_RANGE", NT_STATUS_WIN7_INVALID_RANGE },
        { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES },
        { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED },
        { "STATUS_NOTIFY_CLEANUP", STATUS_NOTIFY_CLEANUP },
index bf046745e6a3aacc48be95fbbc3dc56cb195e782..dbbabd6a6da636f8b9e97bf17d6d101aec5c4f34 100644 (file)
@@ -731,12 +731,12 @@ struct libnet_BecomeDC_state {
        struct libnet_BecomeDC_Callbacks callbacks;
 };
 
-static void becomeDC_recv_cldap(struct cldap_request *req);
+static void becomeDC_recv_cldap(struct tevent_req *req);
 
 static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
 {
        struct composite_context *c = s->creq;
-       struct cldap_request *req;
+       struct tevent_req *req;
 
        s->cldap.io.in.dest_address     = s->source_dsa.address;
        s->cldap.io.in.dest_port        = lp_cldap_port(s->libnet->lp_ctx);
@@ -749,25 +749,27 @@ static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
        s->cldap.io.in.version          = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
        s->cldap.io.in.map_response     = true;
 
-       s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx, 
-                                         lp_iconv_convenience(s->libnet->lp_ctx));
-       if (composite_nomem(s->cldap.sock, c)) return;
+       c->status = cldap_socket_init(s, s->libnet->event_ctx,
+                                     NULL, NULL, &s->cldap.sock);//TODO
+       if (!composite_is_ok(c)) return;
 
-       req = cldap_netlogon_send(s->cldap.sock, &s->cldap.io);
+       req = cldap_netlogon_send(s, s->cldap.sock, &s->cldap.io);
        if (composite_nomem(req, c)) return;
-       req->async.fn           = becomeDC_recv_cldap;
-       req->async.private_data = s;
+       tevent_req_set_callback(req, becomeDC_recv_cldap, s);
 }
 
 static void becomeDC_connect_ldap1(struct libnet_BecomeDC_state *s);
 
-static void becomeDC_recv_cldap(struct cldap_request *req)
+static void becomeDC_recv_cldap(struct tevent_req *req)
 {
-       struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,
+       struct libnet_BecomeDC_state *s = tevent_req_callback_data(req,
                                          struct libnet_BecomeDC_state);
        struct composite_context *c = s->creq;
 
-       c->status = cldap_netlogon_recv(req, s, &s->cldap.io);
+       c->status = cldap_netlogon_recv(req,
+                                       lp_iconv_convenience(s->libnet->lp_ctx),
+                                       s, &s->cldap.io);
+       talloc_free(req);
        if (!composite_is_ok(c)) return;
 
        s->cldap.netlogon = s->cldap.io.out.netlogon.data.nt5_ex;
index 4a32ab92ed58b4a1e6559ecfac473f254e29eac1..8a002b24a4b1e03346f8964743e65cdd8b196fa4 100644 (file)
@@ -56,8 +56,14 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_context *lctx, struct li
        search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
        search.in.map_response = true;
 
-       cldap = cldap_socket_init(tmp_ctx, lctx->event_ctx, lp_iconv_convenience(lctx->lp_ctx));
-       status = cldap_netlogon(cldap, tmp_ctx, &search);
+       /* we want to use non async calls, so we're not passing an event context */
+       status = cldap_socket_init(tmp_ctx, NULL, NULL, NULL, &cldap);//TODO
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(tmp_ctx);
+               r->out.error_string = NULL;
+               return status;
+       }
+       status = cldap_netlogon(cldap, lp_iconv_convenience(lctx->lp_ctx), tmp_ctx, &search);
        if (!NT_STATUS_IS_OK(status)
            || !search.out.netlogon.data.nt5_ex.client_site) {
                /*
index 3f92daab2817aa088b00f424ae7cf717e8aba4f1..e0e5e421151a87b56f8506403b9af47703fdd022 100644 (file)
@@ -250,12 +250,12 @@ struct libnet_UnbecomeDC_state {
        } dest_dsa;
 };
 
-static void unbecomeDC_recv_cldap(struct cldap_request *req);
+static void unbecomeDC_recv_cldap(struct tevent_req *req);
 
 static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s)
 {
        struct composite_context *c = s->creq;
-       struct cldap_request *req;
+       struct tevent_req *req;
 
        s->cldap.io.in.dest_address     = s->source_dsa.address;
        s->cldap.io.in.dest_port        = lp_cldap_port(s->libnet->lp_ctx);
@@ -268,25 +268,27 @@ static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s)
        s->cldap.io.in.version          = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
        s->cldap.io.in.map_response     = true;
 
-       s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx,
-                                         lp_iconv_convenience(s->libnet->lp_ctx));
-       if (composite_nomem(s->cldap.sock, c)) return;
+       c->status = cldap_socket_init(s, s->libnet->event_ctx,
+                                     NULL, NULL, &s->cldap.sock);//TODO
+       if (!composite_is_ok(c)) return;
 
-       req = cldap_netlogon_send(s->cldap.sock, &s->cldap.io);
+       req = cldap_netlogon_send(s, s->cldap.sock, &s->cldap.io);
        if (composite_nomem(req, c)) return;
-       req->async.fn           = unbecomeDC_recv_cldap;
-       req->async.private_data = s;
+       tevent_req_set_callback(req, unbecomeDC_recv_cldap, s);
 }
 
 static void unbecomeDC_connect_ldap(struct libnet_UnbecomeDC_state *s);
 
-static void unbecomeDC_recv_cldap(struct cldap_request *req)
+static void unbecomeDC_recv_cldap(struct tevent_req *req)
 {
-       struct libnet_UnbecomeDC_state *s = talloc_get_type(req->async.private_data,
+       struct libnet_UnbecomeDC_state *s = tevent_req_callback_data(req,
                                            struct libnet_UnbecomeDC_state);
        struct composite_context *c = s->creq;
 
-       c->status = cldap_netlogon_recv(req, s, &s->cldap.io);
+       c->status = cldap_netlogon_recv(req,
+                                       lp_iconv_convenience(s->libnet->lp_ctx),
+                                       s, &s->cldap.io);
+       talloc_free(req);
        if (!composite_is_ok(c)) return;
 
        s->cldap.netlogon = s->cldap.io.out.netlogon.data.nt5_ex;
index ee2018fb694f7dae00683c77eba272f8aac6a6a4..a143604f33c818df66c418d8e82e79dadaa410c1 100644 (file)
@@ -20,7 +20,8 @@ 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/tsocket/config.mk
 mkinclude ../lib/crypto/config.mk
 mkinclude ../lib/torture/config.mk
 mkinclude lib/basic.mk
diff --git a/source4/min_versions.m4 b/source4/min_versions.m4
new file mode 100644 (file)
index 0000000..eaefbd5
--- /dev/null
@@ -0,0 +1,6 @@
+# Minimum and exact required versions for various libraries 
+# if we use the ones installed in the system.
+TDB_MIN_VERSION=1.1.3
+TALLOC_MIN_VERSION=1.3.0
+LDB_REQUIRED_VERSION=0.9.3
+TEVENT_REQUIRED_VERSION=0.9.5
index 459babce0ee5d1d344bf70a7b0089c3678a49d9b..4ebbaaeffc68d0cd7f1a75c8e0e3f818f98ed00e 100644 (file)
@@ -127,44 +127,44 @@ static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC
 {
        struct dcerpc_server_info *server_info = lp_dcerpc_server_info(mem_ctx, server->ntptr->lp_ctx);
        if (strcmp("W3SvcInstalled", r->in.value_name) == 0) {
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
-               r->out.data.value       = 0;
+               *r->out.type            = REG_DWORD;
+               r->out.data->value      = 0;
                return WERR_OK;
        } else if (strcmp("BeepEnabled", r->in.value_name) == 0) {
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
-               r->out.data.value       = 0;
+               *r->out.type            = REG_DWORD;
+               r->out.data->value      = 0;
                return WERR_OK;
        } else if (strcmp("EventLog", r->in.value_name) == 0) {
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
-               r->out.data.value       = 0;
+               *r->out.type            = REG_DWORD;
+               r->out.data->value      = 0;
                return WERR_OK;
        } else if (strcmp("NetPopup", r->in.value_name) == 0) {
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
-               r->out.data.value       = 0;
+               *r->out.type            = REG_DWORD;
+               r->out.data->value      = 0;
                return WERR_OK;
        } else if (strcmp("NetPopupToComputer", r->in.value_name) == 0) {
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
-               r->out.data.value       = 0;
+               *r->out.type            = REG_DWORD;
+               r->out.data->value      = 0;
                return  WERR_OK;
        } else if (strcmp("MajorVersion", r->in.value_name) == 0) {
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
-               r->out.data.value       = 3;
+               *r->out.type            = REG_DWORD;
+               r->out.data->value      = 3;
                return WERR_OK;
        } else if (strcmp("MinorVersion", r->in.value_name) == 0) {
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
-               r->out.data.value       = 0;
+               *r->out.type            = REG_DWORD;
+               r->out.data->value      = 0;
                return WERR_OK;
        } else if (strcmp("DefaultSpoolDirectory", r->in.value_name) == 0) {
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_STRING;
-               r->out.data.string      = "C:\\PRINTERS";
+               *r->out.type            = REG_SZ;
+               r->out.data->string     = "C:\\PRINTERS";
                return  WERR_OK;
        } else if (strcmp("Architecture", r->in.value_name) == 0) {
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_STRING;
-               r->out.data.string      = SPOOLSS_ARCHITECTURE_NT_X86;
+               *r->out.type            = REG_SZ;
+               r->out.data->string     = SPOOLSS_ARCHITECTURE_NT_X86;
                return  WERR_OK;
        } else if (strcmp("DsPresent", r->in.value_name) == 0) {
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
-               r->out.data.value       = 1;
+               *r->out.type            = REG_DWORD;
+               r->out.data->value      = 1;
                return WERR_OK;
        } else if (strcmp("OSVersion", r->in.value_name) == 0) {
                DATA_BLOB blob;
@@ -181,8 +181,8 @@ static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC
                        return WERR_GENERAL_FAILURE;
                }
 
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_BINARY;
-               r->out.data.binary      = blob;
+               *r->out.type            = REG_BINARY;
+               r->out.data->binary     = blob;
                return WERR_OK;
        } else if (strcmp("OSVersionEx", r->in.value_name) == 0) {
                DATA_BLOB blob;
@@ -201,17 +201,17 @@ static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC
                        return WERR_GENERAL_FAILURE;
                }
 
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_BINARY;
-               r->out.data.binary      = blob;
+               *r->out.type            = REG_BINARY;
+               r->out.data->binary     = blob;
                return WERR_OK;
        } else if (strcmp("DNSMachineName", r->in.value_name) == 0) {
                if (!lp_realm(server->ntptr->lp_ctx)) return WERR_INVALID_PARAM;
 
-               *r->out.type            = SPOOLSS_PRINTER_DATA_TYPE_STRING;
-               r->out.data.string      = talloc_asprintf(mem_ctx, "%s.%s",
+               *r->out.type            = REG_SZ;
+               r->out.data->string     = talloc_asprintf(mem_ctx, "%s.%s",
                                                                   lp_netbios_name(server->ntptr->lp_ctx),
                                                                   lp_realm(server->ntptr->lp_ctx));
-               W_ERROR_HAVE_NO_MEMORY(r->out.data.string);
+               W_ERROR_HAVE_NO_MEMORY(r->out.data->string);
                return WERR_OK;
        }
 
@@ -259,7 +259,7 @@ static WERROR sptr_EnumPrintServerForms(struct ntptr_GenericHandle *server, TALL
                return WERR_UNKNOWN_LEVEL;
        }
 
-       r->out.info     = info;
+       *r->out.info    = info;
        *r->out.count   = count;
        return WERR_OK;
 }
@@ -587,7 +587,7 @@ static WERROR sptr_EnumPrinters(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx
                return WERR_UNKNOWN_LEVEL;
        }
 
-       r->out.info     = info;
+       *r->out.info    = info;
        *r->out.count   = count;
        return WERR_OK;
 }
@@ -645,7 +645,7 @@ static WERROR sptr_EnumPorts(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
                return WERR_UNKNOWN_LEVEL;
        }
 
-       r->out.info     = info;
+       *r->out.info    = info;
        *r->out.count   = count;
        return WERR_OK;
 }
@@ -692,7 +692,7 @@ static WERROR sptr_EnumMonitors(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx
                return WERR_UNKNOWN_LEVEL;
        }
 
-       r->out.info     = info;
+       *r->out.info    = info;
        *r->out.count   = count;
        return WERR_OK;
 }
index db22a85492ed8d69683a0dcddb7c0e0b8eb6ecf3..062fa41889f589ac3925ff93e9297348a2c4bef6 100644 (file)
@@ -26,6 +26,8 @@
 #include "auth/auth.h"
 #include "ntvfs/ntvfs.h"
 #include "libcli/wbclient/wbclient.h"
+#define TEVENT_DEPRECATED
+#include <tevent.h>
 
 struct unixuid_private {
        struct wbc_context *wbc_ctx;
@@ -91,6 +93,64 @@ static NTSTATUS set_unix_security(struct unix_sec_ctx *sec)
        return NT_STATUS_OK;
 }
 
+static int unixuid_nesting_level;
+
+/*
+  called at the start and end of a tevent nesting loop. Needs to save/restore
+  unix security context
+ */
+static int unixuid_event_nesting_hook(struct tevent_context *ev,
+                                     void *private_data,
+                                     uint32_t level,
+                                     bool begin,
+                                     void *stack_ptr,
+                                     const char *location)
+{
+       struct unix_sec_ctx *sec_ctx;
+
+       if (unixuid_nesting_level == 0) {
+               /* we don't need to do anything unless we are nested
+                  inside of a call in this module */
+               return 0;
+       }
+
+       if (begin) {
+               sec_ctx = save_unix_security(ev);
+               if (sec_ctx == NULL) {
+                       DEBUG(0,("%s: Failed to save security context\n", location));
+                       return -1;
+               }
+               *(struct unix_sec_ctx **)stack_ptr = sec_ctx;
+               if (seteuid(0) != 0 || setegid(0) != 0) {
+                       DEBUG(0,("%s: Failed to change to root\n", location));
+                       return -1;                      
+               }
+       } else {
+               /* called when we come out of a nesting level */
+               NTSTATUS status;
+
+               sec_ctx = *(struct unix_sec_ctx **)stack_ptr;
+               if (sec_ctx == NULL) {
+                       /* this happens the first time this function
+                          is called, as we install the hook while
+                          inside an event in unixuid_connect() */
+                       return 0;
+               }
+
+               sec_ctx = talloc_get_type_abort(sec_ctx, struct unix_sec_ctx);
+               status = set_unix_security(sec_ctx);
+               talloc_free(sec_ctx);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(0,("%s: Failed to revert security context (%s)\n", 
+                                location, nt_errstr(status)));
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+
 /*
   form a unix_sec_ctx from the current security_token
 */
@@ -219,7 +279,9 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs,
        struct unix_sec_ctx *sec; \
        status = unixuid_setup_security(ntvfs, req, &sec); \
        NT_STATUS_NOT_OK_RETURN(status); \
+       unixuid_nesting_level++; \
        status = ntvfs_next_##op args; \
+       unixuid_nesting_level--; \
        status2 = set_unix_security(sec); \
        talloc_free(sec); \
        if (!NT_STATUS_IS_OK(status2)) smb_panic("Unable to reset security context"); \
@@ -252,6 +314,10 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs,
        priv->last_sec_ctx = NULL;
        priv->last_token = NULL;
 
+       tevent_loop_set_nesting_hook(ntvfs->ctx->event_ctx, 
+                                    unixuid_event_nesting_hook,
+                                    &unixuid_nesting_level);
+
        /* we don't use PASS_THRU_REQ here, as the connect operation runs with 
           root privileges. This allows the backends to setup any database
           links they might need during the connect. */
index 7a06f77d968fb05011b0836f48c38d3b23bdd18f..c8bff59deb66d7eba22cc0f93562efe0cf1ddd9a 100644 (file)
@@ -34,6 +34,7 @@ NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
                        struct provision_settings *settings, 
                        struct provision_result *result)
 {
+       char *configfile;
        PyObject *provision_mod, *provision_dict, *provision_fn, *py_result, *parameters;
        
        DEBUG(0,("Provision for Become-DC test using python\n"));
@@ -76,8 +77,11 @@ NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
                 settings->targetdir));
        parameters = PyDict_New();
 
-       PyDict_SetItemString(parameters, "smbconf", 
-                            PyString_FromString(lp_configfile(lp_ctx)));
+       configfile = lp_configfile(lp_ctx);
+       if (configfile != NULL) {
+               PyDict_SetItemString(parameters, "smbconf", 
+                                    PyString_FromString(configfile));
+       }
 
        PyDict_SetItemString(parameters, "rootdn", 
                                                 PyString_FromString(settings->root_dn_str));
index 92728d505a832f5df63ed6e7ede2e91443617551..3881107cbcfed97a6cbf8e5d006ba23d90aef150 100644 (file)
@@ -107,7 +107,7 @@ char *config_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx,
        char *fname, *config_dir, *p;
        config_dir = talloc_strdup(mem_ctx, lp_configfile(lp_ctx));
        if (config_dir == NULL) {
-               return NULL;
+               config_dir = talloc_strdup(mem_ctx, lp_default_path());
        }
        p = strrchr(config_dir, '/');
        if (p == NULL) {
index f1ef2f0acb95f54bb5feaef2954e0355aca001c5..7d14c0e50288e95579aec66ad5038b00186d060f 100644 (file)
@@ -243,8 +243,8 @@ static WERROR dcesrv_spoolss_EnumPrinters(struct dcesrv_call_state *dce_call, TA
        status = ntptr_EnumPrinters(ntptr, mem_ctx, r);
        W_ERROR_NOT_OK_RETURN(status);
 
-       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinters, ic, r->out.info, r->in.level, *r->out.count);
-       r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinters, ic, *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);
 }
@@ -379,8 +379,8 @@ static WERROR dcesrv_spoolss_EnumPrinterDrivers(struct dcesrv_call_state *dce_ca
        status = ntptr_EnumPrinterDrivers(ntptr, mem_ctx, r);
        W_ERROR_NOT_OK_RETURN(status);
 
-       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinterDrivers, ic, r->out.info, r->in.level, *r->out.count);
-       r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinterDrivers, ic, *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);
 }
@@ -580,9 +580,15 @@ static WERROR dcesrv_spoolss_GetPrinterData(struct dcesrv_call_state *dce_call,
        if (!handle)
                return WERR_BADFID;
 
-       r->out.type = talloc_zero(mem_ctx, enum spoolss_PrinterDataType);
+       r->out.type = talloc_zero(mem_ctx, enum winreg_Type);
        W_ERROR_HAVE_NO_MEMORY(r->out.type);
 
+       r->out.needed = talloc_zero(mem_ctx, uint32_t);
+       W_ERROR_HAVE_NO_MEMORY(r->out.needed);
+
+       r->out.data = talloc_zero(mem_ctx, union spoolss_PrinterData);
+       W_ERROR_HAVE_NO_MEMORY(r->out.data);
+
        switch (handle->type) {
                case NTPTR_HANDLE_SERVER:
                        status = ntptr_GetPrintServerData(handle, mem_ctx, r);
@@ -594,8 +600,8 @@ static WERROR dcesrv_spoolss_GetPrinterData(struct dcesrv_call_state *dce_call,
 
        W_ERROR_NOT_OK_RETURN(status);
 
-       *r->out.needed  = ndr_size_spoolss_PrinterData(&r->out.data, *r->out.type, ic, 0);
-       *r->out.type    = SPOOLSS_BUFFER_OK(*r->out.type, SPOOLSS_PRINTER_DATA_TYPE_NULL);
+       *r->out.needed  = ndr_size_spoolss_PrinterData(r->out.data, *r->out.type, ic, 0);
+       *r->out.type    = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
        r->out.data     = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
 }
@@ -802,8 +808,8 @@ static WERROR dcesrv_spoolss_EnumForms(struct dcesrv_call_state *dce_call, TALLO
                        return WERR_FOOBAR;
        }
 
-       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumForms, ic, r->out.info, r->in.level, *r->out.count);
-       r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumForms, ic, *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);
 }
@@ -825,8 +831,8 @@ static WERROR dcesrv_spoolss_EnumPorts(struct dcesrv_call_state *dce_call, TALLO
        status = ntptr_EnumPorts(ntptr, mem_ctx, r);
        W_ERROR_NOT_OK_RETURN(status);
 
-       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPorts, ic, r->out.info, r->in.level, *r->out.count);
-       r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPorts, ic, *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);
 }
@@ -848,8 +854,8 @@ static WERROR dcesrv_spoolss_EnumMonitors(struct dcesrv_call_state *dce_call, TA
        status = ntptr_EnumMonitors(ntptr, mem_ctx, r);
        W_ERROR_NOT_OK_RETURN(status);
 
-       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumMonitors, ic, r->out.info, r->in.level, *r->out.count);
-       r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
+       *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumMonitors, ic, *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);
 }
@@ -1001,7 +1007,7 @@ static WERROR dcesrv_spoolss_DeletePrintProvidor(struct dcesrv_call_state *dce_c
 static WERROR dcesrv_spoolss_EnumPrintProcDataTypes(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct spoolss_EnumPrintProcDataTypes *r)
 {
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+       return WERR_OK;
 }
 
 
index ae99bceacf08f9017dc7bc11f68b479d25b1e2c4..a3b6ec0d9372f6348b3066bdf6b9ef54c365060f 100755 (executable)
@@ -6,7 +6,7 @@ MANPAGES=$*
 
 for I in $MANPAGES
 do
-       SECTION=`echo $I | grep -o '.$'`
+       SECTION=`echo -n $I | sed "s/.*\(.\)$/\1/"
        DIR="$MANDIR/man$SECTION"
        if [ ! -d "$DIR" ]
        then
index 72b523ed9e88665c0ab599698128ae7d480fd645..9b087c68bb259ab2166e24a75ab754d9a8d19040 100755 (executable)
@@ -8,7 +8,7 @@ MANPAGES=$*
 
 for I in $MANPAGES
 do
-       SECTION=`echo $I | grep -o '.$'`
+       SECTION=`echo -n $I | sed "s/.*\(.\)$/\1/"
        FNAME=$MANDIR/man$SECTION/$I
        if test -f $FNAME; then
          echo Deleting $FNAME
index 0aa84ec6db7fbe07e2488244c4cec0beee005207..d96857661ea5d605415bd496c7215d9d1705fb30 100644 (file)
@@ -1136,7 +1136,8 @@ def provision(setup_dir, message, session_info,
     message("NetBIOS Domain: %s" % names.domain)
     message("DNS Domain:     %s" % names.dnsdomain)
     message("DOMAIN SID:     %s" % str(domainsid))
-    message("Admin password: %s" % adminpass)
+    if samdb_fill == FILL_FULL:
+        message("Admin password: %s" % adminpass)
 
     result = ProvisionResult()
     result.domaindn = domaindn
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 12638e2397b63ccbdbb3082a6ff3d38a5ef7eaa5..62268005c2588e122b12e441885ab92a21ebed55 100644 (file)
@@ -49,7 +49,7 @@ class RpcEchoTests(RpcInterfaceTestCase):
         surrounding_struct.x = 4
         surrounding_struct.surrounding = [1,2,3,4]
         y = self.conn.TestSurrounding(surrounding_struct)
-        self.assertEquals(8 * [0], y.surrounding)
+        self.assertEquals(4 * [0], y.surrounding)
 
     def test_manual_request(self):
         self.assertEquals("\x01\x00\x00\x00", self.conn.request(0, chr(0) * 4))
index 99e530ec3853de79ab6d5bc57f684a5d227060e1..821db064146eb0ff1daf6ac2c36c2be09db71b5a 100755 (executable)
@@ -126,7 +126,7 @@ all_tests="$ncalrpc_tests $ncacn_np_tests $ncacn_ip_tcp_tests $slow_ncalrpc_test
 # Make sure all tests get run
 for t in `$smb4torture --list | grep "^RPC-"`
 do
-       echo $all_tests | grep $t  > /dev/null
+       echo $all_tests | grep "$t"  > /dev/null
        if [ $? -ne 0 ]
        then
                auto_rpc_tests="$auto_rpc_tests $t"
@@ -174,7 +174,7 @@ done
 
 # Tests for the NET API
 
-net=`$smb4torture --list | grep ^NET-`
+net=`$smb4torture --list | grep "^NET-"`
 
 for t in $net; do
     plansmbtorturetest "$t" dc "\$SERVER[$VALIDATE]" -U"\$USERNAME"%"\$PASSWORD" -W "\$DOMAIN" "$*"
@@ -291,7 +291,7 @@ if test x"${PIDL_TESTS_SKIP}" = x"yes"; then
    echo "Skipping pidl tests - PIDL_TESTS_SKIP=yes"
 elif $PERL -e 'eval require Test::More;' > /dev/null 2>&1; then
   for f in $samba4srcdir/../pidl/tests/*.pl; do
-     plantest "pidl.`basename $f .pl`" none $PERL $f "|" $samba4srcdir/../lib/subunit/harness2subunit.pl
+     plantest "pidl.`basename $f .pl`" none $PERL $f "|" $PERL $samba4srcdir/../lib/subunit/harness2subunit.pl
   done
 else 
    echo "Skipping pidl tests - Test::More not installed"
index 56eb7ce0c07a9b4b6747fd6a19df5afcfa66293f..a4dfaea7eb5e3230b8d976b5b59f797852e0f396 100644 (file)
@@ -4096,6 +4096,21 @@ systemOnly: TRUE
 systemFlags: 19
 isMemberOfPartialAttributeSet: TRUE
 
+dn: CN=Parent-GUID,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: Parent-GUID
+ldapDisplayName: parentGUID
+attributeId: 1.2.840.113556.1.4.1224
+attributeSyntax: 2.5.5.10
+omSyntax: 4
+isSingleValued: TRUE
+schemaIdGuid: 2df90d74-009f-11d2-aa4c-00c04fd7d83a
+systemOnly: TRUE
+searchFlags: 0
+systemFlags: 134217748
+schemaFlagsEx: 1
+
 dn: CN=ms-DS-Tasks-For-Az-Task-BL,${SCHEMADN}
 objectClass: top
 objectClass: attributeSchema
index 1ddc628a5c643e6f1de23832fe7808a15a9dc7dd..98669288a8f392bf62bbe3659a2d6ef851417e21 100644 (file)
@@ -28,6 +28,7 @@
 #include "torture/torture.h"
 #include "lib/ldb/include/ldb.h"
 #include "param/param.h"
+#include "../lib/tsocket/tsocket.h"
 
 #define CHECK_STATUS(status, correct) torture_assert_ntstatus_equal(tctx, status, correct, "incorrect status")
 
@@ -45,12 +46,21 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        struct netlogon_samlogon_response n1;
        struct GUID guid;
        int i;
+       struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(tctx->lp_ctx);
+       struct tsocket_address *dest_addr;
+       int ret;
 
-       cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
+       ret = tsocket_address_inet_from_strings(tctx, "ip",
+                                               dest,
+                                               lp_cldap_port(tctx->lp_ctx),
+                                               &dest_addr);
+
+       status = cldap_socket_init(tctx, NULL, NULL, dest_addr, &cldap);
+       CHECK_STATUS(status, NT_STATUS_OK);
 
        ZERO_STRUCT(search);
-       search.in.dest_address = dest;
-       search.in.dest_port = lp_cldap_port(tctx->lp_ctx);
+       search.in.dest_address = NULL;//dest;
+       search.in.dest_port = 0;//lp_cldap_port(tctx->lp_ctx);
        search.in.acct_control = -1;
        search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
        search.in.map_response = true;
@@ -59,7 +69,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
 
        printf("Trying without any attributes\n");
        search = empty_search;
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
 
        n1 = search.out.netlogon;
@@ -72,7 +82,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        for (i=0;i<256;i++) {
                search.in.version = i;
                printf("Trying netlogon level %d\n", i);
-               status = cldap_netlogon(cldap, tctx, &search);
+               status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
                CHECK_STATUS(status, NT_STATUS_OK);
        }
 
@@ -80,19 +90,19 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        for (i=0;i<31;i++) {
                search.in.version = (1<<i);
                printf("Trying netlogon level 0x%x\n", i);
-               status = cldap_netlogon(cldap, tctx, &search);
+               status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
                CHECK_STATUS(status, NT_STATUS_OK);
        }
 
        search.in.version = NETLOGON_NT_VERSION_5|NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_IP;
 
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
 
        printf("Trying with User=NULL\n");
 
        search.in.user = NULL;
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
        CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
@@ -100,20 +110,20 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        printf("Trying with User=Administrator\n");
 
        search.in.user = "Administrator";
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
 
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
        CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
 
        search.in.version = NETLOGON_NT_VERSION_5;
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
 
        printf("Trying with User=NULL\n");
 
        search.in.user = NULL;
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
        CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE);
@@ -121,7 +131,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        printf("Trying with User=Administrator\n");
 
        search.in.user = "Administrator";
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
 
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
@@ -132,7 +142,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        printf("Trying with a GUID\n");
        search.in.realm       = NULL;
        search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid);
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
        CHECK_STRING(GUID_string(tctx, &search.out.netlogon.data.nt5_ex.domain_uuid), search.in.domain_guid);
@@ -141,13 +151,13 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        guid = GUID_random();
        search.in.user        = NULL;
        search.in.domain_guid = GUID_string(tctx, &guid);
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
 
        printf("Trying with a AAC\n");
        search.in.acct_control = ACB_WSTRUST|ACB_SVRTRUST;
        search.in.realm = n1.data.nt5_ex.dns_domain;
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
@@ -155,7 +165,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        printf("Trying with a zero AAC\n");
        search.in.acct_control = 0x0;
        search.in.realm = n1.data.nt5_ex.dns_domain;
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
@@ -164,7 +174,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        search.in.acct_control = 0x0;
        search.in.user = "Administrator";
        search.in.realm = n1.data.nt5_ex.dns_domain;
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "Administrator");
@@ -173,7 +183,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        search.in.user = NULL;
        search.in.acct_control = 0xFF00FF00;
        search.in.realm = n1.data.nt5_ex.dns_domain;
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
@@ -181,14 +191,14 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        printf("Trying with a user only\n");
        search = empty_search;
        search.in.user = "Administrator";
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
 
        printf("Trying with just a bad username\n");
        search.in.user = "___no_such_user___";
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
@@ -197,12 +207,12 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        printf("Trying with just a bad domain\n");
        search = empty_search;
        search.in.realm = "___no_such_domain___";
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
 
        printf("Trying with a incorrect domain and correct guid\n");
        search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid);
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
@@ -210,7 +220,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
 
        printf("Trying with a incorrect domain and incorrect guid\n");
        search.in.domain_guid = GUID_string(tctx, &guid);
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
@@ -219,7 +229,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        printf("Trying with a incorrect GUID and correct domain\n");
        search.in.domain_guid = GUID_string(tctx, &guid);
        search.in.realm = n1.data.nt5_ex.dns_domain;
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
        CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
@@ -239,10 +249,12 @@ static bool test_cldap_netlogon_flags(struct torture_context *tctx,
        struct cldap_netlogon search;
        struct netlogon_samlogon_response n1;
        uint32_t server_type;
+       struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(tctx->lp_ctx);
 
-       cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
+       status = cldap_socket_init(tctx, NULL, NULL, NULL, &cldap);
+       CHECK_STATUS(status, NT_STATUS_OK);
 
-       printf("Printing out netlogon server type flags:\n");
+       printf("Printing out netlogon server type flags: %s\n", dest);
 
        ZERO_STRUCT(search);
        search.in.dest_address = dest;
@@ -251,7 +263,7 @@ static bool test_cldap_netlogon_flags(struct torture_context *tctx,
        search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
        search.in.map_response = true;
 
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
 
        n1 = search.out.netlogon;
@@ -348,10 +360,12 @@ static bool test_cldap_netlogon_flag_ds_dns_forest(struct torture_context *tctx,
        struct cldap_netlogon search;
        uint32_t server_type;
        struct netlogon_samlogon_response n1;
+       struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(tctx->lp_ctx);
 
        bool result = true;
 
-       cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
+       status = cldap_socket_init(tctx, NULL, NULL, NULL, &cldap);
+       CHECK_STATUS(status, NT_STATUS_OK);
 
        printf("Testing netlogon server type flag NBT_SERVER_DS_DNS_FOREST: ");
 
@@ -362,7 +376,7 @@ static bool test_cldap_netlogon_flag_ds_dns_forest(struct torture_context *tctx,
        search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
        search.in.map_response = true;
 
-       status = cldap_netlogon(cldap, tctx, &search);
+       status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
 
        n1 = search.out.netlogon;
@@ -423,7 +437,8 @@ static bool test_cldap_generic(struct torture_context *tctx, const char *dest)
        const char *attrs2[] = { "currentTime", "highestCommittedUSN", "netlogon", NULL };
        const char *attrs3[] = { "netlogon", NULL };
 
-       cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
+       status = cldap_socket_init(tctx, NULL, NULL, NULL, &cldap);
+       CHECK_STATUS(status, NT_STATUS_OK);
 
        ZERO_STRUCT(search);
        search.in.dest_address = dest;
index 1fcfe5a050802e0260d8301dd1a674773ea0f0bc..a422732b039100dc62975f6badd4b3b29eb10abb 100644 (file)
 */
 
 #include "includes.h"
-#include "lib/events/events.h"
+#include <tevent.h>
 #include "libcli/cldap/cldap.h"
 #include "libcli/resolve/resolve.h"
 #include "torture/torture.h"
 #include "param/param.h"
 
 struct bench_state {
+       struct torture_context *tctx;
        int pass_count, fail_count;
 };
 
-static void request_handler(struct cldap_request *req)
+static void request_netlogon_handler(struct tevent_req *req)
 {
        struct cldap_netlogon io;
-       struct bench_state *state = talloc_get_type(req->async.private_data, struct bench_state);
+       struct bench_state *state = tevent_req_callback_data(req, struct bench_state);
        NTSTATUS status;
        TALLOC_CTX *tmp_ctx = talloc_new(NULL);
        io.in.version = 6;
-       status = cldap_netlogon_recv(req, tmp_ctx, &io);
+       status = cldap_netlogon_recv(req,
+                                    lp_iconv_convenience(state->tctx->lp_ctx),
+                                    tmp_ctx, &io);
+       talloc_free(req);
        if (NT_STATUS_IS_OK(status)) {
                state->pass_count++;
        } else {
@@ -47,9 +51,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;
@@ -58,10 +62,13 @@ static bool bench_cldap(struct torture_context *tctx, const char *address)
        int timelimit = torture_setting_int(tctx, "timelimit", 10);
        struct cldap_netlogon search;
        struct bench_state *state;
+       NTSTATUS status;
 
-       cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
+       status = cldap_socket_init(tctx, tctx->ev, NULL, NULL, &cldap);
+       torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
 
        state = talloc_zero(tctx, struct bench_state);
+       state->tctx = tctx;
 
        ZERO_STRUCT(search);
        search.in.dest_address = address;
@@ -69,14 +76,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);
+                       struct tevent_req *req;
+                       req = cldap_netlogon_send(state, cldap, &search);
+
+                       tevent_req_set_callback(req, request_netlogon_handler, state);
 
-                       req->async.private_data = state;
-                       req->async.fn = request_handler;
                        num_sent++;
                        if (num_sent % 50 == 0) {
                                if (torture_setting_bool(tctx, "progress", true)) {
@@ -88,11 +95,11 @@ static bool bench_cldap(struct torture_context *tctx, const char *address)
                        }
                }
 
-               event_loop_once(cldap->event_ctx);
+               tevent_loop_once(tctx->ev);
        }
 
        while (num_sent != (state->pass_count + state->fail_count)) {
-               event_loop_once(cldap->event_ctx);
+               tevent_loop_once(tctx->ev);
        }
 
        printf("%.1f queries per second (%d failures)  \n", 
@@ -103,6 +110,81 @@ static bool bench_cldap(struct torture_context *tctx, const char *address)
        return ret;
 }
 
+static void request_rootdse_handler(struct tevent_req *req)
+{
+       struct cldap_search io;
+       struct bench_state *state = tevent_req_callback_data(req, struct bench_state);
+       NTSTATUS status;
+       TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+       status = cldap_search_recv(req, tmp_ctx, &io);
+       talloc_free(req);
+       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;
+       NTSTATUS status;
+
+       status = cldap_socket_init(tctx, tctx->ev, NULL, NULL, &cldap);
+       torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
+
+       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 tevent_req *req;
+                       req = cldap_search_send(state, cldap, &search);
+
+                       tevent_req_set_callback(req, request_rootdse_handler, state);
+
+                       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 +207,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 3ffc58dbe67d68a0ea577037904e04c7f3987879..c92170cf619037d3e1e385bd52564c58351995fe 100644 (file)
@@ -1429,6 +1429,174 @@ done:
        return ret;
 }
 
+
+/*
+  create a secondary tree connect - used to test for a bug in Samba3 messaging
+  with change notify
+*/
+static struct smbcli_tree *secondary_tcon(struct smbcli_state *cli, 
+                                         struct torture_context *tctx)
+{
+       NTSTATUS status;
+       const char *share, *host;
+       struct smbcli_tree *tree;
+       union smb_tcon tcon;
+
+       share = torture_setting_string(tctx, "share", NULL);
+       host  = torture_setting_string(tctx, "host", NULL);
+       
+       printf("create a second tree context on the same session\n");
+       tree = smbcli_tree_init(cli->session, tctx, false);
+
+       tcon.generic.level = RAW_TCON_TCONX;
+       tcon.tconx.in.flags = 0;
+       tcon.tconx.in.password = data_blob(NULL, 0);
+       tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
+       tcon.tconx.in.device = "A:";    
+       status = smb_raw_tcon(tree, tctx, &tcon);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(tree);
+               printf("Failed to create secondary tree\n");
+               return NULL;
+       }
+
+       tree->tid = tcon.tconx.out.tid;
+       printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid);
+
+       return tree;
+}
+
+
+/* 
+   very simple change notify test
+*/
+static bool test_notify_tcon(struct smbcli_state *cli, struct torture_context *torture)
+{
+       bool ret = true;
+       NTSTATUS status;
+       union smb_notify notify;
+       union smb_open io;
+       int fnum, fnum2;
+       struct smbcli_request *req;
+       extern int torture_numops;
+       struct smbcli_tree *tree = NULL;
+               
+       printf("TESTING SIMPLE CHANGE NOTIFY\n");
+               
+       /*
+         get a handle on the directory
+       */
+       io.generic.level = RAW_OPEN_NTCREATEX;
+       io.ntcreatex.in.root_fid = 0;
+       io.ntcreatex.in.flags = 0;
+       io.ntcreatex.in.access_mask = SEC_FILE_ALL;
+       io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+       io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+       io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
+       io.ntcreatex.in.alloc_size = 0;
+       io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+       io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+       io.ntcreatex.in.security_flags = 0;
+       io.ntcreatex.in.fname = BASEDIR;
+
+       status = smb_raw_open(cli->tree, torture, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       fnum = io.ntcreatex.out.file.fnum;
+
+       status = smb_raw_open(cli->tree, torture, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       fnum2 = io.ntcreatex.out.file.fnum;
+
+       /* ask for a change notify,
+          on file or directory name changes */
+       notify.nttrans.level = RAW_NOTIFY_NTTRANS;
+       notify.nttrans.in.buffer_size = 1000;
+       notify.nttrans.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
+       notify.nttrans.in.file.fnum = fnum;
+       notify.nttrans.in.recursive = true;
+
+       printf("testing notify mkdir\n");
+       req = smb_raw_changenotify_send(cli->tree, &notify);
+       smbcli_mkdir(cli->tree, BASEDIR "\\subdir-name");
+
+       status = smb_raw_changenotify_recv(req, torture, &notify);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       CHECK_VAL(notify.nttrans.out.num_changes, 1);
+       CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_ADDED);
+       CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE);
+
+       printf("testing notify rmdir\n");
+       req = smb_raw_changenotify_send(cli->tree, &notify);
+       smbcli_rmdir(cli->tree, BASEDIR "\\subdir-name");
+
+       status = smb_raw_changenotify_recv(req, torture, &notify);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       CHECK_VAL(notify.nttrans.out.num_changes, 1);
+       CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_REMOVED);
+       CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE);
+
+       printf("SIMPLE CHANGE NOTIFY OK\n");
+
+       printf("TESTING WITH SECONDARY TCON\n");
+       tree = secondary_tcon(cli, torture);
+
+       printf("testing notify mkdir\n");
+       req = smb_raw_changenotify_send(cli->tree, &notify);
+       smbcli_mkdir(cli->tree, BASEDIR "\\subdir-name");
+
+       status = smb_raw_changenotify_recv(req, torture, &notify);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       CHECK_VAL(notify.nttrans.out.num_changes, 1);
+       CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_ADDED);
+       CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE);
+
+       printf("testing notify rmdir\n");
+       req = smb_raw_changenotify_send(cli->tree, &notify);
+       smbcli_rmdir(cli->tree, BASEDIR "\\subdir-name");
+
+       status = smb_raw_changenotify_recv(req, torture, &notify);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       CHECK_VAL(notify.nttrans.out.num_changes, 1);
+       CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_REMOVED);
+       CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE);
+
+       printf("CHANGE NOTIFY WITH TCON OK\n");
+
+       printf("Disconnecting secondary tree\n");
+       status = smb_tree_disconnect(tree);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       talloc_free(tree);
+
+       printf("testing notify mkdir\n");
+       req = smb_raw_changenotify_send(cli->tree, &notify);
+       smbcli_mkdir(cli->tree, BASEDIR "\\subdir-name");
+
+       status = smb_raw_changenotify_recv(req, torture, &notify);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       CHECK_VAL(notify.nttrans.out.num_changes, 1);
+       CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_ADDED);
+       CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE);
+
+       printf("testing notify rmdir\n");
+       req = smb_raw_changenotify_send(cli->tree, &notify);
+       smbcli_rmdir(cli->tree, BASEDIR "\\subdir-name");
+
+       status = smb_raw_changenotify_recv(req, torture, &notify);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       CHECK_VAL(notify.nttrans.out.num_changes, 1);
+       CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_REMOVED);
+       CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE);
+
+       printf("CHANGE NOTIFY WITH TDIS OK\n");
+done:
+       smb_raw_exit(cli->session);
+       return ret;
+}
+
+
 /* 
    basic testing of change notify
 */
@@ -1442,6 +1610,7 @@ bool torture_raw_notify(struct torture_context *torture,
                return false;
        }
 
+       ret &= test_notify_tcon(cli, torture);
        ret &= test_notify_dir(cli, cli2, torture);
        ret &= test_notify_mask(cli, torture);
        ret &= test_notify_recursive(cli, torture);
index 847b32827b8dd2739eb5d285e65f51f2132540ad..1aaf914ceb8af7e7e790eb10717e5e410be81682 100644 (file)
@@ -273,7 +273,12 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx)
        struct cldap_socket *cldap;
        struct cldap_netlogon search;
 
-       cldap = cldap_socket_init(ctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
+       status = cldap_socket_init(ctx, NULL, NULL, NULL, &cldap);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("failed to setup cldap socket - %s\n",
+                       nt_errstr(status));
+               return false;
+       }
 
        r.in.bind_handle                = &ctx->admin.drsuapi.bind_handle;
        r.in.level                      = 1;
@@ -311,7 +316,7 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx)
        search.in.acct_control = -1;
        search.in.version               = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
        search.in.map_response = true;
-       status = cldap_netlogon(cldap, ctx, &search);
+       status = cldap_netlogon(cldap, lp_iconv_convenience(tctx->lp_ctx), ctx, &search);
        if (!NT_STATUS_IS_OK(status)) {
                const char *errstr = nt_errstr(status);
                ctx->site_name = talloc_asprintf(ctx, "%s", "Default-First-Site-Name");
index 7cacba7418190b9628ee175a2b1982cf131b23cd..fe128fea52b0a4a7958d7dd1a4c2aaf5e450909a 100644 (file)
@@ -2619,6 +2619,7 @@ static bool enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe,
        DATA_BLOB blob;
        uint32_t needed;
        uint32_t count;
+       union spoolss_PrinterInfo *info;
 
        r.in.flags = PRINTER_ENUM_LOCAL;
        r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", servername);
@@ -2627,6 +2628,7 @@ static bool enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe,
        r.in.offered = 0;
        r.out.needed = &needed;
        r.out.count = &count;
+       r.out.info = &info;
 
        status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
index 9d8bc4b186e517fe7b8ee03e673d8cd078eb6ae9..2bdcc3fdaf7eff71b9f03019ad421275803ce3de 100644 (file)
@@ -108,6 +108,7 @@ static bool test_EnumPorts(struct torture_context *tctx,
                DATA_BLOB blob;
                uint32_t needed;
                uint32_t count;
+               union spoolss_PortInfo *info;
 
                r.in.servername = "";
                r.in.level = level;
@@ -115,6 +116,7 @@ static bool test_EnumPorts(struct torture_context *tctx,
                r.in.offered = 0;
                r.out.needed = &needed;
                r.out.count = &count;
+               r.out.info = &info;
 
                torture_comment(tctx, "Testing EnumPorts level %u\n", r.in.level);
 
@@ -137,8 +139,10 @@ static bool test_EnumPorts(struct torture_context *tctx,
 
                torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed");
 
+               torture_assert(tctx, info, "EnumPorts returned no info");
+
                ctx->port_count[level]  = count;
-               ctx->ports[level]       = r.out.info;
+               ctx->ports[level]       = info;
        }
 
        for (i=1;i<ARRAY_SIZE(levels);i++) {
@@ -307,6 +311,7 @@ static bool test_EnumPrinterDrivers(struct torture_context *tctx,
                DATA_BLOB blob;
                uint32_t needed;
                uint32_t count;
+               union spoolss_DriverInfo *info;
 
                r.in.server             = "";
                r.in.environment        = SPOOLSS_ARCHITECTURE_NT_X86;
@@ -315,6 +320,7 @@ static bool test_EnumPrinterDrivers(struct torture_context *tctx,
                r.in.offered            = 0;
                r.out.needed            = &needed;
                r.out.count             = &count;
+               r.out.info              = &info;
 
                torture_comment(tctx, "Testing EnumPrinterDrivers level %u\n", r.in.level);
 
@@ -339,7 +345,7 @@ static bool test_EnumPrinterDrivers(struct torture_context *tctx,
                torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDrivers failed");
 
                ctx->driver_count[level]        = count;
-               ctx->drivers[level]             = r.out.info;
+               ctx->drivers[level]             = info;
        }
 
        for (i=1;i<ARRAY_SIZE(levels);i++) {
@@ -426,6 +432,7 @@ static bool test_EnumMonitors(struct torture_context *tctx,
                DATA_BLOB blob;
                uint32_t needed;
                uint32_t count;
+               union spoolss_MonitorInfo *info;
 
                r.in.servername = "";
                r.in.level = level;
@@ -433,6 +440,7 @@ static bool test_EnumMonitors(struct torture_context *tctx,
                r.in.offered = 0;
                r.out.needed = &needed;
                r.out.count = &count;
+               r.out.info = &info;
 
                torture_comment(tctx, "Testing EnumMonitors level %u\n", r.in.level);
 
@@ -456,7 +464,7 @@ static bool test_EnumMonitors(struct torture_context *tctx,
                torture_assert_werr_ok(tctx, r.out.result, "EnumMonitors failed");
 
                ctx->monitor_count[level]       = count;
-               ctx->monitors[level]            = r.out.info;
+               ctx->monitors[level]            = info;
        }
 
        for (i=1;i<ARRAY_SIZE(levels);i++) {
@@ -499,6 +507,7 @@ static bool test_EnumPrintProcessors(struct torture_context *tctx,
                DATA_BLOB blob;
                uint32_t needed;
                uint32_t count;
+               union spoolss_PrintProcessorInfo *info;
 
                r.in.servername = "";
                r.in.environment = "Windows NT x86";
@@ -507,6 +516,7 @@ static bool test_EnumPrintProcessors(struct torture_context *tctx,
                r.in.offered = 0;
                r.out.needed = &needed;
                r.out.count = &count;
+               r.out.info = &info;
 
                torture_comment(tctx, "Testing EnumPrintProcessors level %u\n", r.in.level);
 
@@ -530,7 +540,7 @@ static bool test_EnumPrintProcessors(struct torture_context *tctx,
                torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcessors failed");
 
                ctx->print_processor_count[level]       = count;
-               ctx->print_processors[level]            = r.out.info;
+               ctx->print_processors[level]            = info;
        }
 
        for (i=1;i<ARRAY_SIZE(levels);i++) {
@@ -558,6 +568,57 @@ static bool test_EnumPrintProcessors(struct torture_context *tctx,
        return true;
 }
 
+static bool test_EnumPrintProcDataTypes(struct torture_context *tctx,
+                                       struct dcerpc_pipe *p,
+                                       struct test_spoolss_context *ctx)
+{
+       NTSTATUS status;
+       struct spoolss_EnumPrintProcDataTypes r;
+       uint16_t levels[] = { 1 };
+       int i;
+
+       for (i=0;i<ARRAY_SIZE(levels);i++) {
+               int level = levels[i];
+               DATA_BLOB blob;
+               uint32_t needed;
+               uint32_t count;
+               union spoolss_PrintProcDataTypesInfo *info;
+
+               r.in.servername = "";
+               r.in.print_processor_name = "winprint";
+               r.in.level = level;
+               r.in.buffer = NULL;
+               r.in.offered = 0;
+               r.out.needed = &needed;
+               r.out.count = &count;
+               r.out.info = &info;
+
+               torture_comment(tctx, "Testing EnumPrintProcDataTypes level %u\n", r.in.level);
+
+               status = dcerpc_spoolss_EnumPrintProcDataTypes(p, ctx, &r);
+               torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcDataType failed");
+               if (W_ERROR_IS_OK(r.out.result)) {
+                       /* TODO: do some more checks here */
+                       continue;
+               }
+               torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
+                       "EnumPrintProcDataTypes unexpected return code");
+
+               blob = data_blob_talloc(ctx, NULL, needed);
+               data_blob_clear(&blob);
+               r.in.buffer = &blob;
+               r.in.offered = needed;
+
+               status = dcerpc_spoolss_EnumPrintProcDataTypes(p, ctx, &r);
+               torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcDataTypes failed");
+
+               torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcDataTypes failed");
+       }
+
+       return true;
+}
+
+
 static bool test_EnumPrinters(struct torture_context *tctx, 
                              struct dcerpc_pipe *p,
                              struct test_spoolss_context *ctx)
@@ -572,6 +633,7 @@ static bool test_EnumPrinters(struct torture_context *tctx,
                DATA_BLOB blob;
                uint32_t needed;
                uint32_t count;
+               union spoolss_PrinterInfo *info;
 
                r.in.flags      = PRINTER_ENUM_LOCAL;
                r.in.server     = "";
@@ -580,6 +642,7 @@ static bool test_EnumPrinters(struct torture_context *tctx,
                r.in.offered    = 0;
                r.out.needed    = &needed;
                r.out.count     = &count;
+               r.out.info      = &info;
 
                torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
 
@@ -603,7 +666,7 @@ static bool test_EnumPrinters(struct torture_context *tctx,
                torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
 
                ctx->printer_count[level]       = count;
-               ctx->printers[level]            = r.out.info;
+               ctx->printers[level]            = info;
        }
 
        for (i=1;i<ARRAY_SIZE(levels);i++) {
@@ -793,12 +856,15 @@ static bool test_EnumForms(struct torture_context *tctx,
 
        for (i=0; i<ARRAY_SIZE(levels); i++) {
 
+               union spoolss_FormInfo *info;
+
                r.in.handle = handle;
                r.in.level = levels[i];
                r.in.buffer = NULL;
                r.in.offered = 0;
                r.out.needed = &needed;
                r.out.count = &count;
+               r.out.info = &info;
 
                torture_comment(tctx, "Testing EnumForms level %d\n", levels[i]);
 
@@ -813,7 +879,6 @@ static bool test_EnumForms(struct torture_context *tctx,
                        torture_fail(tctx, "EnumForms on the PrintServer isn't supported by test server (NT4)");
 
                if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
-                       union spoolss_FormInfo *info;
                        int j;
                        DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
                        data_blob_clear(&blob);
@@ -822,9 +887,7 @@ static bool test_EnumForms(struct torture_context *tctx,
 
                        status = dcerpc_spoolss_EnumForms(p, tctx, &r);
 
-                       torture_assert(tctx, r.out.info, "No forms returned");
-
-                       info = r.out.info;
+                       torture_assert(tctx, info, "No forms returned");
 
                        for (j = 0; j < count; j++) {
                                if (!print_server)
@@ -928,6 +991,7 @@ static bool test_EnumPorts_old(struct torture_context *tctx,
        struct spoolss_EnumPorts r;
        uint32_t needed;
        uint32_t count;
+       union spoolss_PortInfo *info;
 
        r.in.servername = talloc_asprintf(tctx, "\\\\%s", 
                                          dcerpc_server_name(p));
@@ -936,6 +1000,7 @@ static bool test_EnumPorts_old(struct torture_context *tctx,
        r.in.offered = 0;
        r.out.needed = &needed;
        r.out.count = &count;
+       r.out.info = &info;
 
        torture_comment(tctx, "Testing EnumPorts\n");
 
@@ -952,7 +1017,7 @@ static bool test_EnumPorts_old(struct torture_context *tctx,
                status = dcerpc_spoolss_EnumPorts(p, tctx, &r);
                torture_assert_ntstatus_ok(tctx, status, "EnumPorts failed");
 
-               torture_assert(tctx, r.out.info, "No ports returned");
+               torture_assert(tctx, info, "No ports returned");
        }
 
        return true;
@@ -1080,6 +1145,7 @@ static bool test_EnumJobs(struct torture_context *tctx,
        struct spoolss_EnumJobs r;
        uint32_t needed;
        uint32_t count;
+       union spoolss_JobInfo *info;
 
        r.in.handle = handle;
        r.in.firstjob = 0;
@@ -1089,6 +1155,7 @@ static bool test_EnumJobs(struct torture_context *tctx,
        r.in.offered = 0;
        r.out.needed = &needed;
        r.out.count = &count;
+       r.out.info = &info;
 
        torture_comment(tctx, "Testing EnumJobs\n");
 
@@ -1097,7 +1164,6 @@ static bool test_EnumJobs(struct torture_context *tctx,
        torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
 
        if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
-               union spoolss_JobInfo *info;
                int j;
                DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
                data_blob_clear(&blob);
@@ -1106,9 +1172,7 @@ static bool test_EnumJobs(struct torture_context *tctx,
 
                status = dcerpc_spoolss_EnumJobs(p, tctx, &r);
 
-               torture_assert(tctx, r.out.info, "No jobs returned");
-
-               info = r.out.info;
+               torture_assert(tctx, info, "No jobs returned");
 
                for (j = 0; j < count; j++) {
 
@@ -1273,13 +1337,15 @@ static bool test_GetPrinterData(struct torture_context *tctx,
        NTSTATUS status;
        struct spoolss_GetPrinterData r;
        uint32_t needed;
-       enum spoolss_PrinterDataType type;
+       enum winreg_Type type;
+       union spoolss_PrinterData data;
 
        r.in.handle = handle;
        r.in.value_name = value_name;
        r.in.offered = 0;
        r.out.needed = &needed;
        r.out.type = &type;
+       r.out.data = &data;
 
        torture_comment(tctx, "Testing GetPrinterData\n");
 
@@ -1306,7 +1372,7 @@ static bool test_GetPrinterDataEx(struct torture_context *tctx,
 {
        NTSTATUS status;
        struct spoolss_GetPrinterDataEx r;
-       uint32_t type;
+       enum winreg_Type type;
        uint32_t needed;
 
        r.in.handle = handle;
@@ -1353,16 +1419,15 @@ static bool test_EnumPrinterData(struct torture_context *tctx, struct dcerpc_pip
        do {
                uint32_t value_size = 0;
                uint32_t data_size = 0;
-               uint32_t printerdata_type = 0;
-               DATA_BLOB data = data_blob(NULL,0);
+               enum winreg_Type type = 0;
 
                r.in.value_offered = value_size;
                r.out.value_needed = &value_size;
                r.in.data_offered = data_size;
                r.out.data_needed = &data_size;
 
-               r.out.printerdata_type = &printerdata_type;
-               r.out.buffer = &data;
+               r.out.type = &type;
+               r.out.data = talloc_zero_array(tctx, uint8_t, 0);
 
                torture_comment(tctx, "Testing EnumPrinterData\n");
 
@@ -1371,7 +1436,9 @@ static bool test_EnumPrinterData(struct torture_context *tctx, struct dcerpc_pip
                torture_assert_ntstatus_ok(tctx, status, "EnumPrinterData failed");
 
                r.in.value_offered = value_size;
+               r.out.value_name = talloc_zero_array(tctx, const char, value_size);
                r.in.data_offered = data_size;
+               r.out.data = talloc_zero_array(tctx, uint8_t, data_size);
 
                status = dcerpc_spoolss_EnumPrinterData(p, tctx, &r);
 
@@ -1396,6 +1463,7 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx,
 {
        NTSTATUS status;
        struct spoolss_EnumPrinterDataEx r;
+       struct spoolss_PrinterEnumValues *info;
        uint32_t needed;
        uint32_t count;
 
@@ -1404,6 +1472,7 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx,
        r.in.offered = 0;
        r.out.needed = &needed;
        r.out.count = &count;
+       r.out.info = &info;
 
        torture_comment(tctx, "Testing EnumPrinterDataEx\n");
 
@@ -1411,7 +1480,6 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx,
        torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed");
 
        r.in.offered = needed;
-       r.out.buffer = talloc_array(tctx, uint8_t, needed);
 
        status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &r);
 
@@ -1451,7 +1519,7 @@ static bool test_SetPrinterData(struct torture_context *tctx,
        
        r.in.handle = handle;
        r.in.value_name = value_name;
-       r.in.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
+       r.in.type = REG_SZ;
        r.in.data.string = "dog";
 
        torture_comment(tctx, "Testing SetPrinterData\n");
@@ -1722,6 +1790,7 @@ static bool test_EnumPrinters_old(struct torture_context *tctx, struct dcerpc_pi
                r.in.offered    = 0;
                r.out.needed    = &needed;
                r.out.count     = &count;
+               r.out.info      = &info;
 
                torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
 
@@ -1740,13 +1809,11 @@ static bool test_EnumPrinters_old(struct torture_context *tctx, struct dcerpc_pi
 
                torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
 
-               if (!r.out.info) {
+               if (!info) {
                        torture_comment(tctx, "No printers returned\n");
                        return true;
                }
 
-               info = r.out.info;
-
                for (j=0;j<count;j++) {
                        if (r.in.level == 1) {
                                /* the names appear to be comma-separated name lists? */
@@ -1829,6 +1896,7 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
 
                uint32_t needed;
                uint32_t count;
+               union spoolss_DriverInfo *info;
 
                r.in.server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
                r.in.environment = "Windows NT x86";
@@ -1837,6 +1905,7 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
                r.in.offered = 0;
                r.out.needed = &needed;
                r.out.count = &count;
+               r.out.info = &info;
 
                torture_comment(tctx, "Testing EnumPrinterDrivers level %u\n", r.in.level);
 
@@ -1856,7 +1925,7 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
 
                torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDrivers failed");
 
-               if (!r.out.info) {
+               if (!info) {
                        torture_comment(tctx, "No printer drivers returned\n");
                        break;
                }
@@ -1937,6 +2006,7 @@ bool torture_rpc_spoolss(struct torture_context *torture)
        ret &= test_EnumPrinterDrivers(torture, p, ctx);
        ret &= test_EnumMonitors(torture, p, ctx);
        ret &= test_EnumPrintProcessors(torture, p, ctx);
+       ret &= test_EnumPrintProcDataTypes(torture, p, ctx);
        ret &= test_EnumPrinters(torture, p, ctx);
        ret &= test_OpenPrinter_badname(torture, p, "__INVALID_PRINTER__");
        ret &= test_OpenPrinter_badname(torture, p, "\\\\__INVALID_HOST__");
index 048f255ffc89ff4166684013aba80164a819f989..b7f2d3c4101b64b9262b947f10811082d8f586f0 100644 (file)
@@ -252,15 +252,15 @@ static bool test_RFFPCNEx(struct torture_context *tctx,
        t1.flags = 0;
        t1.count = 2;
        t1.types = talloc_zero_array(tctx, struct spoolss_NotifyOptionType, 2);
-       t1.types[0].type = SPOOLSS_NOTIFY_PRINTER;
+       t1.types[0].type = PRINTER_NOTIFY_TYPE;
        t1.types[0].count = 1;
-       t1.types[0].fields = talloc_array(t1.types, enum spoolss_Field, 1);
-       t1.types[0].fields[0] = SPOOLSS_FIELD_SERVER_NAME;
+       t1.types[0].fields = talloc_array(t1.types, union spoolss_Field, 1);
+       t1.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
 
-       t1.types[1].type = SPOOLSS_NOTIFY_JOB;
+       t1.types[1].type = JOB_NOTIFY_TYPE;
        t1.types[1].count = 1;
-       t1.types[1].fields = talloc_array(t1.types, enum spoolss_Field, 1);
-       t1.types[1].fields[0] = SPOOLSS_FIELD_PRINTER_NAME;
+       t1.types[1].fields = talloc_array(t1.types, union spoolss_Field, 1);
+       t1.types[1].fields[0].field = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
 
        r.in.notify_options = &t1;
        r.in.handle = &handle;
index 08fadafe2c86e32374ad1d52823ff8f88c6c2bdc..c50cbfbaee3cb7ab9591978adc40a5ee9154771d 100644 (file)
@@ -33,7 +33,7 @@ struct test_spoolss_win_context {
        union spoolss_PrinterInfo *current_info;
 
        /* EnumPrinterKeys */
-       char *printer_keys;
+       const char **printer_keys;
 };
 
 /* This is a convenience function for all OpenPrinterEx calls */
@@ -156,7 +156,8 @@ static bool test_GetPrinterData(struct torture_context *tctx,
        NTSTATUS status;
        struct spoolss_GetPrinterData gpd;
        uint32_t needed;
-       enum spoolss_PrinterDataType type;
+       enum winreg_Type type;
+       union spoolss_PrinterData data;
 
        torture_comment(tctx, "Testing GetPrinterData(%s).\n", value_name);
        gpd.in.handle = handle;
@@ -164,6 +165,7 @@ static bool test_GetPrinterData(struct torture_context *tctx,
        gpd.in.offered = 4;
        gpd.out.needed = &needed;
        gpd.out.type = &type;
+       gpd.out.data = &data;
 
        status = dcerpc_spoolss_GetPrinterData(p, tctx, &gpd);
        torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed.");
@@ -171,7 +173,7 @@ static bool test_GetPrinterData(struct torture_context *tctx,
                        "GetPrinterData did not return expected error value.");
 
        if (W_ERROR_IS_OK(expected_werr)) {
-               torture_assert_int_equal(tctx, gpd.out.data.value,
+               torture_assert_int_equal(tctx, data.value,
                        expected_value,
                        "GetPrinterData did not return expected value.");
        }
@@ -188,6 +190,7 @@ static bool test_EnumPrinters(struct torture_context *tctx,
        DATA_BLOB blob = data_blob_talloc_zero(ctx, initial_blob_size);
        uint32_t needed;
        uint32_t count;
+       union spoolss_PrinterInfo *info;
 
        ep.in.flags = PRINTER_ENUM_NAME;
        ep.in.server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
@@ -196,6 +199,7 @@ static bool test_EnumPrinters(struct torture_context *tctx,
        ep.in.offered = initial_blob_size;
        ep.out.needed = &needed;
        ep.out.count = &count;
+       ep.out.info = &info;
 
        status = dcerpc_spoolss_EnumPrinters(p, ctx, &ep);
        torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed.");
@@ -211,7 +215,7 @@ static bool test_EnumPrinters(struct torture_context *tctx,
        torture_assert_werr_ok(tctx, ep.out.result, "EnumPrinters failed.");
 
        ctx->printer_count = count;
-       ctx->printer_info = ep.out.info;
+       ctx->printer_info = info;
 
        torture_comment(tctx, "Found %d printer(s).\n", ctx->printer_count);
 
@@ -264,6 +268,7 @@ static bool test_EnumJobs(struct torture_context *tctx,
        DATA_BLOB blob = data_blob_talloc_zero(tctx, 1024);
        uint32_t needed;
        uint32_t count;
+       union spoolss_JobInfo *info;
 
        torture_comment(tctx, "Test EnumJobs\n");
 
@@ -273,6 +278,7 @@ static bool test_EnumJobs(struct torture_context *tctx,
        ej.in.offered = 1024;
        ej.out.needed = &needed;
        ej.out.count = &count;
+       ej.out.info = &info;
 
        status = dcerpc_spoolss_EnumJobs(p, tctx, &ej);
        torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
@@ -323,6 +329,7 @@ static bool test_EnumForms(struct torture_context *tctx,
        DATA_BLOB blob = data_blob_talloc_zero(tctx, initial_blob_size);
        uint32_t needed;
        uint32_t count;
+       union spoolss_FormInfo *info;
 
        torture_comment(tctx, "Testing EnumForms\n");
 
@@ -332,6 +339,7 @@ static bool test_EnumForms(struct torture_context *tctx,
        ef.in.offered = initial_blob_size;
        ef.out.needed = &needed;
        ef.out.count = &count;
+       ef.out.info = &info;
 
        status = dcerpc_spoolss_EnumForms(p, tctx, &ef);
        torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
@@ -358,22 +366,22 @@ static bool test_EnumPrinterKey(struct torture_context *tctx,
        NTSTATUS status;
        struct spoolss_EnumPrinterKey epk;
        uint32_t needed = 0;
+       const char **key_buffer = NULL;
 
        torture_comment(tctx, "Testing EnumPrinterKey(%s)\n", key);
 
        epk.in.handle = handle;
        epk.in.key_name = talloc_strdup(tctx, key);
-       epk.in.key_buffer_size = 0;
+       epk.in.offered = 0;
        epk.out.needed = &needed;
-       epk.out.key_buffer = talloc_array(tctx, uint16_t, 0);
+       epk.out.key_buffer = &key_buffer;
 
        status = dcerpc_spoolss_EnumPrinterKey(p, tctx, &epk);
        torture_assert_ntstatus_ok(tctx, status, "EnumPrinterKey failed");
 
 
        if (W_ERROR_EQUAL(epk.out.result, WERR_MORE_DATA)) {
-               epk.in.key_buffer_size = needed;
-               epk.out.key_buffer = talloc_array(tctx, uint16_t, needed/2);
+               epk.in.offered = needed;
                status = dcerpc_spoolss_EnumPrinterKey(p, tctx, &epk);
                torture_assert_ntstatus_ok(tctx, status,
                                "EnumPrinterKey failed");
@@ -381,9 +389,7 @@ static bool test_EnumPrinterKey(struct torture_context *tctx,
 
        torture_assert_werr_ok(tctx, epk.out.result, "EnumPrinterKey failed");
 
-       convert_string_talloc_convenience(ctx, lp_iconv_convenience(tctx->lp_ctx), CH_UTF16,
-                       CH_UNIX, epk.out.key_buffer, *epk.out.needed,
-                       (void**)&ctx->printer_keys, NULL, false);
+       ctx->printer_keys = key_buffer;
 
        return true;
 }
@@ -397,6 +403,7 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx,
 {
        NTSTATUS status;
        struct spoolss_EnumPrinterDataEx epde;
+       struct spoolss_PrinterEnumValues *info;
        uint32_t needed;
        uint32_t count;
 
@@ -407,13 +414,12 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx,
        epde.in.offered = 0;
        epde.out.needed = &needed;
        epde.out.count = &count;
-       epde.out.buffer = talloc_array(tctx, uint8_t, 0);
+       epde.out.info = &info;
 
        status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &epde);
        torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed.");
        if (W_ERROR_EQUAL(epde.out.result, WERR_MORE_DATA)) {
                epde.in.offered = needed;
-               epde.out.buffer = talloc_array(tctx, uint8_t, needed);
                status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &epde);
                torture_assert_ntstatus_ok(tctx, status,
                                "EnumPrinterDataEx failed.");
@@ -450,7 +456,7 @@ static bool test_WinXP(struct torture_context *tctx, struct dcerpc_pipe *p)
         * code, the unused_handle structures are used for that. */
        struct policy_handle unused_handle1, unused_handle2;
        char *server_name;
-       char *key_pointer;
+       uint32_t i;
 
        ntvfs_init(tctx->lp_ctx);
 
@@ -525,24 +531,15 @@ static bool test_WinXP(struct torture_context *tctx, struct dcerpc_pipe *p)
        ret &= test_EnumForms(tctx, p, &handle03, 0);
 
        ret &= test_EnumPrinterKey(tctx, p, &handle03, "", ctx);
-       key_pointer = ctx->printer_keys;
-       while(*key_pointer != '\0') {
-               char *end_pointer;
-               char *key_name;
-
-               for(end_pointer = key_pointer; *end_pointer != '\0';
-                               ++end_pointer) {
-                       /* Do nothing, just move the pointer */
-               }
-               key_name = talloc_strndup(tctx, key_pointer,
-                               end_pointer - key_pointer);
-
-               ret &= test_EnumPrinterKey(tctx, p, &handle03, key_name,
-                               tmp_ctx);
-               ret &= test_EnumPrinterDataEx(tctx, p, &handle03, key_name, 0,
-                               WERR_OK);
-
-               key_pointer = ++end_pointer;
+
+       for (i=0; ctx->printer_keys[i] != NULL; i++) {
+
+               ret &= test_EnumPrinterKey(tctx, p, &handle03,
+                                          ctx->printer_keys[i],
+                                          tmp_ctx);
+               ret &= test_EnumPrinterDataEx(tctx, p, &handle03,
+                                             ctx->printer_keys[i], 0,
+                                             WERR_OK);
        }
 
        ret &= test_EnumPrinterDataEx(tctx, p, &handle03, "", 0,
index 6d898a128cf50b24464d93f80c015aa069fede0f..febfbe03ec4190505cfe6c10cb597927a7ecb584 100644 (file)
@@ -43,6 +43,8 @@
                return false;                                   \
        }} while (0)
 
+#define TARGET_IS_WIN7(_tctx) (torture_setting_bool(_tctx, "win7", false))
+
 /*
   test some interesting combinations found by gentest
  */
@@ -160,7 +162,11 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
                }
        }
 
-       CHECK_EQUAL(access_mask, 0x0df0fe00);
+       if (TARGET_IS_WIN7(torture)) {
+               CHECK_EQUAL(access_mask, 0x0de0fe00);
+       } else {
+               CHECK_EQUAL(access_mask, 0x0df0fe00);
+       }
 
        io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
        io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
index d820983022b35cf01e8f931cf533992ee524abde..5f0293c6810ecb60cfd973943a55a1c8c843dff2 100644 (file)
@@ -28,6 +28,9 @@
 
 #include "librpc/gen_ndr/ndr_security.h"
 
+#define TARGET_IS_WINDOWS(_tctx) (torture_setting_bool(_tctx, "win7", false) || torture_setting_bool(torture, "windows", false))
+#define TARGET_IS_WIN7(_tctx) (torture_setting_bool(_tctx, "win7", false))
+
 #define CHECK_STATUS(status, correct) do { \
        if (!NT_STATUS_EQUAL(status, correct)) { \
                printf("(%s) Incorrect status %s - should be %s\n", \
@@ -97,16 +100,26 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
        el[0].reserved          = 0x00000000;
        el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
        status = smb2_lock(tree, &lck);
-       CHECK_STATUS(status, NT_STATUS_OK);
+       if (TARGET_IS_WIN7(torture)) {
+               CHECK_STATUS(status, NT_STATUS_WIN7_INVALID_RANGE);
+       } else {
+               CHECK_STATUS(status, NT_STATUS_OK);
+       }
        CHECK_VALUE(lck.out.reserved, 0);
 
        lck.in.reserved         = 0x123ab2;
        status = smb2_lock(tree, &lck);
-       CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
+       if (TARGET_IS_WIN7(torture)) {
+               CHECK_STATUS(status, NT_STATUS_WIN7_INVALID_RANGE);
+       } else {
+               CHECK_STATUS(status, NT_STATUS_OK);
+       }
 
        lck.in.reserved         = 0x123ab3;
        status = smb2_lock(tree, &lck);
-       if (torture_setting_bool(torture, "windows", false)) {
+       if (TARGET_IS_WIN7(torture)) {
+               CHECK_STATUS(status, NT_STATUS_WIN7_INVALID_RANGE);
+       } else if (TARGET_IS_WINDOWS(torture)) {
                CHECK_STATUS(status, NT_STATUS_OK);
        } else {
                CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
@@ -115,11 +128,17 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
 
        lck.in.reserved         = 0x123ab4;
        status = smb2_lock(tree, &lck);
-       CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
+       if (TARGET_IS_WIN7(torture)) {
+               CHECK_STATUS(status, NT_STATUS_WIN7_INVALID_RANGE);
+       } else {
+               CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
+       }
 
        lck.in.reserved         = 0x123ab5;
        status = smb2_lock(tree, &lck);
-       if (torture_setting_bool(torture, "windows", false)) {
+       if (TARGET_IS_WIN7(torture)) {
+               CHECK_STATUS(status, NT_STATUS_WIN7_INVALID_RANGE);
+       } else if (TARGET_IS_WINDOWS(torture)) {
                CHECK_STATUS(status, NT_STATUS_OK);
        } else {
                CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
@@ -141,7 +160,7 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
 
        status = smb2_lock(tree, &lck);
-       if (torture_setting_bool(torture, "windows", false)) {
+       if (TARGET_IS_WINDOWS(torture)) {
                CHECK_STATUS(status, NT_STATUS_OK);
        } else {
                CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
@@ -152,7 +171,7 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
 
        status = smb2_lock(tree, &lck);
-       if (torture_setting_bool(torture, "windows", false)) {
+       if (TARGET_IS_WINDOWS(torture)) {
                CHECK_STATUS(status, NT_STATUS_OK);
        } else {
                CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
@@ -481,7 +500,6 @@ static bool test_lock_rw_exclusiv(struct torture_context *torture, struct smb2_t
        return test_lock_read_write(torture, tree, &s);
 }
 
-
 static bool test_lock_auto_unlock(struct torture_context *torture, struct smb2_tree *tree)
 {
        bool ret = true;
@@ -513,13 +531,14 @@ static bool test_lock_auto_unlock(struct torture_context *torture, struct smb2_t
        CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
 
        status = smb2_lock(tree, &lck);
-       if (torture_setting_bool(torture, "windows", false)) {
+       if (TARGET_IS_WINDOWS(torture)) {
                CHECK_STATUS(status, NT_STATUS_OK);
        } else {
                CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
        }
 
-       
+       status = smb2_lock(tree, &lck);
+       CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
 
 done:
        return ret;
index e301b5485ada182e3ba1ce85203e81625e4a4004..ba4f01f4a85d3044fc80b702c1b61b23d5479d29 100755 (executable)
@@ -33,7 +33,7 @@ check() {
 }
 
 
-ldbsearch="$BUILDDIR/bin/ldbsearch$EXEEXT"
+ldbsearch="$VALGRIND $BUILDDIR/bin/ldbsearch$EXEEXT"
 
 check "RootDSE" $ldbsearch $CONFIGURATION $options --basedn='' -H $p://$SERVER -s base DUMMY=x dnsHostName highestCommittedUSN || failed=`expr $failed + 1`