Merge branch 'master' of ssh://git.samba.org/data/git/samba into displaysec
authorJelmer Vernooij <jelmer@samba.org>
Fri, 20 Mar 2009 15:40:09 +0000 (16:40 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Fri, 20 Mar 2009 15:40:09 +0000 (16:40 +0100)
191 files changed:
.gitignore
docs-xml/manpages-3/idmap_hash.8.xml
lib/async_req/async_req.c
lib/async_req/async_req.h
lib/async_req/async_sock.c
lib/replace/libreplace_network.m4
lib/talloc/configure.ac
lib/talloc/talloc.h
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/config.mk
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]
librpc/gen_ndr/cli_spoolss.c
librpc/gen_ndr/cli_spoolss.h
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_spoolss_buf.c
librpc/ndr/ndr_spoolss_buf.h
nsswitch/pam_winbind.h
selftest/target/Samba3.pm
source3/Makefile.in
source3/client/client.c
source3/configure.in
source3/include/includes.h
source3/include/libsmb_internal.h
source3/include/nt_printing.h
source3/include/ntdomain.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_macros.h
source3/include/wbc_async.h
source3/lib/events.c
source3/lib/netapi/cm.c
source3/lib/netapi/group.c
source3/lib/netapi/user.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/kerberos.c
source3/libads/krb5_errs.c
source3/libads/ldap_printer.c
source3/libnet/libnet_join.c
source3/libsmb/async_smb.c
source3/libsmb/cliconnect.c
source3/libsmb/clidfs.c
source3/libsmb/clikrb5.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/trusts_util.c
source3/m4/aclocal.m4
source3/modules/onefs_system.c
source3/passdb/pdb_tdb.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_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_hnd.c
source3/rpc_server/srv_samr_nt.c
source3/rpc_server/srv_samr_util.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/script/installmo.sh
source3/script/mkversion.sh
source3/smbd/ipc.c
source3/smbd/pipes.c
source3/smbd/reply.c
source3/smbd/server.c
source3/torture/torture.c
source3/utils/net_ads.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_util.c
source3/utils/netlookup.c
source3/utils/smbcacls.c
source3/utils/smbcontrol.c
source3/utils/smbcquotas.c
source3/utils/smbtree.c
source3/winbindd/winbindd.c
source3/winbindd/winbindd.h
source3/winbindd/winbindd_ads.c
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_pam.c
source3/winbindd/winbindd_proto.h
source3/winbindd/winbindd_rpc.c
source3/winbindd/winbindd_util.c
source4/aclocal.m4
source4/build/m4/public.m4
source4/cldap_server/cldap_server.c
source4/cldap_server/netlogon.c
source4/cldap_server/rootdse.c
source4/dsdb/samdb/ldb_modules/objectclass.c
source4/dsdb/samdb/ldb_modules/password_hash.c
source4/headermap.txt
source4/lib/cmdline/popt_common.h
source4/lib/ldb/modules/paged_searches.c
source4/lib/ldb/pyldb.c
source4/lib/ldb/tests/python/ldap.py
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/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
source4/ntptr/simple_ldb/ntptr_simple_ldb.c
source4/ntvfs/unixuid/vfs_unixuid.c
source4/rpc_server/spoolss/dcesrv_spoolss.c
source4/script/uninstallman.sh
source4/scripting/bin/fullschema [new file with mode: 0644]
source4/scripting/bin/minschema
source4/scripting/python/samba/__init__.py
source4/setup/schema.ldif
source4/torture/ldap/cldap.c
source4/torture/ldap/cldapbench.c
source4/torture/rpc/dssync.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

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>
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 be24bae6dfd5b27ea9dc8c2b3aca7e39530b3192..77df4060449f939fedbc709946cbfb491c89d4d1 100644 (file)
@@ -389,7 +389,6 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 {
        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) {
@@ -405,22 +404,7 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
                goto fail;
        }
 
-       /*
-        * This if () should go away once our callers are converted to always
-        * pass in a queue.
-        */
-
-       if (queue != NULL) {
-               if (!tevent_queue_add(queue, ev, result, writev_trigger,
-                                     NULL)) {
-                       goto fail;
-               }
-               return result;
-       }
-
-       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;
index 1dc1c44ed8e4ec6b4e630109c3e16ec566b76693..3bac72d136a3be4f6c96db7874e746c1794d8997 100644 (file)
@@ -8,12 +8,15 @@ 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)
@@ -242,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 39cea393cef78af85aea9beb34c2ae07ccc9abd6..00e8242d4ef073d326a46c211ce9210a06cafb6a 100644 (file)
@@ -1,5 +1,5 @@
 AC_PREREQ(2.50)
-AC_INIT(talloc, 1.2.1)
+AC_INIT(talloc, 1.3.0)
 AC_CONFIG_SRCDIR([talloc.c])
 AC_SUBST(datarootdir)
 AC_CONFIG_HEADER(config.h)
index b62393494b6cef28e98aaf8ef31d3f279c8e1be5..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__)
@@ -115,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);
index 69f65c6df7fae99da63240a424cf577309043edd..171a4088bac2c011d75892b574106a895cdc6a48 100644 (file)
@@ -1,5 +1,5 @@
 AC_PREREQ(2.50)
-AC_INIT(tevent, 0.9.4)
+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 867cfc08feff88c3532a98f76c94d1f5b8fb0e47..0c02e46f3ca16e6478fe820ae459d5272e4dfcbc 100644 (file)
@@ -143,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) {
@@ -162,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;
@@ -349,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
 
@@ -378,6 +427,14 @@ 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;
 }
@@ -411,6 +468,8 @@ int _tevent_loop_once(struct tevent_context *ev, const char *location)
                        errno = ELOOP;
                        return -1;
                }
+       }
+       if (ev->nesting.level > 0) {
                if (ev->nesting.hook_fn) {
                        int ret2;
                        ret2 = ev->nesting.hook_fn(ev,
@@ -428,7 +487,7 @@ int _tevent_loop_once(struct tevent_context *ev, const char *location)
 
        ret = ev->ops->loop_once(ev, location);
 
-       if (ev->nesting.level > 1) {
+       if (ev->nesting.level > 0) {
                if (ev->nesting.hook_fn) {
                        int ret2;
                        ret2 = ev->nesting.hook_fn(ev,
@@ -468,6 +527,8 @@ int _tevent_loop_until(struct tevent_context *ev,
                        errno = ELOOP;
                        return -1;
                }
+       }
+       if (ev->nesting.level > 0) {
                if (ev->nesting.hook_fn) {
                        int ret2;
                        ret2 = ev->nesting.hook_fn(ev,
@@ -490,7 +551,7 @@ int _tevent_loop_until(struct tevent_context *ev,
                }
        }
 
-       if (ev->nesting.level > 1) {
+       if (ev->nesting.level > 0) {
                if (ev->nesting.hook_fn) {
                        int ret2;
                        ret2 = ev->nesting.hook_fn(ev,
@@ -511,6 +572,34 @@ done:
        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)
+{
+       /*
+        * 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
 */
index 4a3f51ae5eedb4fe90e253845c240118bf63910a..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,
@@ -233,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);
@@ -295,8 +323,7 @@ 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);
index b63d299d94272efec09d28c06c89a02720a7ce22..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);
        }
 
@@ -417,6 +404,16 @@ static int epoll_event_loop_once(struct tevent_context *ev, const char *location
                                                           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, const char *location
        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, const char *location)
-{
-       struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data,
-                                                          struct epoll_event_context);
-       while (epoll_ev->ev->fd_events) {
-               if (epoll_event_loop_once(ev, location) != 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 f10485398f147315d6c71e3058734795f4fb38f7..eebf76706773a51eb83d8cff158acba25a80ef9d 100644 (file)
@@ -85,7 +85,17 @@ struct tevent_req {
                 *
                 * This for debugging only.
                 */
-               const char *location;
+               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
@@ -105,10 +115,10 @@ struct tevent_req {
                uint64_t error;
 
                /**
-                * @brief the timer event if tevent_req_post was used
+                * @brief the immediate event used by tevent_req_post
                 *
                 */
-               struct tevent_timer *trigger;
+               struct tevent_immediate *trigger;
 
                /**
                 * @brief the timer event if tevent_req_set_timeout was used
@@ -143,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,
@@ -188,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;
@@ -222,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;
 
@@ -247,6 +284,8 @@ struct tevent_context {
 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,
@@ -271,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 3832088b34cc24601a771a1cf2af8ff366244ee2..380a6388e29bca675071d819894f55b2cae1d88b 100644 (file)
@@ -43,7 +43,7 @@ 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,
@@ -95,8 +95,14 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
                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;
+       }
 
        data = talloc_size(req, data_size);
        if (data == NULL) {
@@ -111,9 +117,12 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
        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;
 }
 
@@ -265,14 +269,11 @@ bool tevent_req_is_in_progress(struct tevent_req *req)
  */
 void tevent_req_received(struct tevent_req *req)
 {
-       talloc_free(req->data);
-       req->data = NULL;
+       TALLOC_FREE(req->data);
        req->private_print = NULL;
 
-       talloc_free(req->internal.trigger);
-       req->internal.trigger = NULL;
-       talloc_free(req->internal.timer);
-       req->internal.timer = NULL;
+       TALLOC_FREE(req->internal.trigger);
+       TALLOC_FREE(req->internal.timer);
 
        req->internal.state = TEVENT_REQ_RECEIVED;
 }
@@ -313,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,
index cdddb601c42ce78094a46280d869958e8e660ea7..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,15 +193,13 @@ 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 
@@ -219,42 +210,35 @@ static int select_event_loop_once(struct tevent_context *ev, const char *locatio
                                                           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, const char *location)
-{
-       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, location) != 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 73a45e8c20fe327d75d35b1b0fd1149c860f0f04..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;
                        }
                }
        }
@@ -540,6 +524,16 @@ static int std_event_loop_once(struct tevent_context *ev, const char *location)
                                                           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, const char *location)
        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, const char *location)
-{
-       struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
-                                                          struct std_event_context);
-       std_ev->exit_code = 0;
-
-       while (ev->fd_events && std_ev->exit_code == 0) {
-               if (std_event_loop_once(ev, location) != 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 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
 
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 2e0582e088c7c8cbde18bee4cdd34dbf2eeb1e7a..1e94a2a63c45cf70ab5fdf8ab58f286a3279a42c 100644 (file)
@@ -1302,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)
 {
@@ -1339,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 */
@@ -1354,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)
@@ -3426,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)
@@ -3466,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 */
@@ -3651,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)
@@ -3704,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] */,
@@ -3758,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;
@@ -3795,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) {
@@ -3811,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)
 {
@@ -3822,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);
@@ -3847,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 3aebf3308ebe783066acf7e26231a55fa7a880b7..eb86e8c6a08d50a0366b3f4e09cb2ec78d75b27f 100644 (file)
@@ -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);
@@ -446,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);
@@ -470,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);
@@ -479,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] */,
@@ -488,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 8c8b687a015fda537bae19b5df62a47dd18c2502..f5b161a9c7e7c98a186f5e34377a3a387dac3c29 100644 (file)
@@ -1366,6 +1366,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrinterInfo2(struct ndr_pull *ndr, i
                }
                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));
@@ -2797,6 +2800,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int n
                }
                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));
@@ -3298,6 +3304,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_JobInfo2(struct ndr_pull *ndr, int n
                }
                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));
@@ -3965,6 +3974,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_JobInfo4(struct ndr_pull *ndr, int n
                }
                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));
@@ -4519,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));
@@ -4833,6 +4848,9 @@ static enum ndr_err_code ndr_pull_spoolss_SetJobInfo2(struct ndr_pull *ndr, int
                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));
@@ -5230,6 +5248,9 @@ static enum ndr_err_code ndr_pull_spoolss_SetJobInfo4(struct ndr_pull *ndr, int
                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));
@@ -6286,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));
@@ -14530,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);
@@ -14575,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);
@@ -14584,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);
@@ -14611,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:
@@ -14640,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);
@@ -14652,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);
@@ -14661,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);
@@ -14687,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:
@@ -14716,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;
 
@@ -16968,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));
@@ -16982,37 +16978,86 @@ 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);
+}
+
+_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;
+}
+
+_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));
+       *r = v;
+       return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_spoolss_PrintNotifyField(struct ndr_print *ndr, const char *name, enum spoolss_PrintNotifyField r)
+{
+       const char *val = NULL;
+
+       switch (r) {
+               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);
 }
@@ -17036,12 +17081,84 @@ _PUBLIC_ void ndr_print_spoolss_NotifyType(struct ndr_print *ndr, const char *na
        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_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;
@@ -17058,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]));
                        }
                }
        }
@@ -17094,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);
@@ -17124,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);
                        }
                }
@@ -17509,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));
@@ -17526,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));
@@ -17543,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);
@@ -18235,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));
@@ -21610,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");
                }
@@ -21625,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);
@@ -21646,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);
        }
@@ -21655,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);
                }
@@ -21673,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;
 }
@@ -21719,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);
@@ -21744,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));
        }
@@ -21757,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;
 }
@@ -21784,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));
@@ -21815,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);
@@ -25550,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");
                }
@@ -25571,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);
@@ -25589,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);
        }
@@ -25607,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);
                }
@@ -25631,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;
 }
@@ -25662,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++;
@@ -25887,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");
                }
@@ -25926,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));
@@ -25959,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);
@@ -25997,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");
                }
@@ -26055,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) {
@@ -26101,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++;
@@ -26117,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) {
@@ -26131,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");
                }
@@ -26149,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;
@@ -26172,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);
                }
@@ -26200,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) {
@@ -26228,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--;
@@ -26248,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");
@@ -26258,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");
@@ -26279,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) {
@@ -26300,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);
                }
@@ -26325,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) {
@@ -26348,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) {
@@ -26356,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 b6418f59005314e0bd3af00002bbc487582b1071..0feb4a2c5e3420a796931346584bff9ac968be28 100644 (file)
@@ -387,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);
@@ -452,8 +451,14 @@ enum ndr_err_code ndr_push_spoolss_PrintProcDataTypesInfo(struct ndr_push *ndr,
 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);
@@ -470,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);
@@ -662,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 77fb03ac898aee39dfb6dbfb6165934caa34806c..8340b34e454240ee554655f1e391670a7fdc2eec 100644 (file)
 #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) )
@@ -324,7 +328,7 @@ 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;
@@ -398,7 +402,7 @@ 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;
@@ -420,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;
@@ -452,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;
@@ -480,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;
@@ -502,7 +506,7 @@ struct spoolss_SetJobInfo2 {
        const char *text_status;/* [unique,charset(UTF16)] */
        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;
@@ -528,7 +532,7 @@ struct spoolss_SetJobInfo4 {
        const char *text_status;/* [unique,charset(UTF16)] */
        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;
@@ -652,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;
@@ -1058,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] */;
 
@@ -1299,87 +1284,152 @@ union spoolss_PrintProcDataTypesInfo {
 #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 */
@@ -1426,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)] */
@@ -1494,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 )
@@ -2087,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;
@@ -2098,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;
 
 };
@@ -2116,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;
@@ -2129,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;
@@ -2143,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;
 
 };
@@ -2157,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;
@@ -2826,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;
@@ -2877,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;
@@ -2898,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;
@@ -2907,7 +2965,7 @@ struct spoolss_GetPrinterDataEx {
 };
 
 
-struct spoolss_EnumPrinterDataEx {
+struct _spoolss_EnumPrinterDataEx {
        struct {
                struct policy_handle *handle;/* [ref] */
                const char *key_name;/* [charset(UTF16)] */
@@ -2915,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;
@@ -2924,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 9cb930f97976b3e6c5c5035baf453c5908c2ce2c..79efbb59708a1ca9d4341e31081ff0e6cd5dfd9f 100644 (file)
@@ -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);
@@ -5649,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;
        }
@@ -6106,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;
@@ -6198,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;
        }
@@ -6290,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;
@@ -7865,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;
@@ -8292,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;
                        }
 
@@ -8344,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;
                        }
@@ -8366,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;
                        }
 
@@ -8388,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 f837afbd5d353f707d84c618907dc842af7df3b0..a1bb95aa9fa471dae9e5330cd0e144041df3be46 100644 (file)
@@ -289,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;
@@ -410,7 +410,7 @@ 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;
@@ -432,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;
@@ -464,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;
@@ -493,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;
@@ -515,7 +515,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [string,charset(UTF16)] uint16 *text_status;
                uint32 _secdesc_ptr;
                spoolss_JobStatus status;
-               uint32 priority;
+               [range(0,99)] uint32 priority;
                uint32 position;
                uint32 start_time;
                uint32 until_time;
@@ -541,7 +541,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                [string,charset(UTF16)] uint16 *text_status;
                uint32 _secdesc_ptr;
                spoolss_JobStatus status;
-               uint32 priority;
+               [range(0,99)] uint32 priority;
                uint32 position;
                uint32 start_time;
                uint32 until_time;
@@ -704,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;
@@ -1302,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;
 
@@ -1323,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
        );
 
@@ -1345,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
        );
@@ -1509,6 +1501,16 @@ import "misc.idl", "security.idl", "winreg.idl";
                [out,ref] uint32 *needed
        );
 
+       /*
+        * 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;
@@ -1890,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 {
@@ -1932,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 {
@@ -1981,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;
@@ -2163,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
        );
@@ -2197,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
        );
@@ -2208,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
@@ -2216,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 351dbf701622040b227cd0d2bc1f4a0ac1a12ee1..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
 } 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
 */
@@ -216,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);
 }
 
 /*
@@ -252,7 +268,7 @@ enum ndr_err_code ndr_pull_spoolss_EnumJobs(struct ndr_pull *ndr, int flags, str
 
 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);
 }
 
 /*
@@ -284,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);
 }
 
 /*
@@ -312,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);
 }
 
 /*
@@ -340,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);
 }
 
 /*
@@ -368,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);
 }
 
 /*
@@ -401,7 +417,7 @@ enum ndr_err_code ndr_pull_spoolss_EnumPrintProcessors(struct ndr_pull *ndr, int
 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);
 }
 
 /*
@@ -434,7 +450,107 @@ enum ndr_err_code ndr_pull_spoolss_EnumPrintProcDataTypes(struct ndr_pull *ndr,
 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(spoolss_EnumPrintProcDataTypes);
+       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);
 }
 
 /*
@@ -451,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;
@@ -470,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));
        }
@@ -481,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;
@@ -496,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;
@@ -523,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;
@@ -545,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);
 
@@ -1062,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 04a84bfb628d4433b8fe3d2df16e270c0a4c739e..aa6e277c5f380524290238f60ece58fa68eefcd2 100644 (file)
@@ -38,7 +38,10 @@ enum ndr_err_code ndr_push_spoolss_EnumPrintProcDataTypes(struct ndr_push *ndr,
 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);
@@ -46,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 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 e1bea16523b9031072176cd46820c011cb1ca838..2b96226355acc9e7dca9400758f0f06e182db212 100644 (file)
@@ -41,6 +41,9 @@ sub teardown_env($$)
        $self->stop_sig_term($smbdpid);
        $self->stop_sig_term($nmbdpid);
        $self->stop_sig_term($winbinddpid);
+
+       sleep(2);
+
        $self->stop_sig_kill($smbdpid);
        $self->stop_sig_kill($nmbdpid);
        $self->stop_sig_kill($winbinddpid);
@@ -187,7 +190,7 @@ sub stop_sig_term($$) {
 
 sub stop_sig_kill($$) {
        my ($self, $pid) = @_;
-       kill("KILL", $pid) or warn("Unable to kill $pid: $!");
+       kill("ALRM", $pid) or warn("Unable to kill $pid: $!");
 }
 
 sub write_pid($$$)
index f69c39b6e46af06f7fcf9352e58e7ed2384ccb92..cf74182f27886cbabb3d584dffbbb5be66d6de0f 100644 (file)
@@ -448,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 \
@@ -577,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 \
@@ -590,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
@@ -610,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
@@ -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
+
 
 #####################################################################
 #
@@ -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)
 
index 6491f39ed0d1e3a243986720e852d9f297e8df27..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;
        }
@@ -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;
        }
@@ -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;
        }
@@ -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;
@@ -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;
@@ -4570,7 +4574,7 @@ static int do_host_query(const char *query_host)
 
                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);
        }
 
@@ -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;
@@ -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;
@@ -4667,7 +4671,7 @@ static int do_message_op(struct user_auth_info *auth_info)
                return 1;
        }
 
-       send_message(get_cmdline_auth_info_username(auth_info));
+       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 98f41d61e547158047f55d063369e544ffc541dc..dc5850aba1d25e6a5938657fe131ecf97b441b46 100644 (file)
@@ -31,7 +31,7 @@ if test "x$enable_external_libtalloc" != xno
 then
        PKG_CHECK_MODULES(TALLOC, talloc >= 1.3.0, 
                [ enable_external_libtalloc=yes ],
-               [ if x$enable_external_libtalloc = xyes; then 
+               [ if test x$enable_external_libtalloc = xyes; then
                        AC_MSG_ERROR([Unable to find libtalloc])
              else 
                        enable_external_libtalloc=no
@@ -285,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
@@ -297,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
@@ -433,7 +433,7 @@ 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 vfs_preopen"
@@ -3277,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"
@@ -6087,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
@@ -6131,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)
@@ -6358,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 b48a75526a6e2a0ae271522367c1feaa8e0d4934..4bf4b5c7357037e125e097c8239c2167da24aad2 100644 (file)
@@ -622,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 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 f992f0686a910c6fc1cdb22346e8ba1d79159896..9bffa4d319fb24ec9b1c06c64bf2f703f411a359 100644 (file)
@@ -1072,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);
@@ -1205,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);
@@ -1396,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);
@@ -1553,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,21 +2362,13 @@ 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_display(const struct cli_state *c);
-void cli_cm_set_credentials(struct user_auth_info *auth_info);
-void cli_cm_set_port(int port_number);
-void cli_cm_set_dest_name_type(int type);
-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);
 bool cli_dfs_get_referral(TALLOC_CTX *ctx,
                        struct cli_state *cli,
                        const char *path,
@@ -2382,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,
@@ -4793,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);
@@ -5175,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,
@@ -5189,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,
@@ -5403,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  */
 
@@ -5436,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  */
 
@@ -5534,27 +5529,38 @@ WERROR rpccli_spoolss_enumprinters(struct rpc_pipe_client *cli,
                                   uint32_t offered,
                                   uint32_t *count,
                                   union spoolss_PrinterInfo **info);
-WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                 POLICY_HND *hnd, const char *valuename, 
-                                 REGISTRY_VALUE *value);
-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_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  */
 
@@ -5667,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  */
 
@@ -5752,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);
@@ -5759,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);
@@ -5831,38 +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);
-uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p);
-bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src);
-bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth);
-bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth);
-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 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);
-
 /* The following definitions come from rpc_server/srv_eventlog_lib.c  */
 
 TDB_CONTEXT *elog_init_tdb( char *tdbfilename );
@@ -5900,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);
 
@@ -5941,18 +5886,20 @@ 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  */
 
+void copy_id18_to_sam_passwd(struct samu *to,
+                            struct samr_UserInfo18 *from);
 void copy_id20_to_sam_passwd(struct samu *to,
                             struct samr_UserInfo20 *from);
 void copy_id21_to_sam_passwd(const char *log_prefix,
@@ -5960,13 +5907,12 @@ void copy_id21_to_sam_passwd(const char *log_prefix,
                             struct samr_UserInfo21 *from);
 void copy_id23_to_sam_passwd(struct samu *to,
                             struct samr_UserInfo23 *from);
+void copy_id24_to_sam_passwd(struct samu *to,
+                            struct samr_UserInfo24 *from);
 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);
+void copy_id26_to_sam_passwd(struct samu *to,
+                            struct samr_UserInfo26 *from);
 
 /* The following definitions come from rpc_server/srv_spoolss_nt.c  */
 
@@ -5982,11 +5928,12 @@ 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);
-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);
+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_t type, uint8_t *data, int real_len);
 void spoolss_notify_server_name(int snum,
                                       struct spoolss_Notify *data,
                                       print_queue_struct *queue,
@@ -6054,18 +6001,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);
-struct spoolss_DeviceMode *construct_dev_mode_new(TALLOC_CTX *mem_ctx,
-                                                 const char *servicename);
+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 enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines );
-WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u);
-WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u);
-WERROR _spoolss_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  */
 
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 eb2fdd5..0000000
+++ /dev/null
@@ -1,450 +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"
-
-/* 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 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 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_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 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 fd9b669710c6ef534da367abc5095f591b19d57e..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,
-                               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);
 
 bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err);
 wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req);
index 8c56941829002030cbb654beb1fcc7d030c1e37b..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)
@@ -181,17 +186,6 @@ static int s3_event_loop_once(struct tevent_context *ev, const char *location)
        return 0;
 }
 
-static int s3_event_loop_wait(struct tevent_context *ev, const char *location)
-{
-       int ret = 0;
-
-       while (ret == 0) {
-               ret = s3_event_loop_once(ev, location);
-       }
-
-       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)
index 43ebed6c220d622c7d3a548ee2bf4da2e99f7ff9..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);
index 617bde2c9ae4b078afbb7ca47d834872b3f9ed19..c09632a8570b08c925e5e506d0e850ecd3b7b82d 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;
 
@@ -1276,6 +1276,7 @@ WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx,
 
        *r->out.buffer = NULL;
        *r->out.entries_read = 0;
+       *r->out.total_entries = 0;
 
        switch (r->in.level) {
                case 0:
@@ -1364,13 +1365,8 @@ WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx,
                }
        }
 
-       if (r->out.entries_read) {
-               *r->out.entries_read = entries_read;
-       }
-
-       if (r->out.total_entries) {
-               *r->out.total_entries = entries_read;
-       }
+       *r->out.entries_read = entries_read;
+       *r->out.total_entries = entries_read;
 
        werr = WERR_OK;
 
index 9d7f299f59bae03b0ae66b19355dad8b43da8112..e760a8b1de58f2be84fe1a7b42f1bd7951d4bf6f 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;
@@ -2806,6 +2806,7 @@ WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
 
        *r->out.buffer = NULL;
        *r->out.entries_read = 0;
+       *r->out.total_entries = 0;
 
        switch (r->in.level) {
                case 0:
@@ -2899,12 +2900,8 @@ WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
                }
        }
 
-       if (r->out.entries_read) {
-               *r->out.entries_read = entries_read;
-       }
-       if (r->out.total_entries) {
-               *r->out.total_entries = entries_read;
-       }
+       *r->out.entries_read = entries_read;
+       *r->out.total_entries = entries_read;
 
  done:
        if (ctx->disable_policy_handle_cache) {
@@ -3242,6 +3239,7 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
 
        *r->out.buffer = NULL;
        *r->out.entries_read = 0;
+       *r->out.total_entries = 0;
 
        switch (r->in.level) {
                case 0:
@@ -3402,12 +3400,8 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
                }
        }
 
-       if (r->out.entries_read) {
-               *r->out.entries_read = entries_read;
-       }
-       if (r->out.total_entries) {
-               *r->out.total_entries = entries_read;
-       }
+       *r->out.entries_read = entries_read;
+       *r->out.total_entries = entries_read;
 
  done:
        if (ctx->disable_policy_handle_cache) {
index ec794ca74e765e24a4578fd193a7f874fbd4f5ff..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.
 ****************************************************************************/
@@ -3102,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 3604be369f3f51305e757ab65a7de25b9e85e398..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 */
@@ -1152,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;
@@ -1175,73 +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;
        }
-       tevent_req_set_callback(subreq2, open_socket_out_defer_connected, 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 =
-               tevent_req_callback_data(subreq, 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 e1c67491c0f43219cc7e3241f8511c25fc1adcf7..dbea8b6686df30f2d2810783ad370c69799f38a8 100644 (file)
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
-bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err)
-{
-       enum async_req_state state;
-       uint64_t error;
-       if (!async_req_is_error(req, &state, &error)) {
-               *pwbc_err = WBC_ERR_SUCCESS;
-               return false;
-       }
-
-       switch (state) {
-       case ASYNC_REQ_USER_ERROR:
-               *pwbc_err = error;
-               break;
-       case ASYNC_REQ_TIMED_OUT:
-               *pwbc_err = WBC_ERR_UNKNOWN_FAILURE;
-               break;
-       case ASYNC_REQ_NO_MEMORY:
-               *pwbc_err = WBC_ERR_NO_MEMORY;
-               break;
-       default:
-               *pwbc_err = WBC_ERR_UNKNOWN_FAILURE;
-               break;
-       }
-       return true;
-}
-
 wbcErr map_wbc_err_from_errno(int error)
 {
        switch(error) {
@@ -65,17 +39,6 @@ wbcErr map_wbc_err_from_errno(int error)
        }
 }
 
-wbcErr async_req_simple_recv_wbcerr(struct async_req *req)
-{
-       wbcErr wbc_err;
-
-       if (async_req_is_wbcerr(req, &wbc_err)) {
-               return wbc_err;
-       }
-
-       return WBC_ERR_SUCCESS;
-}
-
 bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err)
 {
        enum tevent_req_state state;
index 80937641e62d78c2feaaba3c5b4763cbe7e2815f..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;
@@ -545,43 +551,18 @@ struct wb_trans_state {
 
 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 async_req *subreq);
+static void wb_trans_retry_wait_done(struct tevent_req *subreq);
 
-static void wb_trigger_trans(struct async_req *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 wb_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_trans_state);
-       struct tevent_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;
-               }
-               tevent_req_set_callback(subreq, wb_trans_connect_done, req);
-               return;
-       }
-
-       subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd,
-                                  state->wb_req);
-       if (async_req_nomem(subreq, req)) {
-               return;
-       }
-       tevent_req_set_callback(subreq, wb_trans_done, req);
-}
-
-struct async_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;
@@ -590,21 +571,32 @@ struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
        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;
@@ -615,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;
        }
 
@@ -634,47 +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 *subreq2;
+       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;
        }
 
-       subreq2 = wb_open_pipe_send(state, state->ev, state->wb_ctx,
-                                   state->need_priv);
-       if (async_req_nomem(subreq2, req)) {
+       subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
+                                  state->need_priv);
+       if (tevent_req_nomem(subreq, req)) {
                return;
        }
-       tevent_req_set_callback(subreq2, wb_trans_connect_done, req);
+       tevent_req_set_callback(subreq, wb_trans_connect_done, req);
 }
 
 static void wb_trans_connect_done(struct tevent_req *subreq)
 {
-       struct async_req *req = tevent_req_callback_data(
-               subreq, struct async_req);
-       struct wb_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_trans_state);
-       struct tevent_req *subreq2;
+       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);
@@ -684,20 +673,20 @@ static void wb_trans_connect_done(struct tevent_req *subreq)
                return;
        }
 
-       subreq2 = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd,
-                                   state->wb_req);
-       if (async_req_nomem(subreq2, req)) {
+       subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd,
+                                  state->wb_req);
+       if (tevent_req_nomem(subreq, req)) {
                return;
        }
-       tevent_req_set_callback(subreq2, wb_trans_done, req);
+       tevent_req_set_callback(subreq, wb_trans_done, req);
 }
 
 static void wb_trans_done(struct tevent_req *subreq)
 {
-       struct async_req *req = tevent_req_callback_data(
-               subreq, 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);
@@ -707,17 +696,17 @@ static void wb_trans_done(struct tevent_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 56d7b061a1b5e5674aaaafe52f467d65fb8ad63a..52cb975a6c5b389d039f914704064c414ed72eb8 100644 (file)
@@ -511,13 +511,13 @@ char *kerberos_get_default_realm_from_ccache( void )
 
   out:
 
-       if (princ) {
-               krb5_free_principal(ctx, princ);
-       }
-       if (cc) {
-               krb5_cc_close(ctx, cc);
-       }
        if (ctx) {
+               if (princ) {
+                       krb5_free_principal(ctx, princ);
+               }
+               if (cc) {
+                       krb5_cc_close(ctx, cc);
+               }
                krb5_free_context(ctx);
        }
 
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 e579d1c9f0bcc32b7cdfda27ae2fbe6390f721ea..066ac7bdb8887478f02a389caf6b2daffe203ff0 100644 (file)
@@ -861,7 +861,7 @@ static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu)
 
 static void handle_incoming_pdu(struct cli_state *cli)
 {
-       struct cli_request *req;
+       struct cli_request *req, *next;
        uint16_t mid;
        size_t raw_pdu_len, buf_len, pdu_len, rest_len;
        char *pdu;
@@ -978,8 +978,11 @@ static void handle_incoming_pdu(struct cli_state *cli)
        DEBUG(10, ("handle_incoming_pdu: Aborting with %s\n",
                   nt_errstr(status)));
 
-       for (req = cli->outstanding_requests; req; req = req->next) {
-               async_req_nterror(req->async[0], status);
+       for (req = cli->outstanding_requests; req; req = next) {
+               next = req->next;
+               if (req->num_async) {
+                       async_req_nterror(req->async[0], status);
+               }
        }
        return;
 }
index 43326e912cc49c33e6067dfc23d4d13f7e42aae0..ebb01c44a6aefd812c89e8648df2a542c456735c 100644 (file)
@@ -1785,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;
        }
 }
 
@@ -1801,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);
@@ -1815,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;
index 8544d5520eac5825d95f1ca069ca8705b0171949..430807eb7f319db765cc2449aec568e355b697de 100644 (file)
    as a separator when looking at the pathname part.... JRA.
 ********************************************************************/
 
-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 bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
                                struct cli_state *cli,
                                const char *sharename,
@@ -96,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,
@@ -143,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_ex(cm_creds.signing_state))) {
+       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);
@@ -167,8 +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;
+       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;
@@ -198,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),
@@ -219,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()))) {
@@ -259,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);
        }
@@ -313,6 +293,7 @@ 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,
@@ -322,6 +303,7 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
        struct cli_state *cli;
 
        cli = do_connect(ctx, server, share,
+                               auth_info,
                                show_hdr, force_encrypt, max_protocol,
                                port, name_type);
 
@@ -389,6 +371,7 @@ 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,
@@ -402,9 +385,25 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
                return c;
        }
 
-       return cli_cm_connect(ctx, referring_cli,
-                               server, share, show_hdr, force_encrypt,
-                               max_protocol, port, name_type);
+       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;
+       }
+
+       return cli_cm_connect(ctx,
+                               referring_cli,
+                               server,
+                               share,
+                               auth_info,
+                               show_hdr,
+                               force_encrypt,
+                               max_protocol,
+                               port,
+                               name_type);
 }
 
 /****************************************************************************
@@ -423,18 +422,10 @@ void cli_cm_display(const struct cli_state *cli)
 /****************************************************************************
 ****************************************************************************/
 
-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);
@@ -449,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
@@ -604,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);
 }
 
 /********************************************************************
@@ -763,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,
@@ -843,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;
        }
 
@@ -893,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,
@@ -952,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 168ca6330332f39f18a909e892442f7390852045..4ab31374e2c712627f521b5015ffeb390dc6628a 100644 (file)
@@ -878,24 +878,30 @@ failed:
 
  bool get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, bool remote)
  {
-       krb5_keyblock *skey;
-       krb5_error_code err;
-       bool ret = False;
+       krb5_keyblock *skey = NULL;
+       krb5_error_code err = 0;
+       bool ret = false;
 
-       if (remote)
+       if (remote) {
                err = krb5_auth_con_getremotesubkey(context, auth_context, &skey);
-       else
+       } else {
                err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey);
-       if (err == 0 && skey != NULL) {
-               DEBUG(10, ("Got KRB5 session key of length %d\n",  (int)KRB5_KEY_LENGTH(skey)));
-               *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey));
-               dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length);
+       }
 
-               ret = True;
+       if (err || skey == NULL) {
+               DEBUG(10, ("KRB5 error getting session key %d\n", err));
+               goto done;
+       }
 
+       DEBUG(10, ("Got KRB5 session key of length %d\n",  (int)KRB5_KEY_LENGTH(skey)));
+       *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey));
+       dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length);
+
+       ret = true;
+
+ done:
+       if (skey) {
                krb5_free_keyblock(context, skey);
-       } else {
-               DEBUG(10, ("KRB5 error getting session key %d\n", err));
        }
 
        return ret;
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 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 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 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 3442561030845c5be68d3c05b9ee3cc7164d5c8e..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 ));
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 71c634442b325fc84f272e73da1a221659b3cffe..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]);
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 ef10c123f3fa62266737928c8cd9bf8f60a26eee..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 },
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 76614c67eb90ae5f67f93be5faecd8b40d3f947b..3f369bdab3c2de92f97d5599076d627427474a51 100644 (file)
@@ -705,252 +705,122 @@ WERROR rpccli_spoolss_enumprinters(struct rpc_pipe_client *cli,
        return werror;
 }
 
-/*********************************************************************
- Decode various spoolss rpc's and info levels
- ********************************************************************/
-
 /**********************************************************************
+ 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;
 
-       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;
+       status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx,
+                                                 handle,
+                                                 key_name,
+                                                 offered,
+                                                 count,
+                                                 info,
+                                                 &needed,
+                                                 &werror);
+
+       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;
+}
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 e499607..0000000
+++ /dev/null
@@ -1,843 +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 uint32 (obvious, but the code is clean)
- ********************************************************************/
-
-static uint32 size_of_uint32(uint32 *value)
-{
-       return (sizeof(*value));
-}
-
-/*******************************************************************
-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;
-}
-
-/*******************************************************************
- 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_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;
-}
-
-/*******************************************************************
- * 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;
-}
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 fb7aca5c0fa2febbf9f3578d72962ce41f2dd3d3..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, NULL, state->p->fd,
-                            &state->iov, 1);
-       if (async_req_nomem(subreq, req)) {
-               return;
-       }
-       tevent_req_set_callback(subreq, np_write_done, req);
-}
-
 static void np_write_done(struct tevent_req *subreq)
 {
-       struct async_req *req =
-               tevent_req_callback_data(subreq, 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,32 +1361,35 @@ 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;
        }
        tevent_req_set_callback(subreq, np_read_done, req);
@@ -1403,10 +1397,10 @@ static void np_read_trigger(struct async_req *req)
 
 static void np_read_done(struct tevent_req *subreq)
 {
-       struct async_req *req =
-               tevent_req_callback_data(subreq, 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;
@@ -1414,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;
        }
 
@@ -1431,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 1128a856cda974a03b0a466457ca42c28c022749..c60d904b18293684f851665e9cfe7f0878c418ff 100644 (file)
@@ -719,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)
 {
@@ -2122,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;
@@ -2135,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,
@@ -2188,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;
@@ -3032,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;
@@ -3047,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;
 
@@ -3159,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;
        }
 
@@ -3447,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;
@@ -3460,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,
@@ -3521,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;
@@ -3642,12 +3636,7 @@ static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
                pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
        }
 
-       if (id18->password_expired) {
-               pdb_set_pass_last_set_time(pwd, 0, PDB_CHANGED);
-       } else {
-               /* FIXME */
-               pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
-       }
+       copy_id18_to_sam_passwd(pwd, id18);
 
        return pdb_update_sam_account(pwd);
 }
@@ -3854,23 +3843,16 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
  set_user_info_pw
  ********************************************************************/
 
-static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
-                            int level)
+static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
 {
        uint32 len = 0;
        char *plaintext_buf = NULL;
        uint32 acct_ctrl;
-       time_t last_set_time;
-       enum pdb_value_state last_set_state;
 
        DEBUG(5, ("Attempting administrator password change for user %s\n",
                  pdb_get_username(pwd)));
 
        acct_ctrl = pdb_get_acct_ctrl(pwd);
-       /* we need to know if it's expired, because this is an admin change, not a
-          user change, so it's still expired when we're done */
-       last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
-       last_set_time = pdb_get_pass_last_set_time(pwd);
 
        if (!decode_pw_buffer(talloc_tos(),
                                pass,
@@ -3913,29 +3895,38 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
 
        memset(plaintext_buf, '\0', strlen(plaintext_buf));
 
-       /*
-        * A level 25 change does reset the pwdlastset field, a level 24
-        * change does not. I know this is probably not the full story, but
-        * it is needed to make XP join LDAP correctly, without it the later
-        * auth2 check can fail with PWD_MUST_CHANGE.
-        */
-       if (level != 25) {
-               /*
-                * restore last set time as this is an admin change, not a
-                * user pw change
-                */
-               pdb_set_pass_last_set_time (pwd, last_set_time,
-                                           last_set_state);
+       DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
+
+       return True;
+}
+
+/*******************************************************************
+ set_user_info_24
+ ********************************************************************/
+
+static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
+                                struct samr_UserInfo24 *id24,
+                                struct samu *pwd)
+{
+       NTSTATUS status;
+
+       if (id24 == NULL) {
+               DEBUG(5, ("set_user_info_24: NULL id24\n"));
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
-       DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
+       if (!set_user_info_pw(id24->password.data, pwd)) {
+               return NT_STATUS_WRONG_PASSWORD;
+       }
 
-       /* update the SAMBA password */
-       if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
-               return False;
+       copy_id24_to_sam_passwd(pwd, id24);
+
+       status = pdb_update_sam_account(pwd);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
-       return True;
+       return NT_STATUS_OK;
 }
 
 /*******************************************************************
@@ -3961,6 +3952,14 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
                return NT_STATUS_ACCESS_DENIED;
        }
 
+       if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
+           (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
+
+               if (!set_user_info_pw(id25->password.data, pwd)) {
+                       return NT_STATUS_WRONG_PASSWORD;
+               }
+       }
+
        copy_id25_to_sam_passwd(pwd, id25);
 
        /* write the change out */
@@ -3986,6 +3985,36 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
+/*******************************************************************
+ set_user_info_26
+ ********************************************************************/
+
+static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
+                                struct samr_UserInfo26 *id26,
+                                struct samu *pwd)
+{
+       NTSTATUS status;
+
+       if (id26 == NULL) {
+               DEBUG(5, ("set_user_info_26: NULL id26\n"));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (!set_user_info_pw(id26->password.data, pwd)) {
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
+       copy_id26_to_sam_passwd(pwd, id26);
+
+       status = pdb_update_sam_account(pwd);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       return NT_STATUS_OK;
+}
+
+
 /*******************************************************************
  samr_SetUserInfo
  ********************************************************************/
@@ -3996,7 +4025,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;
@@ -4009,7 +4037,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;
        }
 
@@ -4146,10 +4174,8 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
 
                        dump_data(100, info->info24.password.data, 516);
 
-                       if (!set_user_info_pw(info->info24.password.data, pwd,
-                                             switch_value)) {
-                               status = NT_STATUS_WRONG_PASSWORD;
-                       }
+                       status = set_user_info_24(p->mem_ctx,
+                                                 &info->info24, pwd);
                        break;
 
                case 25:
@@ -4164,13 +4190,6 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
 
                        status = set_user_info_25(p->mem_ctx,
                                                  &info->info25, pwd);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               goto done;
-                       }
-                       if (!set_user_info_pw(info->info25.password.data, pwd,
-                                             switch_value)) {
-                               status = NT_STATUS_WRONG_PASSWORD;
-                       }
                        break;
 
                case 26:
@@ -4183,18 +4202,14 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
 
                        dump_data(100, info->info26.password.data, 516);
 
-                       if (!set_user_info_pw(info->info26.password.data, pwd,
-                                             switch_value)) {
-                               status = NT_STATUS_WRONG_PASSWORD;
-                       }
+                       status = set_user_info_26(p->mem_ctx,
+                                                 &info->info26, pwd);
                        break;
 
                default:
                        status = NT_STATUS_INVALID_INFO_CLASS;
        }
 
- done:
-
        TALLOC_FREE(pwd);
 
        if (has_enough_rights) {
index ef588aed1a38c8220a3a834995f22bc579bec919..068156054f00ccaffe289fc30a49656399dbfb48 100644 (file)
                    (!(s1) && (s2)) ||\
                ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
 
+/*************************************************************
+ Copies a struct samr_UserInfo18 to a struct samu
+**************************************************************/
+
+void copy_id18_to_sam_passwd(struct samu *to,
+                            struct samr_UserInfo18 *from)
+{
+       struct samr_UserInfo21 i;
+
+       if (from == NULL || to == NULL) {
+               return;
+       }
+
+       ZERO_STRUCT(i);
+
+       i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
+       i.password_expired      = from->password_expired;
+
+       copy_id21_to_sam_passwd("INFO_18", to, &i);
+}
+
 /*************************************************************
  Copies a struct samr_UserInfo20 to a struct samu
 **************************************************************/
@@ -336,7 +357,7 @@ void copy_id21_to_sam_passwd(const char *log_prefix,
        if (from->fields_present & SAMR_FIELD_EXPIRED_FLAG) {
                DEBUG(10,("%s SAMR_FIELD_EXPIRED_FLAG: %02X\n", l,
                        from->password_expired));
-               if (from->password_expired == PASS_MUST_CHANGE_AT_NEXT_LOGON) {
+               if (from->password_expired != 0) {
                        pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
                } else {
                        /* A subtlety here: some windows commands will
@@ -345,9 +366,27 @@ void copy_id21_to_sam_passwd(const char *log_prefix,
                           in these caess.  "net user /dom <user> /active:y"
                           for example, to clear an autolocked acct.
                           We must check to see if it's expired first. jmcd */
+
+                       uint32_t pwd_max_age = 0;
+                       time_t now = time(NULL);
+
+                       pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age);
+
+                       if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) {
+                               pwd_max_age = get_time_t_max();
+                       }
+
                        stored_time = pdb_get_pass_last_set_time(to);
-                       if (stored_time == 0)
-                               pdb_set_pass_last_set_time(to, time(NULL),PDB_CHANGED);
+
+                       /* we will only *set* a pwdlastset date when
+                          a) the last pwdlastset time was 0 (user was forced to
+                             change password).
+                          b) the users password has not expired. gd. */
+
+                       if ((stored_time == 0) ||
+                           ((now - stored_time) > pwd_max_age)) {
+                               pdb_set_pass_last_set_time(to, now, PDB_CHANGED);
+                       }
                }
        }
 }
@@ -367,6 +406,27 @@ void copy_id23_to_sam_passwd(struct samu *to,
        copy_id21_to_sam_passwd("INFO 23", to, &from->info);
 }
 
+/*************************************************************
+ Copies a struct samr_UserInfo24 to a struct samu
+**************************************************************/
+
+void copy_id24_to_sam_passwd(struct samu *to,
+                            struct samr_UserInfo24 *from)
+{
+       struct samr_UserInfo21 i;
+
+       if (from == NULL || to == NULL) {
+               return;
+       }
+
+       ZERO_STRUCT(i);
+
+       i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
+       i.password_expired      = from->password_expired;
+
+       copy_id21_to_sam_passwd("INFO_24", to, &i);
+}
+
 /*************************************************************
  Copies a struct samr_UserInfo25 to a struct samu
 **************************************************************/
@@ -380,3 +440,24 @@ void copy_id25_to_sam_passwd(struct samu *to,
 
        copy_id21_to_sam_passwd("INFO_25", to, &from->info);
 }
+
+/*************************************************************
+ Copies a struct samr_UserInfo26 to a struct samu
+**************************************************************/
+
+void copy_id26_to_sam_passwd(struct samu *to,
+                            struct samr_UserInfo26 *from)
+{
+       struct samr_UserInfo21 i;
+
+       if (from == NULL || to == NULL) {
+               return;
+       }
+
+       ZERO_STRUCT(i);
+
+       i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
+       i.password_expired      = from->password_expired;
+
+       copy_id21_to_sam_passwd("INFO_26", to, &i);
+}
diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c
deleted file mode 100644 (file)
index da82202..0000000
+++ /dev/null
@@ -1,692 +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)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMPRINTERS);
-}
-
-/********************************************************************
- * api_spoolss_getprinter
- * called from the spoolss dispatcher
- *
- ********************************************************************/
-
-static bool api_spoolss_getprinter(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_GETPRINTER);
-}
-
-/********************************************************************
- * api_spoolss_getprinter
- * called from the spoolss dispatcher
- *
- ********************************************************************/
-
-static bool api_spoolss_getprinterdriver2(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_GETPRINTERDRIVER2);
-}
-
-/********************************************************************
- * 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)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMJOBS);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-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)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMPRINTERDRIVERS);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_getform(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_GETFORM);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_enumforms(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMFORMS);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_enumports(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMPORTS);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-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)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMPRINTPROCESSORS);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_addprintprocessor(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ADDPRINTPROCESSOR);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_enumprintprocdatatypes(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMPRINTPROCDATATYPES);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_enumprintmonitors(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_ENUMMONITORS);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool api_spoolss_getjob(pipes_struct *p)
-{
-       return proxy_spoolss_call(p, NDR_SPOOLSS_GETJOB);
-}
-
-/********************************************************************
- * 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 950dc013b2dd079df17ddd2e19a326b0f8fd3ecf..b66f48aa29922da51c56e5f896ed8343c25b0c39 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
@@ -34,6 +35,9 @@
 #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)
 
 
@@ -62,13 +66,13 @@ typedef struct _counter_printer_0 {
        struct _counter_printer_0 *prev;
 
        int snum;
-       uint32 counter;
+       uint32_t counter;
 } counter_printer_0;
 
 static counter_printer_0 *counter_list;
 
 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
-static uint32 smb_connections=0;
+static uint32_t smb_connections = 0;
 
 
 /* in printing/nt_printing.c */
@@ -144,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;
@@ -182,7 +186,7 @@ static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
                /* Tell the connections db we're no longer interested in
                 * printer notify messages. */
 
-               register_message_flags( False, FLAG_MSG_PRINT_NOTIFY );
+               register_message_flags(false, FLAG_MSG_PRINT_NOTIFY);
        }
 
        smb_connections--;
@@ -194,7 +198,7 @@ static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
 
 static int printer_entry_destructor(Printer_entry *Printer)
 {
-       if (Printer->notify.client_connected==True) {
+       if (Printer->notify.client_connected == true) {
                int snum = -1;
 
                if ( Printer->printer_type == SPLHND_SERVER) {
@@ -213,7 +217,7 @@ static int printer_entry_destructor(Printer_entry *Printer)
        Printer->notify.localmachine[0]='\0';
        Printer->notify.printerlocal=0;
        TALLOC_FREE(Printer->notify.option);
-       Printer->notify.client_connected=False;
+       Printer->notify.client_connected = false;
 
        free_nt_devicemode( &Printer->nt_devmode );
        free_a_printer( &Printer->printer_info, 2 );
@@ -227,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;
 
@@ -243,18 +248,19 @@ 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)));
-               return False;
+               DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
+                       OUR_HANDLE(hnd)));
+               return false;
        }
 
        close_policy_hnd(p, hnd);
 
-       return True;
+       return true;
 }
 
 /****************************************************************************
@@ -267,7 +273,7 @@ WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sh
        char *command = NULL;
        int ret;
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
-       bool is_print_op = False;
+       bool is_print_op = false;
 
        /* can't fail if we don't try */
 
@@ -309,7 +315,7 @@ WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sh
                return WERR_BADFID; /* What to return here? */
 
        /* go ahead and re-read the services immediately */
-       reload_services( False );
+       reload_services(false);
 
        if ( lp_servicenumber( sharename )  < 0 )
                return WERR_ACCESS_DENIED;
@@ -321,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;
        }
 
@@ -358,14 +365,15 @@ 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)));
-               return False;
+               DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
+                       OUR_HANDLE(hnd)));
+               return false;
        }
 
        switch (Printer->printer_type) {
@@ -374,9 +382,9 @@ static bool get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number,
                        *number = print_queue_snum(Printer->sharename);
                        return (*number != -1);
                case SPLHND_SERVER:
-                       return False;
+                       return false;
                default:
-                       return False;
+                       return false;
        }
 }
 
@@ -391,7 +399,7 @@ static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename
 
        if ( strlen(handlename) < 3 ) {
                DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
-               return False;
+               return false;
        }
 
        /* it's a print server */
@@ -405,7 +413,7 @@ static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename
                Printer->printer_type = SPLHND_PRINTER;
        }
 
-       return True;
+       return true;
 }
 
 /****************************************************************************
@@ -422,7 +430,7 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
        char *aprinter, *printername;
        const char *servername;
        fstring sname;
-       bool found=False;
+       bool found = false;
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        WERROR result;
 
@@ -442,15 +450,15 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
        /* save the servername to fill in replies on this handle */
 
        if ( !is_myname_or_ipaddr( servername ) )
-               return False;
+               return false;
 
        fstrcpy( Printer->servername, servername );
 
        if ( Printer->printer_type == SPLHND_SERVER )
-               return True;
+               return true;
 
        if ( Printer->printer_type != SPLHND_PRINTER )
-               return False;
+               return false;
 
        DEBUGADD(5, ("searching for [%s]\n", aprinter ));
 
@@ -459,12 +467,12 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
        if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
                Printer->printer_type = SPLHND_PORTMON_TCP;
                fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
-               found = True;
+               found = true;
        }
        else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
                Printer->printer_type = SPLHND_PORTMON_LOCAL;
                fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
-               found = True;
+               found = true;
        }
 
        /* Search all sharenames first as this is easier than pulling
@@ -482,7 +490,7 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
 
                fstrcpy(sname, lp_servicename(snum));
                if ( strequal( aprinter, sname ) ) {
-                       found = True;
+                       found = true;
                        break;
                }
 
@@ -520,7 +528,7 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
 
                if ( strequal(printername, aprinter) ) {
                        free_a_printer( &printer, 2);
-                       found = True;
+                       found = true;
                        break;
                }
 
@@ -533,21 +541,22 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
 
        if ( !found ) {
                DEBUGADD(4,("Printer not found\n"));
-               return False;
+               return false;
        }
 
        DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
 
        fstrcpy(Printer->sharename, sname);
 
-       return True;
+       return true;
 }
 
 /****************************************************************************
  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;
 
@@ -561,7 +570,7 @@ static bool open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3
 
        if (!create_policy_hnd(p, hnd, new_printer)) {
                TALLOC_FREE(new_printer);
-               return False;
+               return false;
        }
 
        /* Add to the internal list. */
@@ -571,19 +580,19 @@ static bool open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3
 
        if (!set_printer_hnd_printertype(new_printer, name)) {
                close_printer_handle(p, hnd);
-               return False;
+               return false;
        }
 
        if (!set_printer_hnd_name(new_printer, name)) {
                close_printer_handle(p, hnd);
-               return False;
+               return false;
        }
 
        new_printer->access_granted = access_granted;
 
        DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count ));
 
-       return True;
+       return true;
 }
 
 /***************************************************************************
@@ -591,17 +600,17 @@ static bool open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3
  given by (notify_type, notify_field).
  **************************************************************************/
 
-static bool is_monitoring_event_flags(uint32 flags, uint16 notify_type,
-                                     uint16 notify_field)
+static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
+                                     uint16_t notify_field)
 {
-       return True;
+       return true;
 }
 
-static bool is_monitoring_event(Printer_entry *p, uint16 notify_type,
-                               uint16 notify_field)
+static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
+                               uint16_t notify_field)
 {
        struct spoolss_NotifyOption *option = p->notify.option;
-       uint32 i, j;
+       uint32_t i, j;
 
        /*
         * Flags should always be zero when the change notify
@@ -611,7 +620,7 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type,
         */
 
        if (!option) {
-               return False;
+               return false;
        }
 
        if (p->notify.flags)
@@ -628,8 +637,8 @@ 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) {
-                               return True;
+                       if (option->types[i].fields[j].field == notify_field) {
+                               return true;
                        }
                }
        }
@@ -637,7 +646,7 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type,
        DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
                   p->servername, p->sharename, notify_type, notify_field));
 
-       return False;
+       return false;
 }
 
 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
@@ -746,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 },
 };
 
 
@@ -840,7 +849,7 @@ static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
 /***********************************************************************
  **********************************************************************/
 
-static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
+static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
 {
        if ( !ctr || !ctr->msg_groups )
                return NULL;
@@ -931,7 +940,7 @@ static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MS
  back registered
  **********************************************************************/
 
-static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
+static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
 {
        Printer_entry            *p;
        TALLOC_CTX               *mem_ctx = notify_ctr_getctx( ctr );
@@ -1104,23 +1113,23 @@ done:
 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
 {
 
-       uint32 tv_sec, tv_usec;
+       uint32_t tv_sec, tv_usec;
        size_t offset = 0;
 
        /* Unpack message */
 
-       offset += tdb_unpack((uint8 *)buf + offset, len - offset, "f",
+       offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
                             msg->printer);
 
-       offset += tdb_unpack((uint8 *)buf + offset, len - offset, "ddddddd",
+       offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
                                &tv_sec, &tv_usec,
                                &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
 
        if (msg->len == 0)
-               tdb_unpack((uint8 *)buf + offset, len - offset, "dd",
+               tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
                           &msg->notify.value[0], &msg->notify.value[1]);
        else
-               tdb_unpack((uint8 *)buf + offset, len - offset, "B",
+               tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
                           &msg->len, &msg->notify.data);
 
        DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
@@ -1133,9 +1142,9 @@ static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, voi
                DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
                          msg->notify.value[1]));
        else
-               dump_data(3, (uint8 *)msg->notify.data, msg->len);
+               dump_data(3, (uint8_t *)msg->notify.data, msg->len);
 
-       return True;
+       return true;
 }
 
 /********************************************************************
@@ -1224,7 +1233,8 @@ static void receive_notify2_message_list(struct messaging_context *msg,
 
        /* cleanup */
 
-       DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count ));
+       DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
+               (uint32_t)msg_count ));
 
        notify_msg_ctr_destroy( &messages );
 
@@ -1242,16 +1252,16 @@ static bool srv_spoolss_drv_upgrade_printer(char* drivername)
        int len = strlen(drivername);
 
        if (!len)
-               return False;
+               return false;
 
        DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
                drivername));
 
        messaging_send_buf(smbd_messaging_context(), procid_self(),
                           MSG_PRINTER_DRVUPGRADE,
-                          (uint8 *)drivername, len+1);
+                          (uint8_t *)drivername, len+1);
 
-       return True;
+       return true;
 }
 
 /**********************************************************************
@@ -1319,7 +1329,7 @@ void update_monitored_printq_cache( void )
        int snum;
 
        /* loop through all printers and update the cache where
-          client_connected == True */
+          client_connected == true */
        while ( printer )
        {
                if ( (printer->printer_type == SPLHND_PRINTER)
@@ -1345,16 +1355,16 @@ static bool srv_spoolss_reset_printerdata(char* drivername)
        int len = strlen(drivername);
 
        if (!len)
-               return False;
+               return false;
 
        DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
                drivername));
 
        messaging_send_buf(smbd_messaging_context(), procid_self(),
                           MSG_PRINTERDATA_INIT_RESET,
-                          (uint8 *)drivername, len+1);
+                          (uint8_t *)drivername, len+1);
 
-       return True;
+       return true;
 }
 
 /**********************************************************************
@@ -1455,12 +1465,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;
 
@@ -1470,7 +1479,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;
        }
@@ -1519,7 +1528,7 @@ static bool convert_devicemode_new(const char *printername,
        if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
                SAFE_FREE(nt_devmode->nt_dev_private);
                nt_devmode->driverextra = devmode->__driverextra_length;
-               if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
+               if((nt_devmode->nt_dev_private = SMB_MALLOC_ARRAY(uint8_t, nt_devmode->driverextra)) == NULL)
                        return false;
                memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
        }
@@ -1536,7 +1545,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;
@@ -1550,16 +1558,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;
        }
@@ -1610,7 +1618,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;
                }
@@ -1622,7 +1630,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;
                        }
@@ -1638,7 +1646,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;
                        }
@@ -1660,8 +1668,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;
                }
@@ -1697,14 +1705,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;
                }
@@ -1732,12 +1740,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 */
@@ -1793,8 +1800,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;
 
@@ -1807,7 +1814,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;
                        }
@@ -1993,83 +2000,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) {
@@ -2080,7 +2018,7 @@ static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handl
        if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
-       Printer->document_started=False;
+       Printer->document_started = false;
        print_job_end(snum, Printer->jobid,NORMAL_CLOSE);
        /* error codes unhandled so far ... */
 
@@ -2094,14 +2032,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
@@ -2121,16 +2057,15 @@ 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);
+       update_c_setprinter(false);
 
        return result;
 }
@@ -2236,7 +2171,7 @@ WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
                        /* remove the Win2k driver first*/
 
                        status_win2k = delete_printer_driver(
-                               p, info_win2k.info_3, 3, False );
+                               p, info_win2k.info_3, 3, false);
                        free_a_printer_driver( info_win2k, 3 );
 
                        /* this should not have failed---if it did, report to client */
@@ -2248,7 +2183,7 @@ WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
                }
        }
 
-       status = delete_printer_driver(p, info.info_3, version, False);
+       status = delete_printer_driver(p, info.info_3, version, false);
 
        /* if at least one of the deletes succeeded return OK */
 
@@ -2273,7 +2208,6 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
        NT_PRINTER_DRIVER_INFO_LEVEL    info;
        NT_PRINTER_DRIVER_INFO_LEVEL    info_win2k;
        int                             version;
-       uint32_t                        flags = r->in.delete_flags;
        bool                            delete_files;
        WERROR                          status;
        WERROR                          status_win2k = WERR_ACCESS_DENIED;
@@ -2300,7 +2234,7 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
                return WERR_INVALID_ENVIRONMENT;
        }
 
-       if ( flags & DPD_DELETE_SPECIFIC_VERSION )
+       if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
                version = r->in.version;
 
        ZERO_STRUCT(info);
@@ -2316,7 +2250,7 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
                 * then we've failed
                 */
 
-               if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
+               if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
                        goto done;
 
                /* try for Win2k driver if "Windows NT x86" */
@@ -2345,11 +2279,11 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
         * Refer to MSDN docs on DeletePrinterDriverEx() for details.
         */
 
-       delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
+       delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
 
        /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
 
-       if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
+       if ( delete_files && printer_driver_files_in_use(info.info_3) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) {
                /* no idea of the correct error here */
                status = WERR_ACCESS_DENIED;
                goto done;
@@ -2358,11 +2292,11 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
 
        /* also check for W32X86/3 if necessary; maybe we already have? */
 
-       if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION)  ) {
+       if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION)  ) {
                if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
                {
 
-                       if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
+                       if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) {
                                /* no idea of the correct error here */
                                free_a_printer_driver( info_win2k, 3 );
                                status = WERR_ACCESS_DENIED;
@@ -2394,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
  ***************************************************************************/
@@ -2453,8 +2341,9 @@ static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char
  Internal routine for storing printerdata
  ***************************************************************************/
 
-WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
-                                  uint32 type, uint8 *data, int real_len  )
+WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer,
+                         const char *key, const char *value,
+                         uint32_t type, uint8_t *data, int real_len)
 {
        /* the registry objects enforce uniqueness based on value name */
 
@@ -2465,188 +2354,151 @@ 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;
        }
 
        /* REG_BINARY
-        *  uint32 size          = 0x114
-        *  uint32 major         = 5
-        *  uint32 minor         = [0|1]
-        *  uint32 build         = [2195|2600]
+        *  uint32_t size        = 0x114
+        *  uint32_t major       = 5
+        *  uint32_t minor       = [0|1]
+        *  uint32_t build       = [2195|2600]
         *  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
@@ -2655,79 +2507,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);
 }
 
 /*********************************************************
@@ -2744,12 +2597,12 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
        if ( is_zero_addr((struct sockaddr *)client_ss) ) {
                if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
                        DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
-                       return False;
+                       return false;
                }
 
                if (ismyaddr((struct sockaddr *)&rm_addr)) {
                        DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
-                       return False;
+                       return false;
                }
        } else {
                char addr[INET6_ADDRSTRLEN];
@@ -2771,13 +2624,13 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
        if ( !NT_STATUS_IS_OK( ret ) ) {
                DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
                        remote_machine ));
-               return False;
+               return false;
        }
 
        if ( the_cli->protocol != PROTOCOL_NT1 ) {
                DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
                cli_shutdown(the_cli);
-               return False;
+               return false;
        }
 
        /*
@@ -2785,15 +2638,15 @@ 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)));
                cli_shutdown(the_cli);
-               return False;
+               return false;
        }
 
-       return True;
+       return true;
 }
 
 /***************************************************************************
@@ -2801,8 +2654,9 @@ 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)
+                                       uint32_t localprinter, uint32_t type,
+                                       struct policy_handle *handle,
+                                       struct sockaddr_storage *client_ss)
 {
        WERROR result;
        NTSTATUS status;
@@ -2817,14 +2671,14 @@ static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
                fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
 
                if ( !spoolss_connect_to_client( &notify_cli_pipe, client_ss, unix_printer ))
-                       return False;
+                       return false;
 
                messaging_register(smbd_messaging_context(), NULL,
                                   MSG_PRINTER_NOTIFY2,
                                   receive_notify2_message_list);
                /* Tell the connections db we're now interested in printer
                 * notify messages. */
-               register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
+               register_message_flags(true, FLAG_MSG_PRINT_NOTIFY);
        }
 
        /*
@@ -2888,7 +2742,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;
@@ -2916,18 +2770,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;
        }
 
@@ -2945,7 +2799,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,
@@ -2958,7 +2812,7 @@ WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
                                        &Printer->notify.client_hnd, &client_ss))
                return WERR_SERVER_UNAVAILABLE;
 
-       Printer->notify.client_connected=True;
+       Printer->notify.client_connected = true;
 
        return WERR_OK;
 }
@@ -3433,7 +3287,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,
@@ -3443,59 +3297,59 @@ struct s_notify_info_data_table
 
 /* A table describing the various print notification constants and
    whether the notification data is a pointer to a variable sized
-   buffer, a one value uint32 or a two value uint32. */
+   buffer, a one value uint32_t or a two value uint32_t. */
 
 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 },
 };
 
 /*******************************************************************
@@ -3503,7 +3357,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;
 
@@ -3523,7 +3377,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;
@@ -3533,11 +3387,11 @@ static bool search_notify(enum spoolss_NotifyType type,
                    notify_info_data_table[i].field == field &&
                    notify_info_data_table[i].fn != NULL) {
                        *value = i;
-                       return True;
+                       return true;
                }
        }
 
-       return False;
+       return false;
 }
 
 /****************************************************************************
@@ -3545,11 +3399,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;
 }
@@ -3569,7 +3423,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;
@@ -3582,10 +3436,10 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd,
                option_type->count, lp_servicename(snum)));
 
        if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
-               return False;
+               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));
 
@@ -3598,7 +3452,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd,
                if (info->notifies == NULL) {
                        DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
                        free_a_printer(&printer, 2);
-                       return False;
+                       return false;
                }
 
                current_data = &info->notifies[info->count];
@@ -3615,7 +3469,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd,
        }
 
        free_a_printer(&printer, 2);
-       return True;
+       return true;
 }
 
 /*******************************************************************
@@ -3634,7 +3488,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"));
@@ -3646,7 +3500,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;
@@ -3656,7 +3510,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue,
                                                      info->count + 1);
                if (info->notifies == NULL) {
                        DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
-                       return False;
+                       return false;
                }
 
                current_data=&(info->notifies[info->count]);
@@ -3667,7 +3521,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue,
                info->count++;
        }
 
-       return True;
+       return true;
 }
 
 /*
@@ -3700,12 +3554,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;
@@ -3766,13 +3621,14 @@ 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;
+       uint32_t id;
        struct spoolss_NotifyOption *option;
        struct spoolss_NotifyOptionType option_type;
        int count,j;
@@ -3859,10 +3715,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 */
@@ -3876,7 +3731,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;
        }
 
@@ -3892,7 +3748,7 @@ WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
        /* We need to keep track of the change value to send back in
            RRPCN replies otherwise our updates are ignored. */
 
-       Printer->notify.fnpcn = True;
+       Printer->notify.fnpcn = true;
 
        if (Printer->notify.client_connected) {
                DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
@@ -3905,15 +3761,17 @@ 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;
        }
 
-       Printer->notify.fnpcn = False;
+       Printer->notify.fnpcn = false;
 
 done:
        return result;
@@ -4001,27 +3859,14 @@ static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
        return WERR_OK;
 }
 
-/****************************************************************************
- Free a DEVMODE struct.
-****************************************************************************/
-
-static void free_dev_mode(DEVICEMODE *dev)
-{
-       if (dev == NULL)
-               return;
-
-       SAFE_FREE(dev->dev_private);
-       SAFE_FREE(dev);
-}
-
 /****************************************************************************
  Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure.  Both pointers
  should be valid upon entry
 ****************************************************************************/
 
-static WERROR convert_nt_devicemode_new(TALLOC_CTX *mem_ctx,
-                                       struct spoolss_DeviceMode *r,
-                                       const NT_DEVICEMODE *ntdevmode)
+static WERROR convert_nt_devicemode(TALLOC_CTX *mem_ctx,
+                                   struct spoolss_DeviceMode *r,
+                                   const NT_DEVICEMODE *ntdevmode)
 {
        if (!r || !ntdevmode) {
                return WERR_INVALID_PARAM;
@@ -4082,64 +3927,18 @@ static WERROR convert_nt_devicemode_new(TALLOC_CTX *mem_ctx,
 }
 
 
-/****************************************************************************
- Convert an NT_DEVICEMODE to a DEVICEMODE structure.  Both pointers
- should be valid upon entry
-****************************************************************************/
-
-static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
-{
-       if ( !devmode || !ntdevmode )
-               return False;
-
-       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;
-
-       if (ntdevmode->nt_dev_private != NULL) {
-               if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
-                       return False;
-       }
-
-       return True;
-}
-
 /****************************************************************************
  Create a spoolss_DeviceMode struct. Returns talloced memory.
 ****************************************************************************/
 
-struct spoolss_DeviceMode *construct_dev_mode_new(TALLOC_CTX *mem_ctx,
-                                                 const char *servicename)
+struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx,
+                                             const char *servicename)
 {
        WERROR result;
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
        struct spoolss_DeviceMode *devmode = NULL;
 
-       DEBUG(7,("construct_dev_mode_new\n"));
+       DEBUG(7,("construct_dev_mode\n"));
 
        DEBUGADD(8,("getting printer characteristics\n"));
 
@@ -4153,13 +3952,13 @@ struct spoolss_DeviceMode *construct_dev_mode_new(TALLOC_CTX *mem_ctx,
 
        devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
        if (!devmode) {
-               DEBUG(2,("construct_dev_mode_new: talloc fail.\n"));
+               DEBUG(2,("construct_dev_mode: talloc fail.\n"));
                goto done;
        }
 
        DEBUGADD(8,("loading DEVICEMODE\n"));
 
-       result = convert_nt_devicemode_new(mem_ctx, devmode, printer->info_2->devmode);
+       result = convert_nt_devicemode(mem_ctx, devmode, printer->info_2->devmode);
        if (!W_ERROR_IS_OK(result)) {
                TALLOC_FREE(devmode);
        }
@@ -4170,47 +3969,6 @@ done:
        return devmode;
 }
 
-/****************************************************************************
- Create a DEVMODE struct. Returns malloced memory.
-****************************************************************************/
-
-DEVICEMODE *construct_dev_mode(const char *servicename)
-{
-       NT_PRINTER_INFO_LEVEL   *printer = NULL;
-       DEVICEMODE              *devmode = NULL;
-
-       DEBUG(7,("construct_dev_mode\n"));
-
-       DEBUGADD(8,("getting printer characteristics\n"));
-
-       if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
-               return NULL;
-
-       if ( !printer->info_2->devmode ) {
-               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"));
-               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;
-       }
-
-done:
-       free_a_printer(&printer,2);
-
-       return devmode;
-}
-
 /********************************************************************
  * construct_printer_info3
  * fill a spoolss_PrinterInfo3 struct
@@ -4415,7 +4173,7 @@ static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
        r->cjobs                = count;
        r->averageppm           = ntprinter->info_2->averageppm;
 
-       r->devmode = construct_dev_mode_new(mem_ctx, lp_const_servicename(snum));
+       r->devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
        if (!r->devmode) {
                DEBUG(8,("Returning NULL Devicemode!\n"));
        }
@@ -4544,94 +4302,30 @@ static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
        return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
 }
 
-#if 0  /* JERRY -- disabled for now.  Don't think this is used, tested, or correct */
 /********************************************************************
- enum_all_printers_info_1_remote.
+ enum_all_printers_info_1_network.
 *********************************************************************/
 
-static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
+                                              const char *name,
+                                              union spoolss_PrinterInfo **info,
+                                              uint32_t *count)
 {
-       PRINTER_INFO_1 *printer;
-       fstring printername;
-       fstring desc;
-       fstring comment;
-       DEBUG(4,("enum_all_printers_info_1_remote\n"));
-       WERROR result = WERR_OK;
+       const char *s = name;
 
-       /* JFM: currently it's more a place holder than anything else.
-        * In the spooler world there is a notion of server registration.
-        * the print servers are registered on the PDC (in the same domain)
-        *
-        * We should have a TDB here. The registration is done thru an
-        * undocumented RPC call.
-        */
+       DEBUG(4,("enum_all_printers_info_1_network\n"));
 
-       if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
-               return WERR_NOMEM;
+       /* If we respond to a enum_printers level 1 on our name with flags
+          set to PRINTER_ENUM_REMOTE with a list of printers then these
+          printers incorrectly appear in the APW browse list.
+          Specifically the printers for the server appear at the workgroup
+          level where all the other servers in the domain are
+          listed. Windows responds to this call with a
+          WERR_CAN_NOT_COMPLETE so we should do the same. */
 
-       *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;
-       }
-
-       /* 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;
-}
-
-#endif
-
-/********************************************************************
- enum_all_printers_info_1_network.
-*********************************************************************/
-
-static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
-                                              const char *name,
-                                              union spoolss_PrinterInfo **info,
-                                              uint32_t *count)
-{
-       const char *s = name;
-
-       DEBUG(4,("enum_all_printers_info_1_network\n"));
-
-       /* If we respond to a enum_printers level 1 on our name with flags
-          set to PRINTER_ENUM_REMOTE with a list of printers then these
-          printers incorrectly appear in the APW browse list.
-          Specifically the printers for the server appear at the workgroup
-          level where all the other servers in the domain are
-          listed. Windows responds to this call with a
-          WERR_CAN_NOT_COMPLETE so we should do the same. */
-
-       if (name[0] == '\\' && name[1] == '\\') {
-                s = name + 2;
-       }
+       if (name[0] == '\\' && name[1] == '\\') {
+                s = name + 2;
+       }
 
        if (is_myname_or_ipaddr(s)) {
                 return WERR_CAN_NOT_COMPLETE;
@@ -4727,12 +4421,6 @@ static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
                return enum_all_printers_info_1_name(mem_ctx, name, info, count);
        }
 
-#if 0  /* JERRY - disabled for now */
-       if (flags & PRINTER_ENUM_REMOTE) {
-               return enum_all_printers_info_1_remote(mem_ctx, name, info, count);
-       }
-#endif
-
        if (flags & PRINTER_ENUM_NETWORK) {
                return enum_all_printers_info_1_network(mem_ctx, name, info, count);
        }
@@ -5240,79 +4928,6 @@ static WERROR construct_printer_driver_info_2(TALLOC_CTX *mem_ctx,
        return result;
 }
 
-/********************************************************************
- * copy a strings array and convert to UNICODE
- *
- * convert an array of ascii string to a UNICODE string
- ********************************************************************/
-
-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;
-
-               j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
-               i++;
-       }
-
-       if (*uni_array) {
-               /* special case for ""; we need to add both NULL's here */
-               if (!j)
-                       (*uni_array)[j++]=0x0000;
-               (*uni_array)[j]=0x0000;
-       }
-
-       DEBUGADD(6,("last one:done\n"));
-
-       /* return size of array in uint16's */
-
-       return j+1;
-}
-
 /********************************************************************
  * construct_printer_info_3
  * fill a printer_info_3 struct
@@ -5456,7 +5071,7 @@ WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
 
        DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
 
-       if (!(printer = find_printer_index_by_hnd( p, r->in.handle))) {
+       if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
                DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
                return WERR_INVALID_PRINTER_NAME;
        }
@@ -5535,9 +5150,7 @@ WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
 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: "
@@ -5545,7 +5158,7 @@ WERROR _spoolss_StartPagePrinter(pipes_struct *p,
                return WERR_BADFID;
        }
 
-       Printer->page_started=True;
+       Printer->page_started = true;
        return WERR_OK;
 }
 
@@ -5556,21 +5169,20 @@ 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;
+       Printer->page_started = false;
        print_job_endpage(snum, Printer->jobid);
 
        return WERR_OK;
@@ -5583,15 +5195,14 @@ 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;
        }
 
@@ -5611,13 +5222,13 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p,
 
        if (info_1->datatype) {
                if (strcmp(info_1->datatype, "RAW") != 0) {
-                       (*jobid)=0;
+                       *r->out.job_id = 0;
                        return WERR_INVALID_DATATYPE;
                }
        }
 
        /* 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;
        }
 
@@ -5632,8 +5243,8 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p,
                return map_werror_from_unix(errno);
        }
 
-       Printer->document_started=True;
-       (*jobid) = Printer->jobid;
+       Printer->document_started = true;
+       *r->out.job_id = Printer->jobid;
 
        return WERR_OK;
 }
@@ -5645,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);
 }
 
 /****************************************************************
@@ -5657,26 +5266,25 @@ 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;
+       uint32_t buffer_written;
        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,
-                                       (SMB_OFF_T)-1, (size_t)buffer_size);
-       if (*buffer_written == (uint32)-1) {
+       buffer_written = (uint32_t)print_job_write(snum, Printer->jobid,
+                                                  (const char *)r->in.data.data,
+                                                  (SMB_OFF_T)-1,
+                                                  (size_t)r->in._data_size);
+       if (buffer_written == (uint32_t)-1) {
                *r->out.num_written = 0;
                if (errno == ENOSPC)
                        return WERR_NO_SPOOL_SPACE;
@@ -5695,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;
@@ -5703,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;
        }
 
@@ -5744,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 );
@@ -5768,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;
@@ -5907,7 +5515,7 @@ static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
 
 
 
-       return True;
+       return true;
 }
 
 /****************************************************************************
@@ -5919,7 +5527,7 @@ WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname
        char *command = NULL;
        int ret;
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
-       bool is_print_op = False;
+       bool is_print_op = false;
 
        if ( !*cmd ) {
                return WERR_ACCESS_DENIED;
@@ -5971,7 +5579,7 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV
        int ret;
        int fd;
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
-       bool is_print_op = False;
+       bool is_print_op = false;
        char *remote_machine = talloc_strdup(ctx, "%m");
 
        if (!remote_machine) {
@@ -6023,11 +5631,11 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV
        if ( ret != 0 ) {
                if (fd != -1)
                        close(fd);
-               return False;
+               return false;
        }
 
        /* reload our services immediately */
-       reload_services( False );
+       reload_services(false);
 
        numlines = 0;
        /* Get lines and convert them back to dos-codepage */
@@ -6045,7 +5653,7 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV
        }
 
        TALLOC_FREE(qlines);
-       return True;
+       return true;
 }
 
 
@@ -6054,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)
 {
@@ -6093,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;
        }
@@ -6103,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;
                }
@@ -6175,7 +5782,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
        if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
                init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
-                       REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+                       REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 );
 
                notify_printer_comment(snum, printer->info_2->comment);
        }
@@ -6183,7 +5790,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
        if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
                init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
-                       REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+                       REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 );
 
                notify_printer_sharename(snum, printer->info_2->sharename);
        }
@@ -6199,7 +5806,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
 
                init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
-                       REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+                       REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 );
 
                notify_printer_printername( snum, pname );
        }
@@ -6207,7 +5814,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
        if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
                init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
-                       REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+                       REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 );
 
                notify_printer_port(snum, printer->info_2->portname);
        }
@@ -6215,7 +5822,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
        if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
                init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
-                       REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+                       REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 );
 
                notify_printer_location(snum, printer->info_2->location);
        }
@@ -6225,15 +5832,15 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
 
        init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
        set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
-               REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+               REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 );
        set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
-               REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+               REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 );
 
        slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
                  global_myname(), printer->info_2->sharename );
        init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
        set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
-               REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+               REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 );
 
        /* Update printer info */
        result = mod_a_printer(printer, 2);
@@ -6248,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
@@ -6284,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;
@@ -6327,22 +5934,21 @@ 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;
        }
 
-       if (Printer->notify.client_connected==True) {
+       if (Printer->notify.client_connected == true) {
                int snum = -1;
 
                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);
@@ -6353,7 +5959,7 @@ WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
        Printer->notify.localmachine[0]='\0';
        Printer->notify.printerlocal=0;
        TALLOC_FREE(Printer->notify.option);
-       Printer->notify.client_connected=False;
+       Printer->notify.client_connected = false;
 
        return WERR_OK;
 }
@@ -6544,7 +6150,7 @@ static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
 
                struct spoolss_DeviceMode *devmode;
 
-               devmode = construct_dev_mode_new(info, lp_const_servicename(snum));
+               devmode = construct_dev_mode(info, lp_const_servicename(snum));
                if (!devmode) {
                        result = WERR_NOMEM;
                        goto out;
@@ -6669,36 +6275,32 @@ 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;
        }
 
-       if (!print_job_exists(lp_const_servicename(snum), jobid)) {
+       if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
                return WERR_INVALID_PRINTER_NAME;
        }
 
-       switch (command) {
+       switch (r->in.command) {
        case SPOOLSS_JOB_CONTROL_CANCEL:
        case SPOOLSS_JOB_CONTROL_DELETE:
-               if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
+               if (print_job_delete(p->server_info, snum, r->in.job_id, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
        case SPOOLSS_JOB_CONTROL_PAUSE:
-               if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
+               if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
        case SPOOLSS_JOB_CONTROL_RESTART:
        case SPOOLSS_JOB_CONTROL_RESUME:
-               if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
+               if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
@@ -7266,7 +6868,7 @@ static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
        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); /* FIXME */
+       r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
        W_ERROR_HAVE_NO_MEMORY(r->description);
 
        r->port_type = SPOOLSS_PORT_TYPE_WRITE;
@@ -7497,7 +7099,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;
@@ -7510,7 +7112,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;
        }
@@ -7583,10 +7185,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 */
@@ -7604,7 +7206,7 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
                return WERR_ACCESS_DENIED;
        }
 
-       update_c_setprinter(False);
+       update_c_setprinter(false);
        free_a_printer(&printer,2);
 
        return WERR_OK;
@@ -7646,7 +7248,7 @@ WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
        WERROR err = WERR_OK;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
        fstring driver_name;
-       uint32 version;
+       uint32_t version;
        const char *fn;
 
        switch (p->hdr_req.opnum) {
@@ -7949,29 +7551,15 @@ WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
        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;
@@ -7979,25 +7567,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 );
@@ -8010,12 +7599,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)) {
 
-               biggest_valuesize = 0;
-               biggest_datasize  = 0;
+               uint32_t biggest_valuesize = 0;
+               uint32_t biggest_datasize = 0;
+
+               DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
 
                num_values = regval_ctr_numvals( p_data->keys[key_index].values );
 
@@ -8037,10 +7626,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;
        }
@@ -8050,46 +7640,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
@@ -8100,36 +7678,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:
@@ -8137,37 +7708,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
@@ -8177,43 +7747,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;
 }
 
 /****************************************************************
@@ -8223,8 +7799,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"));
@@ -8237,11 +7812,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;
 
 
@@ -8256,21 +7831,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) {
@@ -8306,7 +7880,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;
@@ -8315,13 +7888,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;
        }
 
@@ -8330,7 +7903,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));
@@ -8382,12 +7955,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;
@@ -8396,7 +7968,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;
        }
 
@@ -8404,7 +7976,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));
@@ -8452,7 +8024,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;
@@ -8461,13 +8032,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;
        }
 
@@ -8475,7 +8046,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));
@@ -8751,13 +8322,13 @@ static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
        *count = 2;
 
        result = fill_monitor_1(info, &info[0].info1,
-                               SPL_LOCAL_PORT /* FIXME */);
+                               SPL_LOCAL_PORT);
        if (!W_ERROR_IS_OK(result)) {
                goto out;
        }
 
        result = fill_monitor_1(info, &info[1].info1,
-                               SPL_TCPIP_PORT /* FIXME */);
+                               SPL_TCPIP_PORT);
        if (!W_ERROR_IS_OK(result)) {
                goto out;
        }
@@ -8791,7 +8362,7 @@ static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
        *count = 2;
 
        result = fill_monitor_2(info, &info[0].info2,
-                               SPL_LOCAL_PORT, /* FIXME */
+                               SPL_LOCAL_PORT,
                                "Windows NT X86", /* FIXME */
                                "localmon.dll");
        if (!W_ERROR_IS_OK(result)) {
@@ -8799,7 +8370,7 @@ static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
        }
 
        result = fill_monitor_2(info, &info[1].info2,
-                               SPL_TCPIP_PORT, /* FIXME */
+                               SPL_TCPIP_PORT,
                                "Windows NT X86", /* FIXME */
                                "tcpmon.dll");
        if (!W_ERROR_IS_OK(result)) {
@@ -8943,12 +8514,12 @@ static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
        if (nt_devmode) {
                devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
                W_ERROR_HAVE_NO_MEMORY(devmode);
-               result = convert_nt_devicemode_new(devmode, devmode, nt_devmode);
+               result = convert_nt_devicemode(devmode, devmode, nt_devmode);
                if (!W_ERROR_IS_OK(result)) {
                        return result;
                }
        } else {
-               devmode = construct_dev_mode_new(mem_ctx, lp_const_servicename(snum));
+               devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
                W_ERROR_HAVE_NO_MEMORY(devmode);
        }
 
@@ -9040,31 +8611,27 @@ WERROR _spoolss_GetJob(pipes_struct *p,
 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;
        }
 
@@ -9073,50 +8640,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;
 }
 
 /****************************************************************
@@ -9126,11 +8701,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"));
@@ -9139,19 +8713,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
@@ -9161,38 +8736,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;
                        }
 
                        /*
@@ -9202,17 +8777,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;
 }
 
 /****************************************************************
@@ -9222,21 +8798,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) {
@@ -9263,76 +8839,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_u->needed = printerkey_len*2;
+       *r->out.needed = 4;
 
-       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);
+       }
 
-        return status;
+       free_a_printer(&printer, 2);
+       SAFE_FREE(keynames);
+
+       return result;
 }
 
 /****************************************************************
@@ -9342,8 +8930,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;
@@ -9352,7 +8939,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;
        }
 
@@ -9361,7 +8948,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) {
@@ -9386,35 +8973,64 @@ WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
        return status;
 }
 
+/****************************************************************
+****************************************************************/
+
+static WERROR registry_value_to_printer_enum_value(TALLOC_CTX *mem_ctx,
+                                                  REGISTRY_VALUE *v,
+                                                  struct spoolss_PrinterEnumValues *r)
+{
+       WERROR result;
 
-/********************************************************************
- * spoolss_enumprinterdataex
- ********************************************************************/
+       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;
        }
 
@@ -9425,51 +9041,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;
        }
 
        /*
@@ -9477,37 +9092,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
@@ -9518,32 +9121,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);
 }
 
 /****************************************************************************
@@ -9974,28 +9573,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
 ****************************************************************/
@@ -10304,17 +9881,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
 ****************************************************************/
@@ -10348,28 +9914,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 33fff2e3b3a24df21aa26de12bf4f4bfec7a538c..18c0790569e4d4a14103e2e79e1e5aeb445e4060 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]);
@@ -413,10 +414,10 @@ 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;
+       uint32_t        info_level = 2;
        union spoolss_PrinterInfo info;
        struct spoolss_SetPrinterInfoCtr info_ctr;
        const char      *printername, *comment = NULL;
@@ -489,10 +490,10 @@ 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;
+       uint32_t        info_level = 2;
        union spoolss_PrinterInfo info;
        const char      *printername,
                        *new_printername = NULL;
@@ -565,7 +566,7 @@ 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_t        level = 1;
        const char      *printername;
@@ -643,7 +644,7 @@ static void display_reg_value(REGISTRY_VALUE value)
        switch(value.type) {
        case REG_DWORD:
                printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
-                      *((uint32 *) value.data_p));
+                      *((uint32_t *) value.data_p));
                break;
        case REG_SZ:
                rpcstr_pull_talloc(talloc_tos(),
@@ -672,7 +673,7 @@ static void display_reg_value(REGISTRY_VALUE value)
                break;
        }
        case REG_MULTI_SZ: {
-               uint32 i, num_values;
+               uint32_t i, num_values;
                char **values;
 
                if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p,
@@ -682,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]);
                }
@@ -697,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]);
@@ -733,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))
@@ -758,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;
@@ -918,7 +971,7 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
                                    TALLOC_CTX *mem_ctx,
                                    int argc, const char **argv)
 {
-       POLICY_HND      pol;
+       struct policy_handle pol;
        WERROR          werror;
        uint32_t        level = 3;
        const char      *printername;
@@ -1285,7 +1338,7 @@ static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
 {
        WERROR result;
        NTSTATUS status;
-       uint32                  level = 3;
+       uint32_t                  level = 3;
        struct spoolss_AddDriverInfoCtr info_ctr;
        struct spoolss_AddDriverInfo3 info3;
        const char              *arch;
@@ -1411,10 +1464,10 @@ 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;
+       uint32_t                level = 2;
        const char              *printername;
        union spoolss_PrinterInfo info;
        struct spoolss_SetPrinterInfoCtr info_ctr;
@@ -1660,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;
@@ -1750,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;
@@ -1864,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;
@@ -1948,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;
@@ -1995,10 +2048,10 @@ 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;
+       uint32_t num_forms, level = 1, i;
        union spoolss_FormInfo *forms;
 
        /* Parse the command arguments */
@@ -2063,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) {
@@ -2080,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;
@@ -2110,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;
@@ -2207,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;
 }
@@ -2273,7 +2309,7 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
        WERROR result;
        uint32_t level = 1, count, i;
        const char *printername;
-       POLICY_HND hnd;
+       struct policy_handle hnd;
        union spoolss_JobInfo *info;
 
        if (argc < 2 || argc > 3) {
@@ -2412,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]);
@@ -2434,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;
 }
@@ -2468,19 +2544,17 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
                                          const char **argv)
 {
        WERROR result;
-       uint32 i;
+       uint32_t 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]);
@@ -2489,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;
 }
@@ -2518,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 */
 
@@ -2546,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;
 }
@@ -2587,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;
@@ -2624,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) {
@@ -2671,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;
@@ -2687,7 +2764,7 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
        if ( !W_ERROR_IS_OK(werror) ) {
                printf("failed (%s)\n", win_errstr(werror));
                talloc_destroy(mem_ctx);
-               return False;
+               return false;
        }
        printf("ok\n");
 
@@ -2700,26 +2777,26 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
        if ( !W_ERROR_IS_OK(werror) ) {
                printf("failed (%s)\n", win_errstr(werror));
                talloc_destroy(mem_ctx);
-               return False;
+               return false;
        }
        printf("ok\n");
 
        talloc_destroy(mem_ctx);
 
-       return True;
+       return true;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-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;
        TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
        SEC_DESC *sd1, *sd2;
-       bool result = True;
+       bool result = true;
 
 
        printf("Retrieving printer security for %s...", cli1->desthost);
@@ -2730,7 +2807,7 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h
                                           &info1);
        if ( !W_ERROR_IS_OK(werror) ) {
                printf("failed (%s)\n", win_errstr(werror));
-               result = False;
+               result = false;
                goto done;
        }
        printf("ok\n");
@@ -2743,7 +2820,7 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h
                                           &info2);
        if ( !W_ERROR_IS_OK(werror) ) {
                printf("failed (%s)\n", win_errstr(werror));
-               result = False;
+               result = false;
                goto done;
        }
        printf("ok\n");
@@ -2756,13 +2833,13 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h
 
        if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
                printf("NULL secdesc!\n");
-               result = False;
+               result = false;
                goto done;
        }
 
        if (!sec_desc_equal( sd1, sd2 ) ) {
                printf("Security Descriptors *not* equal!\n");
-               result = False;
+               result = false;
                goto done;
        }
 
@@ -2787,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;
 
@@ -2812,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",
@@ -3045,39 +3122,39 @@ 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", "" },
-       { "enumprocs",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs,         &syntax_spoolss, NULL, "Enumerate Print Processors",          "" },
-       { "enumprocdatatypes",  RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &syntax_spoolss, NULL, "Enumerate Print Processor Data Types", "" },
-       { "enummonitors",       RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors,      &syntax_spoolss, NULL, "Enumerate Print Monitors", "" },
+       { "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 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 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 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 a743385f7f51fa7c454f66875ba4fd7a19ba1104..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;
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 e2d1497b280b589d9727d17188d2b896817216e9..6029eb072781d8cc1670385009b2ad0f1d3644ae 100644 (file)
@@ -4160,8 +4160,8 @@ static bool run_opentest(int dummy)
 static bool run_simple_posix_open_test(int dummy)
 {
        static struct cli_state *cli1;
-       const char *fname = "\\posix.file";
-       const char *dname = "\\posix.dir";
+       const char *fname = "\\posix:file";
+       const char *dname = "\\posix:dir";
        uint16 major, minor;
        uint32 caplow, caphigh;
        int fnum1 = -1;
@@ -5613,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);
@@ -5654,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);
                }
        }
 
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 c54d4794133950c0292ad48276071acce9931608..21881ba6a99f70f0ce7c819164aa3a2fa01887c8 100644 (file)
@@ -54,8 +54,8 @@ NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                                   DOM_SID **domain_sid,
                                   const char **domain_name)
 {
-       struct rpc_pipe_client *lsa_pipe;
-       POLICY_HND pol;
+       struct rpc_pipe_client *lsa_pipe = NULL;
+       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;
@@ -1657,8 +1657,8 @@ 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 rpc_pipe_client *pipe_hnd = NULL;
+       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 8a2ebfb01f54d2f4aeb659756eb12ec1be300be3..1d0e9a38beebb132e2b0498dd521d6b0b9ead411 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
@@ -84,7 +84,7 @@ static void display_reg_value(const char *subkey, REGISTRY_VALUE value)
        switch(value.type) {
        case REG_DWORD:
                d_printf("\t[%s:%s]: REG_DWORD: 0x%08x\n", subkey, value.valuename,
-                      *((uint32 *) value.data_p));
+                      *((uint32_t *) value.data_p));
                break;
 
        case REG_SZ:
@@ -105,7 +105,7 @@ static void display_reg_value(const char *subkey, REGISTRY_VALUE value)
                break;
 
        case REG_MULTI_SZ: {
-               uint32 i, num_values;
+               uint32_t i, num_values;
                char **values;
 
                if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p,
@@ -158,7 +158,7 @@ NTSTATUS net_copy_fileattr(struct net_context *c,
        int fnum_src = 0;
        int fnum_dst = 0;
        SEC_DESC *sd = NULL;
-       uint16 attr;
+       uint16_t attr;
        time_t f_atime, f_ctime, f_mtime;
 
 
@@ -654,9 +654,9 @@ static NTSTATUS copy_print_driver_3(struct net_context *c,
 static bool net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd,
                                        TALLOC_CTX *mem_ctx,
                                        char *name,
-                                       uint32 flags,
-                                       uint32 level,
-                                       uint32 *num_printers,
+                                       uint32_t flags,
+                                       uint32_t level,
+                                       uint32_t *num_printers,
                                        union spoolss_PrinterInfo **info)
 {
        WERROR result;
@@ -681,9 +681,9 @@ static bool net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd,
 static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd,
                                        TALLOC_CTX *mem_ctx,
                                        const char *printername,
-                                       uint32 access_required,
+                                       uint32_t access_required,
                                        const char *username,
-                                       POLICY_HND *hnd)
+                                       struct policy_handle *hnd)
 {
        WERROR result;
        fstring printername2;
@@ -722,8 +722,8 @@ 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,
-                               uint32 level,
+                               struct policy_handle *hnd,
+                               uint32_t level,
                                union spoolss_PrinterInfo *info)
 {
        WERROR result;
@@ -744,8 +744,8 @@ 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,
-                               uint32 level,
+                               struct policy_handle *hnd,
+                               uint32_t level,
                                union spoolss_PrinterInfo *info)
 {
        WERROR result;
@@ -815,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));
@@ -835,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));
@@ -854,15 +863,21 @@ 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,
+                                       uint32_t offered,
+                                       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));
@@ -875,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;
@@ -902,7 +917,7 @@ 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_t *num_forms,
                                union spoolss_FormInfo **forms)
@@ -926,8 +941,8 @@ 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 *count,
+                                       uint32_t level, const char *env,
+                                       uint32_t *count,
                                        union spoolss_DriverInfo **info)
 {
        WERROR result;
@@ -950,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_t level,
                             const char *env, int version,
                             union spoolss_DriverInfo *info)
 {
@@ -984,7 +999,7 @@ static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd,
 
 
 static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd,
-                            TALLOC_CTX *mem_ctx, uint32 level,
+                            TALLOC_CTX *mem_ctx, uint32_t level,
                             union spoolss_DriverInfo *info)
 {
        WERROR result;
@@ -1024,7 +1039,7 @@ static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd,
 }
 
 /**
- * abstraction function to get uint32 num_printers and PRINTER_INFO_CTR ctr
+ * abstraction function to get uint32_t num_printers and PRINTER_INFO_CTR ctr
  * for a single printer or for all printers depending on argc/argv
  **/
 
@@ -1033,10 +1048,10 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd,
                        int level,
                        int argc,
                        const char **argv,
-                       uint32 *num_printers,
+                       uint32_t *num_printers,
                        union spoolss_PrinterInfo **info_p)
 {
-       POLICY_HND hnd;
+       struct policy_handle hnd;
 
        /* no arguments given, enumerate all printers */
        if (argc == 0) {
@@ -1099,8 +1114,8 @@ NTSTATUS rpc_printer_list_internals(struct net_context *c,
                                        const char **argv)
 {
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-       uint32 i, num_printers;
-       uint32 level = 2;
+       uint32_t i, num_printers;
+       uint32_t level = 2;
        const char *printername, *sharename;
        union spoolss_PrinterInfo *info;
 
@@ -1151,8 +1166,8 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c,
                                                const char **argv)
 {
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-       uint32 i;
-       uint32 level = 3;
+       uint32_t i;
+       uint32_t level = 3;
        union spoolss_DriverInfo *info;
        int d;
 
@@ -1160,7 +1175,7 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c,
 
         for (i=0; archi_table[i].long_archi!=NULL; i++) {
 
-               uint32 num_drivers;
+               uint32_t num_drivers;
 
                /* enum remote drivers */
                if (!net_spoolss_enumprinterdrivers(pipe_hnd, mem_ctx, level,
@@ -1210,18 +1225,18 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_
                                        TALLOC_CTX *mem_ctx,
                                        int argc,
                                        const char **argv,
-                                       uint32 action)
+                                       uint32_t action)
 {
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-       uint32 i, num_printers;
-       uint32 level = 7;
+       uint32_t i, num_printers;
+       uint32_t level = 7;
        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;
 
@@ -1358,12 +1373,12 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c,
                                                const char **argv)
 {
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-       uint32 i, num_printers;
-       uint32 level = 7;
+       uint32_t i, num_printers;
+       uint32_t level = 7;
        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, &info_enum))
@@ -1450,12 +1465,12 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c,
           convince jerry that we should add clientside setacls level 3 at least
        */
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-       uint32 i = 0;
-       uint32 num_printers;
-       uint32 level = 2;
+       uint32_t i = 0;
+       uint32_t num_printers;
+       uint32_t level = 2;
        const char *printername, *sharename;
        struct rpc_pipe_client *pipe_hnd_dst = NULL;
-       POLICY_HND hnd_src, hnd_dst;
+       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;
@@ -1464,7 +1479,7 @@ NTSTATUS rpc_printer_migrate_security_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;
 
@@ -1596,12 +1611,12 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c,
 {
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        WERROR result;
-       uint32 i, f;
-       uint32 num_printers;
-       uint32 level = 1;
+       uint32_t i, f;
+       uint32_t num_printers;
+       uint32_t level = 1;
        const char *printername, *sharename;
        struct rpc_pipe_client *pipe_hnd_dst = NULL;
-       POLICY_HND hnd_src, hnd_dst;
+       struct policy_handle hnd_src, hnd_dst;
        union spoolss_PrinterInfo *info_enum;
        union spoolss_PrinterInfo info_dst;
        uint32_t num_forms;
@@ -1612,7 +1627,7 @@ NTSTATUS rpc_printer_migrate_forms_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;
 
@@ -1756,14 +1771,14 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
                                                const char **argv)
 {
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-       uint32 i, p;
-       uint32 num_printers;
-       uint32 level = 3;
+       uint32_t i, p;
+       uint32_t num_printers;
+       uint32_t level = 3;
        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;
        union spoolss_PrinterInfo *info_enum;
        union spoolss_PrinterInfo info_dst;
@@ -1775,7 +1790,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
        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;
 
@@ -1887,7 +1902,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
 
                }
 
-               if (strlen(drivername) == 0) {
+               if (!drivername || strlen(drivername) == 0) {
                        DEBUGADD(1,("Did not get driver for printer %s\n",
                                    printername));
                        goto done;
@@ -1968,12 +1983,12 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c,
 {
        WERROR result;
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-       uint32 i = 0, num_printers;
-       uint32 level = 2;
+       uint32_t i = 0, num_printers;
+       uint32_t level = 2;
        union spoolss_PrinterInfo info_dst, info_src;
        union spoolss_PrinterInfo *info_enum;
        struct cli_state *cli_dst = NULL;
-       POLICY_HND hnd_dst, hnd_src;
+       struct policy_handle hnd_dst, hnd_src;
        const char *printername, *sharename;
        struct rpc_pipe_client *pipe_hnd_dst = NULL;
        struct spoolss_SetPrinterInfoCtr info_ctr;
@@ -1982,7 +1997,7 @@ 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;
 
@@ -2124,21 +2139,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 level = 2;
+       uint32_t i = 0, p = 0, j = 0;
+       uint32_t num_printers;
+       uint32_t level = 2;
        const char *printername, *sharename;
        struct rpc_pipe_client *pipe_hnd_dst = NULL;
-       POLICY_HND hnd_src, hnd_dst;
+       struct policy_handle hnd_src, hnd_dst;
        union spoolss_PrinterInfo *info_enum;
        union spoolss_PrinterInfo info_dst_publish;
        union spoolss_PrinterInfo info_dst;
-       REGVAL_CTR *reg_ctr;
        struct cli_state *cli_dst = NULL;
        char *devicename = NULL, *unc_name = NULL, *url = NULL;
        const char *longname;
-
-       uint16 *keylist = NULL, *curkey;
+       const char **keylist = NULL;
 
        /* FIXME GD */
        ZERO_STRUCT(info_dst_publish);
@@ -2147,7 +2160,7 @@ 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;
 
@@ -2174,6 +2187,12 @@ 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 */
                printername = info_enum[i].info2.printername;
                sharename = info_enum[i].info2.sharename;
@@ -2266,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));
                        }
                }
 
@@ -2315,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;
@@ -2346,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;
@@ -2369,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;
 
@@ -2384,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);
@@ -2399,7 +2445,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
                                        value.type = REG_SZ;
                                        value.size = data.uni_str_len * 2;
                                        if (value.size) {
-                                               value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, data.buffer, value.size);
+                                               value.data_p = (uint8_t *)TALLOC_MEMDUP(mem_ctx, data.buffer, value.size);
                                        } else {
                                                value.data_p = NULL;
                                        }
@@ -2414,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 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 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 f5812f9e6524c26d771fa97b677f73a69ef7cbe1..66271068d26e493e9e622208c6182d87c61ff80c 100644 (file)
@@ -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:
 
@@ -1366,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 e06e30e0a89fdbe1a40cd9011c0b6b321b8fd0a6..ed0a33a5f22cc9610734551616716d6f0d15c27f 100644 (file)
@@ -1772,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;
 
@@ -1990,7 +1990,7 @@ 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;
@@ -2156,7 +2156,7 @@ 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;
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 4fc96e8a4bb4b0db17a7a4871f7d3c545f0a1645..384395f89648b06fc8da5fb69a1c304bec1566ed 100644 (file)
@@ -208,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);
 
@@ -549,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 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 732de1e20e0942afc6974e4f2745cab809cd3023..2bf63f0ca691ca5714825955e8972d4610f24735 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
@@ -116,7 +117,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 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 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 9de5b1cc0cc4dd7dde55d0916ddd3beca07158d0..280d60beb2fb1f58f4a7ba9e71700340ff6391bc 100644 (file)
@@ -10,6 +10,8 @@
 ../lib/util/talloc_stack.h: util/talloc_stack.h
 ../lib/util/xfile.h: util/xfile.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 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 01e77cb22cc8c6ee4c95e6995c61e2c14328a584..c5430eb9bf1f7965bd6710c7a53b59016d872f3b 100644 (file)
@@ -2,6 +2,7 @@
    ldb database library
 
    Copyright (C) Simo Sorce  2005-2008
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
 
      ** NOTE! The following LGPL license applies to the ldb
      ** library. This does NOT imply that all of Samba is released
@@ -52,23 +53,40 @@ struct ps_context {
 
        char **saved_referrals;
        int num_referrals;
+
+       struct ldb_request *down_req;
 };
 
-static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares)
+static int check_ps_continuation(struct ps_context *ac, struct ldb_request *req, struct ldb_reply *ares)
 {
-       struct ps_context *ac;
-       struct ldb_paged_control *rep_control, *req_control;
+       struct ldb_context *ldb;
+       struct ldb_control *rep_control, *req_control;
+       struct ldb_paged_control *paged_rep_control = NULL, *paged_req_control = NULL;
+       ldb = ldb_module_get_ctx(ac->module);
 
-       ac = talloc_get_type(req->context, struct ps_context);
+       rep_control = ldb_reply_get_control(ares, LDB_CONTROL_PAGED_RESULTS_OID);
+       if (rep_control) {
+               paged_rep_control = talloc_get_type(rep_control->data, struct ldb_paged_control);
+       }
 
-       /* look up our paged control */
-       if (!ares->controls || strcmp(LDB_CONTROL_PAGED_RESULTS_OID, ares->controls[0]->oid) != 0) {
-               /* something wrong here */
-               return LDB_ERR_OPERATIONS_ERROR;
+       req_control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID);
+       paged_req_control = talloc_get_type(req_control->data, struct ldb_paged_control);
+
+       if (!rep_control || !paged_rep_control) {
+               if (paged_req_control->cookie) {
+                       /* something wrong here - why give us a control back befre, but not one now? */
+                       ldb_set_errstring(ldb, "paged_searches:  ERROR: We got back a control from a previous page, but this time no control was returned!");
+                       return LDB_ERR_OPERATIONS_ERROR;
+               } else {
+                       /* No cookie recived yet, valid to just return the full data set */
+
+                       /* we are done */
+                       ac->pending = false;
+                       return LDB_SUCCESS;
+               }
        }
 
-       rep_control = talloc_get_type(ares->controls[0]->data, struct ldb_paged_control);
-       if (rep_control->cookie_len == 0) {
+       if (paged_rep_control->cookie_len == 0) {
                /* we are done */
                ac->pending = false;
                return LDB_SUCCESS;
@@ -79,21 +97,14 @@ static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares
        /* if there's a reply control we must find a request
         * control matching it */
 
-       if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, req->controls[0]->oid) != 0) {
-               /* something wrong here */
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       req_control = talloc_get_type(req->controls[0]->data, struct ldb_paged_control);
-
-       if (req_control->cookie) {
-               talloc_free(req_control->cookie);
+       if (paged_req_control->cookie) {
+               talloc_free(paged_req_control->cookie);
        }
 
-       req_control->cookie = talloc_memdup(req_control,
-                                           rep_control->cookie,
-                                           rep_control->cookie_len);
-       req_control->cookie_len = rep_control->cookie_len;
+       paged_req_control->cookie = talloc_memdup(req_control,
+                                                 paged_rep_control->cookie,
+                                                 paged_rep_control->cookie_len);
+       paged_req_control->cookie_len = paged_rep_control->cookie_len;
 
        ac->pending = true;
        return LDB_SUCCESS;
@@ -141,8 +152,6 @@ static int send_referrals(struct ps_context *ac)
        return LDB_SUCCESS;
 }
 
-static int ps_next_request(struct ps_context *ac);
-
 static int ps_callback(struct ldb_request *req, struct ldb_reply *ares)
 {
        struct ps_context *ac;
@@ -176,14 +185,15 @@ static int ps_callback(struct ldb_request *req, struct ldb_reply *ares)
 
        case LDB_REPLY_DONE:
 
-               ret = check_ps_continuation(req, ares);
+               ret = check_ps_continuation(ac, req, ares);
                if (ret != LDB_SUCCESS) {
                        return ldb_module_done(ac->req, NULL, NULL, ret);
                }
 
                if (ac->pending) {
 
-                       ret = ps_next_request(ac);
+                       ret = ldb_next_request(ac->module, ac->down_req);
+
                        if (ret != LDB_SUCCESS) {
                                return ldb_module_done(ac->req,
                                                        NULL, NULL, ret);
@@ -214,14 +224,16 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req)
        struct ldb_context *ldb;
        struct private_data *private_data;
        struct ps_context *ac;
+       struct ldb_paged_control *control;
+       int ret;
 
        private_data = talloc_get_type(ldb_module_get_private(module), struct private_data);
        ldb = ldb_module_get_ctx(module);
 
-       /* check if paging is supported and if there is a any control */
-       if (!private_data || !private_data->paged_supported || req->controls) {
+       /* check if paging is supported */
+       if (!private_data || !private_data->paged_supported) {
                /* do not touch this request paged controls not
-                * supported or explicit controls have been set or we
+                * supported or we
                 * are just not setup yet */
                return ldb_next_request(module, req);
        }
@@ -238,30 +250,9 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req)
        ac->saved_referrals = NULL;
        ac->num_referrals = 0;
 
-       return ps_next_request(ac);
-}
-
-static int ps_next_request(struct ps_context *ac) {
-
-       struct ldb_context *ldb;
-       struct ldb_paged_control *control;
-       struct ldb_control **controls;
-       struct ldb_request *new_req;
-       int ret;
-
        ldb = ldb_module_get_ctx(ac->module);
 
-       controls = talloc_array(ac, struct ldb_control *, 2);
-       if (!controls) {
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       controls[0] = talloc(controls, struct ldb_control);
-       if (!controls[0]) {
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       control = talloc(controls[0], struct ldb_paged_control);
+       control = talloc(ac, struct ldb_paged_control);
        if (!control) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
@@ -270,26 +261,28 @@ static int ps_next_request(struct ps_context *ac) {
        control->cookie = NULL;
        control->cookie_len = 0;
 
-       controls[0]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
-       controls[0]->critical = 1;
-       controls[0]->data = control;
-       controls[1] = NULL;
-
-       ret = ldb_build_search_req_ex(&new_req, ldb, ac,
+       ret = ldb_build_search_req_ex(&ac->down_req, ldb, ac,
                                        ac->req->op.search.base,
                                        ac->req->op.search.scope,
                                        ac->req->op.search.tree,
                                        ac->req->op.search.attrs,
-                                       controls,
+                                       ac->req->controls,
                                        ac,
                                        ps_callback,
                                        ac->req);
        if (ret != LDB_SUCCESS) {
                return ret;
        }
-       talloc_steal(new_req, controls);
 
-       return ldb_next_request(ac->module, new_req);
+       ret = ldb_request_add_control(ac->down_req, LDB_CONTROL_PAGED_RESULTS_OID,
+                                     true, control);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+
+       talloc_steal(ac->down_req, control);
+
+       return ldb_next_request(ac->module, ac->down_req);
 }
 
 static int check_supported_paged(struct ldb_request *req,
index 81b960979f6b6f52e6fea28027634b0eeec1042e..7ff4bf4aad3dc9b43273f35797fc855867f9d92a 100644 (file)
@@ -469,19 +469,20 @@ static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
        return PyLdbDn_FromDn(dn);
 }
 
-static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list)
+static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, 
+                                                                               const char *paramname)
 {
        const char **ret;
        int i;
        if (!PyList_Check(list)) {
-               PyErr_SetString(PyExc_TypeError, "options is not a list");
+               PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
                return NULL;
        }
        ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
        for (i = 0; i < PyList_Size(list); i++) {
                PyObject *item = PyList_GetItem(list, i);
                if (!PyString_Check(item)) {
-                       PyErr_SetString(PyExc_TypeError, "options should be strings");
+                       PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
                        return NULL;
                }
                ret[i] = PyString_AsString(item);
@@ -510,7 +511,7 @@ static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
        if (py_options == Py_None) {
                options = NULL;
        } else {
-               options = PyList_AsStringList(ldb, py_options);
+               options = PyList_AsStringList(ldb, py_options, "options");
                if (options == NULL)
                        return -1;
        }
@@ -563,7 +564,7 @@ static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwa
        if (py_options == Py_None) {
                options = NULL;
        } else {
-               options = PyList_AsStringList(NULL, py_options);
+               options = PyList_AsStringList(NULL, py_options, "options");
                if (options == NULL)
                        return NULL;
        }
@@ -813,7 +814,7 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar
        if (py_attrs == Py_None) {
                attrs = NULL;
        } else {
-               attrs = PyList_AsStringList(ldb_ctx, py_attrs);
+               attrs = PyList_AsStringList(ldb_ctx, py_attrs, "attrs");
                if (attrs == NULL)
                        return NULL;
        }
@@ -828,7 +829,7 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar
        if (py_controls == Py_None) {
                parsed_controls = NULL;
        } else {
-               const char **controls = PyList_AsStringList(ldb_ctx, py_controls);
+               const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
                parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
                talloc_free(controls);
        }
@@ -1129,7 +1130,7 @@ static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, P
        mod = self->mod;
 
        ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base), 
-                            scope, NULL /* expr */, py_attrs == Py_None?NULL:PyList_AsStringList(req, py_attrs),
+                            scope, NULL /* expr */, py_attrs == Py_None?NULL:PyList_AsStringList(req, py_attrs, "attrs"),
                             NULL /* controls */, NULL, NULL, NULL);
        PyErr_LDB_ERROR_IS_ERR_RAISE(ret, mod->ldb);
 
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"""
 
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 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 8ea9727ed3bc2a92a3c92339ce642f4b65b0073a..d7db0580e97caaff8d2f360f0ee71849c29bf340 100644 (file)
@@ -21,6 +21,7 @@ mkinclude ../lib/nss_wrapper/config.mk
 mkinclude lib/stream/config.mk
 mkinclude ../lib/util/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
@@ -45,6 +46,7 @@ mkinclude torture/config.mk
 mkinclude librpc/config.mk
 mkinclude client/config.mk
 mkinclude libcli/config.mk
+mkinclude ../libcli/cldap/config.mk
 mkinclude scripting/python/config.mk
 mkinclude kdc/config.mk
 mkinclude ../lib/smbconf/config.mk
index 46f45a1bf33dd3633aef452df29a84e44a6fe84f..eaefbd5148f0df44f59027f3f179f5a7392ef1d7 100644 (file)
@@ -3,4 +3,4 @@
 TDB_MIN_VERSION=1.1.3
 TALLOC_MIN_VERSION=1.3.0
 LDB_REQUIRED_VERSION=0.9.3
-TEVENT_REQUIRED_VERSION=0.9.4
+TEVENT_REQUIRED_VERSION=0.9.5
index aea5d08c3f35f9104840f829d9219e1b782352cd..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;
        }
 
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 61c8009716b691bb2d81c4b0d8ff266d19ebd6ab..7d14c0e50288e95579aec66ad5038b00186d060f 100644 (file)
@@ -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);
 }
index 9b087c68bb259ab2166e24a75ab754d9a8d19040..edc1c47e4df84ae8985ba8dc86bec32c50e9b418 100755 (executable)
@@ -8,7 +8,7 @@ MANPAGES=$*
 
 for I in $MANPAGES
 do
-       SECTION=`echo -n $I | sed "s/.*\(.\)$/\1/"
+       SECTION=`echo -n $I | sed "s/.*\(.\)$/\1/"`
        FNAME=$MANDIR/man$SECTION/$I
        if test -f $FNAME; then
          echo Deleting $FNAME
diff --git a/source4/scripting/bin/fullschema b/source4/scripting/bin/fullschema
new file mode 100644 (file)
index 0000000..41c45f3
--- /dev/null
@@ -0,0 +1,179 @@
+#!/usr/bin/python
+# 
+#  work out the minimal schema for a set of objectclasses 
+#
+
+import base64
+import optparse
+import os
+import sys
+
+# Find right directory when running from source tree
+sys.path.insert(0, "bin/python")
+
+import samba
+from samba import getopt as options, Ldb
+from ldb import SCOPE_SUBTREE, SCOPE_BASE, LdbError
+import sys
+
+parser = optparse.OptionParser("fullschema <URL>")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+parser.add_option_group(options.VersionOptions(parser))
+parser.add_option("--dump-classes", action="store_true")
+parser.add_option("--dump-attributes", action="store_true")
+
+opts, args = parser.parse_args()
+opts.dump_all = True
+
+if opts.dump_classes:
+    opts.dump_all = False
+if opts.dump_attributes:
+    opts.dump_all = False
+if opts.dump_all:
+    opts.dump_classes = True
+    opts.dump_attributes = True
+
+if len(args) != 1:
+    parser.print_usage()
+    sys.exit(1)
+
+url = args[0]
+
+lp_ctx = sambaopts.get_loadparm()
+
+creds = credopts.get_credentials(lp_ctx)
+ldb = Ldb(url, credentials=creds, lp=lp_ctx, options=["modules:paged_searches"])
+
+# the attributes we need for objectclasses
+class_attrs = ["objectClass", 
+               "cn",
+               "subClassOf", 
+               "governsID", 
+               "possSuperiors", 
+               "possibleInferiors",
+               "mayContain",
+               "mustContain",
+               "auxiliaryClass",
+               "rDNAttID",
+               "adminDisplayName",
+               "adminDescription",
+               "objectClassCategory",
+               "lDAPDisplayName",
+               "schemaIDGUID",
+               "systemOnly",
+               "systemPossSuperiors",
+               "systemMayContain",
+               "systemMustContain",
+               "systemAuxiliaryClass",
+               "defaultSecurityDescriptor",
+               "systemFlags",
+               "defaultHidingValue",
+               "defaultObjectCategory", 
+               
+               # this attributes are not used by w2k3
+               "schemaFlagsEx",
+               "msDs-IntId",
+               "msDs-Schema-Extensions",
+               "classDisplayName",
+               "isDefunct"]
+
+attrib_attrs = ["objectClass",
+                "cn",
+                "attributeID", 
+                "attributeSyntax",
+                "isSingleValued",
+                "rangeLower",
+                "rangeUpper",
+                "mAPIID",
+                "linkID",
+                "adminDisplayName",
+                "oMObjectClass",
+                "adminDescription",
+                "oMSyntax", 
+                "searchFlags",
+                "extendedCharsAllowed",
+                "lDAPDisplayName",
+                "schemaIDGUID",
+                "attributeSecurityGUID",
+                "systemOnly",
+                "systemFlags",
+                "isMemberOfPartialAttributeSet",
+                
+                # this attributes are not used by w2k3
+                "schemaFlagsEx",
+                "msDs-IntId",
+                "msDs-Schema-Extensions",
+                "classDisplayName",
+                "isEphemeral",
+                "isDefunct"]
+
+class Objectclass(dict):
+
+    def __init__(self, ldb, name):
+        """create an objectclass object"""
+        self.name = name
+
+
+class Attribute(dict):
+
+    def __init__(self, ldb, name):
+        """create an attribute object"""
+        self.name = name
+        self["cn"] = get_object_cn(ldb, name)
+
+
+
+def fix_dn(dn):
+    """fix a string DN to use ${SCHEMADN}"""
+    return dn.replace(rootDse["schemaNamingContext"][0], "${SCHEMADN}")
+
+
+def write_ldif_one(o, attrs):
+    """dump an object as ldif"""
+    print "dn: CN=%s,${SCHEMADN}" % o["cn"]
+    for a in attrs:
+        if not o.has_key(a):
+            continue
+        # special case for oMObjectClass, which is a binary object
+        v = o[a]
+        for j in v:
+            value = fix_dn(j)
+            if a != "cn":
+                if a == "oMObjectClass":
+                    print "%s:: %s" % (a, base64.b64encode(value))
+                elif a.endswith("GUID"):
+                    print "%s: %s" % (a, ldb.schema_format_value(a, value))
+                else:
+                    print "%s: %s" % (a, value)
+    print ""
+
+
+# get the rootDSE
+res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
+rootDse = res[0]
+
+if opts.dump_attributes:
+    res = ldb.search(expression="objectClass=attributeSchema", 
+                     base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=attrib_attrs,
+                     controls=["server_sort:1:0:cn"])
+    
+    for msg in res:
+        o = Objectclass(ldb, msg["ldapDisplayName"])
+        for a in msg:
+            o[a] = msg[a]
+        write_ldif_one(o, attrib_attrs)
+            
+if opts.dump_classes:
+    res = ldb.search(expression="objectClass=classSchema", 
+                     base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=class_attrs,
+                     controls=["server_sort:1:0:cn"])
+
+    for msg in res:
+        o = Objectclass(ldb, msg["ldapDisplayName"])
+        for a in msg:
+            o[a] = msg[a]
+        write_ldif_one(o, class_attrs)
+
index e7d7ed497913e752ac267e482d4f0e0506fbef3d..c860495e96595ff1640cc4776d39b0f7564d37da 100755 (executable)
@@ -3,9 +3,10 @@
 #  work out the minimal schema for a set of objectclasses 
 #
 
+import base64
 import optparse
-
-import os, sys
+import os
+import sys
 
 # Find right directory when running from source tree
 sys.path.insert(0, "bin/python")
@@ -54,10 +55,10 @@ if len(args) != 2:
 lp_ctx = sambaopts.get_loadparm()
 
 creds = credopts.get_credentials(lp_ctx)
-ldb = Ldb(url, credentials=creds)
+ldb = Ldb(url, credentials=creds, lp=lp_ctx)
 
-objectclasses = []
-attributes = []
+objectclasses = {}
+attributes = {}
 
 objectclasses_expanded = set()
 
@@ -71,7 +72,6 @@ class_attrs = ["objectClass",
                "mustContain",
                "auxiliaryClass",
                "rDNAttID",
-               "showInAdvancedViewOnly",
                "adminDisplayName",
                "adminDescription",
                "objectClassCategory",
@@ -103,7 +103,6 @@ attrib_attrs = ["objectClass",
                 "rangeUpper",
                 "mAPIID",
                 "linkID",
-                "showInAdvancedViewOnly",
                 "adminDisplayName",
                 "oMObjectClass",
                 "adminDescription",
@@ -136,24 +135,25 @@ attrib_attrs = ["objectClass",
 
 def get_object_cn(ldb, name):
     attrs = ["cn"]
-
-    res = ldb.search("(ldapDisplayName=%s)" % name, rootDse["schemaNamingContext"], SCOPE_SUBTREE, attrs)
+    res = ldb.search(expression="(ldapDisplayName=%s)" % name, base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, attrs=attrs)
     assert len(res) == 1
-
     return res[0]["cn"]
 
-class Objectclass:
+
+class Objectclass(dict):
+
     def __init__(self, ldb, name):
         """create an objectclass object"""
         self.name = name
-        self.cn = get_object_cn(ldb, name)
+        self["cn"] = get_object_cn(ldb, name)
+
 
+class Attribute(dict):
 
-class Attribute:
     def __init__(self, ldb, name):
         """create an attribute object"""
         self.name = name
-        self.cn = get_object_cn(ldb, name)
+        self["cn"] = get_object_cn(ldb, name)
 
 
 syntaxmap = dict()
@@ -180,36 +180,38 @@ syntaxmap['2.5.5.17'] = '1.3.6.1.4.1.1466.115.121.1.40'
 def map_attribute_syntax(s):
     """map some attribute syntaxes from some apparently MS specific
     syntaxes to the standard syntaxes"""
-    if syntaxmap.has_key(s):
+    if s in list(syntaxmap):
         return syntaxmap[s]
     return s
 
 
 def fix_dn(dn):
     """fix a string DN to use ${SCHEMADN}"""
-    return dn.replace(rootDse["schemaNamingContext"], "${SCHEMADN}")
+    return dn.replace(rootDse["schemaNamingContext"][0], "${SCHEMADN}")
 
 
 def write_ldif_one(o, attrs):
     """dump an object as ldif"""
-    print "dn: CN=%s,${SCHEMADN}\n" % o["cn"]
+    print "dn: CN=%s,${SCHEMADN}" % o["cn"]
     for a in attrs:
         if not o.has_key(a):
             continue
         # special case for oMObjectClass, which is a binary object
-        if a == "oMObjectClass":
-            print "%s:: %s\n" % (a, o[a])
-            continue
         v = o[a]
-        if isinstance(v, str):
-            v = [v]
         for j in v:
-            print "%s: %s\n" % (a, fix_dn(j))
-    print "\n"
+                       value = fix_dn(j)
+                       if a == "oMObjectClass":
+                               print "%s:: %s" % (a, base64.b64encode(value))
+                       elif a.endswith("GUID"):
+                               print "%s: %s" % (a, ldb.schema_format_value(a, value))
+                       else:
+                               print "%s: %s" % (a, value)
+    print ""
+
 
 def write_ldif(o, attrs):
     """dump an array of objects as ldif"""
-    for i in o:
+    for n, i in o.items():
         write_ldif_one(i, attrs)
 
 
@@ -225,7 +227,7 @@ def find_objectclass_properties(ldb, o):
     """the properties of an objectclass"""
     res = ldb.search(
         expression="(ldapDisplayName=%s)" % o.name,
-        base=rootDse["schemaNamingContext"], scope=SCOPE_SUBTREE, attrs=class_attrs)
+        base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, attrs=class_attrs)
     assert(len(res) == 1)
     msg = res[0]
     for a in msg:
@@ -235,15 +237,11 @@ def find_attribute_properties(ldb, o):
     """find the properties of an attribute"""
     res = ldb.search(
         expression="(ldapDisplayName=%s)" % o.name,
-        base=rootDse["schemaNamingContext"], scope=SCOPE_SUBTREE, 
+        base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, 
         attrs=attrib_attrs)
     assert(len(res) == 1)
     msg = res[0]
     for a in msg:
-        # special case for oMObjectClass, which is a binary object
-        if a == "oMObjectClass":
-            o[a] = ldb.encode(msg[a])
-            continue
         o[a] = msg[a]
 
 
@@ -254,15 +252,15 @@ def find_objectclass_auto(ldb, o):
         return
     testdn = create_testdn(o.exampleDN)
 
-    print "testdn is '%s'\n" % testdn
+    print "testdn is '%s'" % testdn
 
     ldif = "dn: " + testdn
     ldif += "\nobjectClass: " + o.name
     try:
         ldb.add(ldif)
     except LdbError, e:
-        print "error adding %s: %s\n" % (o.name, e)
-        print "%s\n" % ldif
+        print "error adding %s: %s" % (o.name, e)
+        print "%s" % ldif
         return
 
     res = ldb.search(base=testdn, scope=ldb.SCOPE_BASE)
@@ -280,20 +278,20 @@ def expand_objectclass(ldb, o):
                   "subClassOf"]
     res = ldb.search(
         expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % o.name,
-        base=rootDse["schemaNamingContext"], scope=SCOPE_SUBTREE, 
+        base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, 
         attrs=attrs)
-    print "Expanding class %s\n" % o.name
+    print >>sys.stderr, "Expanding class %s" % o.name
     assert(len(res) == 1)
     msg = res[0]
-    for a in attrs:
-        if not msg.has_key(aname):
+    for aname in attrs:
+        if not aname in msg:
             continue
         list = msg[aname]
         if isinstance(list, str):
             list = [msg[aname]]
         for name in list:
             if not objectclasses.has_key(name):
-                print "Found new objectclass '%s'\n" % name
+                print >>sys.stderr, "Found new objectclass '%s'" % name
                 objectclasses[name] = Objectclass(ldb, name)
 
 
@@ -320,13 +318,13 @@ def walk_dn(ldb, dn):
     try:
         res = ldb.search("objectClass=*", dn, SCOPE_BASE, attrs)
     except LdbError, e:
-        print "Unable to fetch allowedAttributes for '%s' - %r\n" % (dn, e)
+        print >>sys.stderr, "Unable to fetch allowedAttributes for '%s' - %r" % (dn, e)
         return
     allattrs = res[0]["allowedAttributes"]
     try:
         res = ldb.search("objectClass=*", dn, SCOPE_BASE, allattrs)
     except LdbError, e:
-        print "Unable to fetch all attributes for '%s' - %s\n" % (dn, e)
+        print >>sys.stderr, "Unable to fetch all attributes for '%s' - %s" % (dn, e)
         return
     msg = res[0]
     for a in msg:
@@ -339,7 +337,7 @@ def walk_naming_context(ldb, namingContext):
         res = ldb.search("objectClass=*", namingContext, SCOPE_DEFAULT, 
                          ["objectClass"])
     except LdbError, e:
-        print "Unable to fetch objectClasses for '%s' - %s\n" % (namingContext, e)
+        print >>sys.stderr, "Unable to fetch objectClasses for '%s' - %s" % (namingContext, e)
         return
     for msg in res:
         msg = res.msgs[r]["objectClass"]
@@ -356,12 +354,9 @@ def trim_objectclass_attributes(ldb, objectclass):
     if objectclass.has_key("possibleInferiors"):
         possinf = objectclass["possibleInferiors"]
         newpossinf = []
-        if isinstance(possinf, str):
-            possinf = [possinf]
         for x in possinf:
             if objectclasses.has_key(x):
-                newpossinf[n] = x
-                n+=1
+                newpossinf.append(x)
         objectclass["possibleInferiors"] = newpossinf
 
     # trim systemMayContain,
@@ -369,8 +364,6 @@ def trim_objectclass_attributes(ldb, objectclass):
     if objectclass.has_key("systemMayContain"):
         sysmay = objectclass["systemMayContain"]
         newsysmay = []
-        if isinstance(sysmay, str):
-            sysmay = [sysmay]
         for x in sysmay:
             if not x in newsysmay:
                 newsysmay.append(x)
@@ -378,7 +371,7 @@ def trim_objectclass_attributes(ldb, objectclass):
 
     # trim mayContain,
     # remove duplicates
-    if not objectclass.has_key("mayContain"):
+    if objectclass.has_key("mayContain"):
         may = objectclass["mayContain"]
         newmay = []
         if isinstance(may, str):
@@ -388,71 +381,65 @@ def trim_objectclass_attributes(ldb, objectclass):
                 newmay.append(x)
         objectclass["mayContain"] = newmay
 
+
 def build_objectclass(ldb, name):
     """load the basic attributes of an objectClass"""
     attrs = ["name"]
-    try:
-        res = ldb.search(
-            expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % name,
-            base=rootDse["schemaNamingContext"], scope=SCOPE_SUBTREE, 
-            attrs=attrs)
-    except LdbError, e:
-        print "unknown class '%s'\n" % name
-        return None
+    res = ldb.search(
+        expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % name,
+        base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, 
+        attrs=attrs)
     if len(res) == 0:
-        print "unknown class '%s'\n" % name
+        print >>sys.stderr, "unknown class '%s'" % name
         return None
     return Objectclass(ldb, name)
 
+
 def attribute_list(objectclass, attr1, attr2):
     """form a coalesced attribute list"""
-    a1 = objectclass[attr1]
-    a2 = objectclass[attr2]
-    if isinstance(a1, str):
-        a1 = [a1]
-    if isinstance(a2, str):
-        a2 = [a2]
+    a1 = list(objectclass.get(attr1, []))
+    a2 = list(objectclass.get(attr2, []))
     return a1 + a2
 
 def aggregate_list(name, list):
     """write out a list in aggregate form"""
-    if list is None:
-        return
-    print "%s ( %s )" % (name, "$ ".join(list))
+    if list == []:
+        return ""
+    return " %s ( %s )" % (name, " $ ".join(list))
 
 def write_aggregate_objectclass(objectclass):
     """write the aggregate record for an objectclass"""
-    print "objectClasses: ( %s NAME '%s' " % (objectclass.governsID, objectclass.name)
+    line = "objectClasses: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name)
     if not objectclass.has_key('subClassOf'):
-        print "SUP %s " % objectclass['subClassOf']
-    if objectclass.objectClassCategory == 1:
-        print "STRUCTURAL "
-    elif objectclass.objectClassCategory == 2:
-        print "ABSTRACT "
-    elif objectclass.objectClassCategory == 3:
-        print "AUXILIARY "
+        line += "SUP %s" % objectclass['subClassOf']
+    if objectclass["objectClassCategory"] == 1:
+        line += "STRUCTURAL"
+    elif objectclass["objectClassCategory"] == 2:
+        line += "ABSTRACT"
+    elif objectclass["objectClassCategory"] == 3:
+        line += "AUXILIARY"
 
     list = attribute_list(objectclass, "systemMustContain", "mustContain")
-    aggregate_list("MUST", list)
+    line += aggregate_list("MUST", list)
 
     list = attribute_list(objectclass, "systemMayContain", "mayContain")
-    aggregate_list("MAY", list)
+    line += aggregate_list("MAY", list)
 
-    print ")\n"
+    print line + " )"
 
 
 def write_aggregate_ditcontentrule(objectclass):
     """write the aggregate record for an ditcontentrule"""
     list = attribute_list(objectclass, "auxiliaryClass", "systemAuxiliaryClass")
-    if list is None:
+    if list == []:
         return
 
-    print "dITContentRules: ( %s NAME '%s' " % (objectclass.governsID, objectclass.name)
+    line = "dITContentRules: ( %s NAME '%s'" % (objectclass["governsID"], objectclass.name)
 
-    aggregate_list("AUX", list)
+    line += aggregate_list("AUX", list)
 
-    may_list = None
-    must_list = None
+    may_list = []
+    must_list = []
 
     for c in list:
         list2 = attribute_list(objectclasses[c], 
@@ -462,44 +449,43 @@ def write_aggregate_ditcontentrule(objectclass):
                        "mustContain", "systemMustContain")
         must_list = must_list + list2
 
-    aggregate_list("MUST", must_list)
-    aggregate_list("MAY", may_list)
+    line += aggregate_list("MUST", must_list)
+    line += aggregate_list("MAY", may_list)
 
-    print ")\n"
+    print line + " )"
 
 def write_aggregate_attribute(attrib):
     """write the aggregate record for an attribute"""
-    print "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % (
-           attrib.attributeID, attrib.name, 
-           map_attribute_syntax(attrib.attributeSyntax))
-    if attrib['isSingleValued'] == "TRUE":
-        print "SINGLE-VALUE "
-    if attrib['systemOnly'] == "TRUE":
-        print "NO-USER-MODIFICATION "
+    line = "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % (
+           attrib["attributeID"], attrib.name, 
+           map_attribute_syntax(attrib["attributeSyntax"]))
+    if attrib.get('isSingleValued') == "TRUE":
+        line += "SINGLE-VALUE "
+    if attrib.get('systemOnly') == "TRUE":
+        line += "NO-USER-MODIFICATION "
 
-    print ")\n"
+    print line + ")"
 
 
 def write_aggregate():
     """write the aggregate record"""
-    print "dn: CN=Aggregate,${SCHEMADN}\n"
+    print "dn: CN=Aggregate,${SCHEMADN}"
     print """objectClass: top
 objectClass: subSchema
-objectCategory: CN=SubSchema,${SCHEMADN}
-"""
+objectCategory: CN=SubSchema,${SCHEMADN}"""
     if not opts.dump_subschema_auto:
         return
 
-    for objectclass in objectclasses:
+    for objectclass in objectclasses.values():
         write_aggregate_objectclass(objectclass)
-    for attr in attributes:
+    for attr in attributes.values():
         write_aggregate_attribute(attr)
-    for objectclass in objectclasses:
+    for objectclass in objectclasses.values():
         write_aggregate_ditcontentrule(objectclass)
 
 def load_list(file):
     """load a list from a file"""
-    return open(file, 'r').readlines()
+    return [l.strip("\n") for l in open(file, 'r').readlines()]
 
 # get the rootDSE
 res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
@@ -523,32 +509,32 @@ expanded = 0
 # than necessary to recursively expand all classes
 #
 for inf in range(500):
-    for n in objectclasses:
+    for n, o in objectclasses.items():
         if not n in objectclasses_expanded:
-            expand_objectclass(ldb, objectclasses[i])
+            expand_objectclass(ldb, o)
             objectclasses_expanded.add(n)
 
 #
 #  find objectclass properties
 #
-for objectclass in objectclasses:
+for name, objectclass in objectclasses.items():
     find_objectclass_properties(ldb, objectclass)
 
 
 #
 #  form the full list of attributes
 #
-for objectclass in objectclasses:
+for name, objectclass in objectclasses.items():
     add_objectclass_attributes(ldb, objectclass)
 
 # and attribute properties
-for attr in attributes:
+for name, attr in attributes.items():
     find_attribute_properties(ldb, attr)
 
 #
 # trim the 'may' attribute lists to those really needed
 #
-for objectclass in objectclasses:
+for name, objectclass in objectclasses.items():
     trim_objectclass_attributes(ldb, objectclass)
 
 #
index a49e6e1eadb7460476b7cc2bb5838465574c473f..c5827b96e0e134843a9739a64a240b9e2f12afc8 100644 (file)
@@ -54,7 +54,7 @@ class Ldb(ldb.Ldb):
     functions see samdb.py.
     """
     def __init__(self, url=None, session_info=None, credentials=None, 
-                 modules_dir=None, lp=None):
+                 modules_dir=None, lp=None, options=None):
         """Open a Samba Ldb file. 
 
         :param url: Optional LDB URL to open
@@ -67,7 +67,7 @@ class Ldb(ldb.Ldb):
         modules-dir is used by default and that credentials and session_info 
         can be passed through (required by some modules).
         """
-        super(Ldb, self).__init__()
+        super(Ldb, self).__init__(options=options)
 
         if modules_dir is not None:
             self.set_modules_dir(modules_dir)
@@ -90,7 +90,7 @@ class Ldb(ldb.Ldb):
         #self.set_debug(msg)
 
         if url is not None:
-            self.connect(url)
+            self.connect(url, options=options)
 
     def set_credentials(self, credentials):
         glue.ldb_set_credentials(self, credentials)
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 ae2cb808360d93f3ee065496a524805ce4400eda..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_netlogon_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 {
@@ -58,10 +62,13 @@ static bool bench_cldap_netlogon(struct torture_context *tctx, const char *addre
        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;
@@ -72,11 +79,11 @@ static bool bench_cldap_netlogon(struct torture_context *tctx, const char *addre
        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_netlogon_handler;
                        num_sent++;
                        if (num_sent % 50 == 0) {
                                if (torture_setting_bool(tctx, "progress", true)) {
@@ -88,11 +95,11 @@ static bool bench_cldap_netlogon(struct torture_context *tctx, const char *addre
                        }
                }
 
-               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,13 +110,14 @@ static bool bench_cldap_netlogon(struct torture_context *tctx, const char *addre
        return ret;
 }
 
-static void request_rootdse_handler(struct cldap_request *req)
+static void request_rootdse_handler(struct tevent_req *req)
 {
        struct cldap_search 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);
        status = cldap_search_recv(req, tmp_ctx, &io);
+       talloc_free(req);
        if (NT_STATUS_IS_OK(status)) {
                state->pass_count++;
        } else {
@@ -130,8 +138,10 @@ static bool bench_cldap_rootdse(struct torture_context *tctx, const char *addres
        int timelimit = torture_setting_int(tctx, "timelimit", 10);
        struct cldap_search 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);
 
@@ -145,11 +155,11 @@ static bool bench_cldap_rootdse(struct torture_context *tctx, const char *addres
        printf("Running CLDAP/rootdse for %d seconds\n", timelimit);
        while (timeval_elapsed(&tv) < timelimit) {
                while (num_sent - (state->pass_count+state->fail_count) < 10) {
-                       struct cldap_request *req;
-                       req = cldap_search_send(cldap, &search);
+                       struct tevent_req *req;
+                       req = cldap_search_send(state, cldap, &search);
+
+                       tevent_req_set_callback(req, request_rootdse_handler, state);
 
-                       req->async.private_data = state;
-                       req->async.fn = request_rootdse_handler;
                        num_sent++;
                        if (num_sent % 50 == 0) {
                                if (torture_setting_bool(tctx, "progress", true)) {
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 f8029b246b99b56bc11540fdd765187b62c316c8..2bdcc3fdaf7eff71b9f03019ad421275803ce3de 100644 (file)
@@ -1337,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");
 
@@ -1370,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;
@@ -1417,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");
 
@@ -1435,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);
 
@@ -1460,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;
 
@@ -1468,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");
 
@@ -1475,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);
 
@@ -1515,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");
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 add06522c615402bbda8f0570213409c37151602..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.");
        }
@@ -364,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");
@@ -387,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;
 }
@@ -403,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;
 
@@ -413,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.");
@@ -456,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);
 
@@ -531,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;