[Pkg-samba-maint] r3863 - in branches/samba/experimental: . auth docs/manpages docs-xml/manpages-3 docs-xml/smbdotconf/misc examples/VFS lib/util libcli/auth libcli/ldap libcli/nbt libcli/smbreadline libds/common librpc/ndr nsswitch packaging/RHEL packaging/RHEL-CTDB release-scripts source3 source3/auth source3/client source3/groupdb source3/include source3/intl source3/lib source3/lib/eventlog source3/lib/netapi source3/libads source3/libgpo source3/libnet source3/librpc/gen_ndr source3/librpc/idl source3/librpc/ndr source3/libsmb source3/locking source3/m4 source3/modules source3/nmbd source3/param source3/passdb source3/printing source3/registry source3/rpc_client source3/rpc_server source3/rpc_server/spoolss source3/rpc_server/srvsvc source3/rpc_server/svcctl source3/script source3/script/tests source3/smbd source3/utils source3/web source3/winbindd

bubulle at alioth.debian.org bubulle at alioth.debian.org
Thu Jul 28 16:06:17 UTC 2011


Author: bubulle
Date: 2011-07-28 16:06:15 +0000 (Thu, 28 Jul 2011)
New Revision: 3863

Added:
   branches/samba/experimental/source3/printing/nt_printing_migrate_internal.c
   branches/samba/experimental/source3/printing/nt_printing_migrate_internal.h
   branches/samba/experimental/source3/printing/nt_printing_os2.c
   branches/samba/experimental/source3/printing/nt_printing_os2.h
   branches/samba/experimental/source3/rpc_client/cli_winreg_spoolss.c
   branches/samba/experimental/source3/rpc_client/cli_winreg_spoolss.h
Removed:
   branches/samba/experimental/WHATSNEW4.txt
   branches/samba/experimental/docs-xml/manpages-3/ldb.3.xml
   branches/samba/experimental/docs-xml/manpages-3/ldbadd.1.xml
   branches/samba/experimental/docs-xml/manpages-3/ldbdel.1.xml
   branches/samba/experimental/docs-xml/manpages-3/ldbedit.1.xml
   branches/samba/experimental/docs-xml/manpages-3/ldbmodify.1.xml
   branches/samba/experimental/docs-xml/manpages-3/ldbrename.1.xml
   branches/samba/experimental/docs-xml/manpages-3/ldbsearch.1.xml
   branches/samba/experimental/howto-ol-backend-s4.txt
   branches/samba/experimental/howto4.txt
   branches/samba/experimental/prog_guide4.txt
   branches/samba/experimental/upgrading-samba4.txt
Modified:
   branches/samba/experimental/WHATSNEW.txt
   branches/samba/experimental/auth/auth_sam_reply.h
   branches/samba/experimental/docs-xml/manpages-3/idmap_autorid.8.xml
   branches/samba/experimental/docs-xml/manpages-3/net.8.xml
   branches/samba/experimental/docs-xml/smbdotconf/misc/timeoffset.xml
   branches/samba/experimental/docs/manpages/eventlogadm.8
   branches/samba/experimental/docs/manpages/findsmb.1
   branches/samba/experimental/docs/manpages/idmap_ad.8
   branches/samba/experimental/docs/manpages/idmap_adex.8
   branches/samba/experimental/docs/manpages/idmap_autorid.8
   branches/samba/experimental/docs/manpages/idmap_hash.8
   branches/samba/experimental/docs/manpages/idmap_ldap.8
   branches/samba/experimental/docs/manpages/idmap_nss.8
   branches/samba/experimental/docs/manpages/idmap_rid.8
   branches/samba/experimental/docs/manpages/idmap_tdb.8
   branches/samba/experimental/docs/manpages/idmap_tdb2.8
   branches/samba/experimental/docs/manpages/libsmbclient.7
   branches/samba/experimental/docs/manpages/lmhosts.5
   branches/samba/experimental/docs/manpages/log2pcap.1
   branches/samba/experimental/docs/manpages/net.8
   branches/samba/experimental/docs/manpages/nmbd.8
   branches/samba/experimental/docs/manpages/nmblookup.1
   branches/samba/experimental/docs/manpages/ntlm_auth.1
   branches/samba/experimental/docs/manpages/pam_winbind.8
   branches/samba/experimental/docs/manpages/pam_winbind.conf.5
   branches/samba/experimental/docs/manpages/pdbedit.8
   branches/samba/experimental/docs/manpages/profiles.1
   branches/samba/experimental/docs/manpages/rpcclient.1
   branches/samba/experimental/docs/manpages/samba.7
   branches/samba/experimental/docs/manpages/sharesec.1
   branches/samba/experimental/docs/manpages/smb.conf.5
   branches/samba/experimental/docs/manpages/smbcacls.1
   branches/samba/experimental/docs/manpages/smbclient.1
   branches/samba/experimental/docs/manpages/smbcontrol.1
   branches/samba/experimental/docs/manpages/smbcquotas.1
   branches/samba/experimental/docs/manpages/smbd.8
   branches/samba/experimental/docs/manpages/smbget.1
   branches/samba/experimental/docs/manpages/smbgetrc.5
   branches/samba/experimental/docs/manpages/smbpasswd.5
   branches/samba/experimental/docs/manpages/smbpasswd.8
   branches/samba/experimental/docs/manpages/smbspool.8
   branches/samba/experimental/docs/manpages/smbstatus.1
   branches/samba/experimental/docs/manpages/smbta-util.8
   branches/samba/experimental/docs/manpages/smbtar.1
   branches/samba/experimental/docs/manpages/smbtree.1
   branches/samba/experimental/docs/manpages/swat.8
   branches/samba/experimental/docs/manpages/tdbbackup.8
   branches/samba/experimental/docs/manpages/tdbdump.8
   branches/samba/experimental/docs/manpages/tdbtool.8
   branches/samba/experimental/docs/manpages/testparm.1
   branches/samba/experimental/docs/manpages/vfs_acl_tdb.8
   branches/samba/experimental/docs/manpages/vfs_acl_xattr.8
   branches/samba/experimental/docs/manpages/vfs_audit.8
   branches/samba/experimental/docs/manpages/vfs_cacheprime.8
   branches/samba/experimental/docs/manpages/vfs_cap.8
   branches/samba/experimental/docs/manpages/vfs_catia.8
   branches/samba/experimental/docs/manpages/vfs_commit.8
   branches/samba/experimental/docs/manpages/vfs_crossrename.8
   branches/samba/experimental/docs/manpages/vfs_default_quota.8
   branches/samba/experimental/docs/manpages/vfs_dirsort.8
   branches/samba/experimental/docs/manpages/vfs_extd_audit.8
   branches/samba/experimental/docs/manpages/vfs_fake_perms.8
   branches/samba/experimental/docs/manpages/vfs_fileid.8
   branches/samba/experimental/docs/manpages/vfs_full_audit.8
   branches/samba/experimental/docs/manpages/vfs_gpfs.8
   branches/samba/experimental/docs/manpages/vfs_netatalk.8
   branches/samba/experimental/docs/manpages/vfs_notify_fam.8
   branches/samba/experimental/docs/manpages/vfs_prealloc.8
   branches/samba/experimental/docs/manpages/vfs_preopen.8
   branches/samba/experimental/docs/manpages/vfs_readahead.8
   branches/samba/experimental/docs/manpages/vfs_readonly.8
   branches/samba/experimental/docs/manpages/vfs_recycle.8
   branches/samba/experimental/docs/manpages/vfs_scannedonly.8
   branches/samba/experimental/docs/manpages/vfs_shadow_copy.8
   branches/samba/experimental/docs/manpages/vfs_shadow_copy2.8
   branches/samba/experimental/docs/manpages/vfs_smb_traffic_analyzer.8
   branches/samba/experimental/docs/manpages/vfs_streams_depot.8
   branches/samba/experimental/docs/manpages/vfs_streams_xattr.8
   branches/samba/experimental/docs/manpages/vfs_time_audit.8
   branches/samba/experimental/docs/manpages/vfs_xattr_tdb.8
   branches/samba/experimental/docs/manpages/vfstest.1
   branches/samba/experimental/docs/manpages/wbinfo.1
   branches/samba/experimental/docs/manpages/winbind_krb5_locator.7
   branches/samba/experimental/docs/manpages/winbindd.8
   branches/samba/experimental/examples/VFS/shadow_copy_test.c
   branches/samba/experimental/examples/VFS/skel_opaque.c
   branches/samba/experimental/examples/VFS/skel_transparent.c
   branches/samba/experimental/lib/util/data_blob.h
   branches/samba/experimental/lib/util/time.h
   branches/samba/experimental/lib/util/util_ldb.h
   branches/samba/experimental/lib/util/util_tdb.h
   branches/samba/experimental/lib/util/wrap_xattr.h
   branches/samba/experimental/libcli/auth/msrpc_parse.h
   branches/samba/experimental/libcli/ldap/ldap_ndr.h
   branches/samba/experimental/libcli/nbt/nbt_proto.h
   branches/samba/experimental/libcli/smbreadline/smbreadline.h
   branches/samba/experimental/libds/common/flag_mapping.h
   branches/samba/experimental/librpc/ndr/ndr_backupkey.h
   branches/samba/experimental/librpc/ndr/ndr_compression.h
   branches/samba/experimental/librpc/ndr/ndr_dns.h
   branches/samba/experimental/librpc/ndr/ndr_spoolss_buf.h
   branches/samba/experimental/librpc/ndr/ndr_table.h
   branches/samba/experimental/nsswitch/pam_winbind.h
   branches/samba/experimental/nsswitch/winbind_client.h
   branches/samba/experimental/packaging/RHEL-CTDB/samba.spec
   branches/samba/experimental/packaging/RHEL/makerpms.sh
   branches/samba/experimental/packaging/RHEL/samba.spec
   branches/samba/experimental/release-scripts/create-tarball
   branches/samba/experimental/source3/Makefile.in
   branches/samba/experimental/source3/VERSION
   branches/samba/experimental/source3/auth/auth_server.c
   branches/samba/experimental/source3/auth/pass_check.c
   branches/samba/experimental/source3/auth/proto.h
   branches/samba/experimental/source3/client/clitar.c
   branches/samba/experimental/source3/configure
   branches/samba/experimental/source3/groupdb/proto.h
   branches/samba/experimental/source3/include/async_smb.h
   branches/samba/experimental/source3/include/krb5_env.h
   branches/samba/experimental/source3/include/krb5_protos.h
   branches/samba/experimental/source3/include/mangle.h
   branches/samba/experimental/source3/include/nt_printing.h
   branches/samba/experimental/source3/include/proto.h
   branches/samba/experimental/source3/include/smb.h
   branches/samba/experimental/source3/include/smb_krb5.h
   branches/samba/experimental/source3/include/smb_ldap.h
   branches/samba/experimental/source3/include/version.h
   branches/samba/experimental/source3/intl/lang_tdb.h
   branches/samba/experimental/source3/lib/afs.c
   branches/samba/experimental/source3/lib/afs_settoken.c
   branches/samba/experimental/source3/lib/charcnv.c
   branches/samba/experimental/source3/lib/eventlog/proto.h
   branches/samba/experimental/source3/lib/idmap_cache.h
   branches/samba/experimental/source3/lib/ms_fnmatch.c
   branches/samba/experimental/source3/lib/netapi/libnetapi.h
   branches/samba/experimental/source3/lib/privileges.h
   branches/samba/experimental/source3/lib/sharesec.c
   branches/samba/experimental/source3/lib/smbldap.c
   branches/samba/experimental/source3/lib/username.c
   branches/samba/experimental/source3/lib/util_str.c
   branches/samba/experimental/source3/lib/util_unistr.c
   branches/samba/experimental/source3/libads/ads_ldap_protos.h
   branches/samba/experimental/source3/libads/ads_proto.h
   branches/samba/experimental/source3/libads/ads_status.h
   branches/samba/experimental/source3/libads/cldap.h
   branches/samba/experimental/source3/libads/kerberos_proto.h
   branches/samba/experimental/source3/libads/ldap_schema.h
   branches/samba/experimental/source3/libgpo/gpo_proto.h
   branches/samba/experimental/source3/libnet/libnet_join.h
   branches/samba/experimental/source3/librpc/gen_ndr/ndr_wbint.c
   branches/samba/experimental/source3/librpc/gen_ndr/ndr_wbint_c.c
   branches/samba/experimental/source3/librpc/gen_ndr/ndr_wbint_c.h
   branches/samba/experimental/source3/librpc/gen_ndr/wbint.h
   branches/samba/experimental/source3/librpc/idl/wbint.idl
   branches/samba/experimental/source3/librpc/ndr/util.h
   branches/samba/experimental/source3/libsmb/async_smb.c
   branches/samba/experimental/source3/libsmb/cli_np_tstream.c
   branches/samba/experimental/source3/libsmb/clidgram.h
   branches/samba/experimental/source3/libsmb/clireadwrite.c
   branches/samba/experimental/source3/libsmb/clitrans.c
   branches/samba/experimental/source3/libsmb/errormap_wbc.h
   branches/samba/experimental/source3/libsmb/libsmb.h
   branches/samba/experimental/source3/libsmb/nmblib.h
   branches/samba/experimental/source3/libsmb/proto.h
   branches/samba/experimental/source3/libsmb/unexpected.c
   branches/samba/experimental/source3/locking/brlock.c
   branches/samba/experimental/source3/locking/proto.h
   branches/samba/experimental/source3/m4/check_path.m4
   branches/samba/experimental/source3/modules/vfs_acl_common.c
   branches/samba/experimental/source3/modules/vfs_afsacl.c
   branches/samba/experimental/source3/modules/vfs_commit.c
   branches/samba/experimental/source3/modules/vfs_time_audit.c
   branches/samba/experimental/source3/nmbd/nmbd.h
   branches/samba/experimental/source3/nmbd/nmbd_proto.h
   branches/samba/experimental/source3/nmbd/nmbd_subnetdb.c
   branches/samba/experimental/source3/param/loadparm.c
   branches/samba/experimental/source3/passdb/machine_sid.h
   branches/samba/experimental/source3/passdb/passdb.c
   branches/samba/experimental/source3/passdb/proto.h
   branches/samba/experimental/source3/printing/load.h
   branches/samba/experimental/source3/printing/nt_printing.c
   branches/samba/experimental/source3/printing/nt_printing_ads.c
   branches/samba/experimental/source3/printing/nt_printing_migrate.c
   branches/samba/experimental/source3/printing/nt_printing_migrate.h
   branches/samba/experimental/source3/printing/pcap.h
   branches/samba/experimental/source3/printing/spoolssd.c
   branches/samba/experimental/source3/registry/reg_parse_internal.c
   branches/samba/experimental/source3/registry/reg_parse_internal.h
   branches/samba/experimental/source3/rpc_client/cli_netlogon.h
   branches/samba/experimental/source3/rpc_client/cli_spoolss.h
   branches/samba/experimental/source3/rpc_client/cli_winreg.c
   branches/samba/experimental/source3/rpc_client/init_lsa.h
   branches/samba/experimental/source3/rpc_client/init_netlogon.h
   branches/samba/experimental/source3/rpc_client/init_samr.h
   branches/samba/experimental/source3/rpc_client/init_spoolss.c
   branches/samba/experimental/source3/rpc_client/init_spoolss.h
   branches/samba/experimental/source3/rpc_client/util_netlogon.h
   branches/samba/experimental/source3/rpc_server/dcesrv_gssapi.c
   branches/samba/experimental/source3/rpc_server/rpc_ep_setup.c
   branches/samba/experimental/source3/rpc_server/spoolss/srv_spoolss_nt.c
   branches/samba/experimental/source3/rpc_server/spoolss/srv_spoolss_util.c
   branches/samba/experimental/source3/rpc_server/spoolss/srv_spoolss_util.h
   branches/samba/experimental/source3/rpc_server/srv_access_check.h
   branches/samba/experimental/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
   branches/samba/experimental/source3/rpc_server/svcctl/srv_svcctl_nt.c
   branches/samba/experimental/source3/rpc_server/wscript_build
   branches/samba/experimental/source3/script/mkbuildoptions.awk
   branches/samba/experimental/source3/script/tests/test_net_registry_roundtrip.sh
   branches/samba/experimental/source3/script/tests/test_smbclient_s3.sh
   branches/samba/experimental/source3/script/tests/test_wbinfo_sids2xids_int.py
   branches/samba/experimental/source3/smbd/fake_file.c
   branches/samba/experimental/source3/smbd/file_access.c
   branches/samba/experimental/source3/smbd/globals.h
   branches/samba/experimental/source3/smbd/mangle_hash.c
   branches/samba/experimental/source3/smbd/mangle_hash2.c
   branches/samba/experimental/source3/smbd/msdfs.c
   branches/samba/experimental/source3/smbd/open.c
   branches/samba/experimental/source3/smbd/process.c
   branches/samba/experimental/source3/smbd/proto.h
   branches/samba/experimental/source3/smbd/quotas.c
   branches/samba/experimental/source3/smbd/reply.c
   branches/samba/experimental/source3/smbd/server.c
   branches/samba/experimental/source3/smbd/server_exit.c
   branches/samba/experimental/source3/smbd/service.c
   branches/samba/experimental/source3/smbd/smb2_create.c
   branches/samba/experimental/source3/smbd/smb2_ioctl.c
   branches/samba/experimental/source3/smbd/smb2_read.c
   branches/samba/experimental/source3/smbd/smb2_server.c
   branches/samba/experimental/source3/smbd/smb2_tcon.c
   branches/samba/experimental/source3/smbd/uid.c
   branches/samba/experimental/source3/utils/net_afs.c
   branches/samba/experimental/source3/utils/net_cache.c
   branches/samba/experimental/source3/utils/net_conf.c
   branches/samba/experimental/source3/utils/net_printing.c
   branches/samba/experimental/source3/utils/net_registry.c
   branches/samba/experimental/source3/utils/net_rpc_registry.c
   branches/samba/experimental/source3/web/cgi.c
   branches/samba/experimental/source3/web/statuspage.c
   branches/samba/experimental/source3/web/swat.c
   branches/samba/experimental/source3/web/swat_proto.h
   branches/samba/experimental/source3/winbindd/idmap_autorid.c
   branches/samba/experimental/source3/winbindd/idmap_proto.h
   branches/samba/experimental/source3/winbindd/wb_lookupsids.c
   branches/samba/experimental/source3/winbindd/winbindd_dual_srv.c
   branches/samba/experimental/source3/winbindd/winbindd_lookuprids.c
   branches/samba/experimental/source3/winbindd/winbindd_pam.c
   branches/samba/experimental/source3/winbindd/winbindd_sids_to_xids.c
   branches/samba/experimental/source3/wscript_build
Log:
Merge upstream 3.6.0rc3

Modified: branches/samba/experimental/WHATSNEW.txt
===================================================================
--- branches/samba/experimental/WHATSNEW.txt	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/WHATSNEW.txt	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,10 +1,10 @@
                    ================================
-                   Release Notes for Samba 3.6.0rc2
-                            June 7, 2011
+                   Release Notes for Samba 3.6.0rc3
+                            July , 2011
                    ================================
 
 
-This is the second release candidate of Samba 3.6.0.  This is *not*
+This is the third release candidate of Samba 3.6.0.  This is *not*
 intended for production environments and is designed for testing
 purposes only.  Please report any defects via the Samba bug reporting
 system at https://bugzilla.samba.org/.
@@ -30,15 +30,16 @@
 set '--option=clientusentlmv2auth=no' on your smbclient command line, or
 set 'client ntlmv2 auth = no' in your smb.conf
 
-The impact of 'client use spnego principal = no' is that we may be able
-to use Kerberos to communicate with a server less often in smbclient,
-winbind and other Samba client tools.  We may fall back to NTLMSSP in
-more situations where we would previously rely on the insecure
-indication from the 'NegProt' CIFS packet.  This mostly occursed when
-connecting to a name alias not recorded as a servicePrincipalName for
-the server.  This indication is not available from Windows 2008 or later
-in any case, and is not used by modern Windows clients, so this makes
-Samba's behaviour consistent with other clients and against all servers.
+The impact of 'client use spnego principal = no' is that Samba will
+use CIFS/hostname to obtain a kerberos ticket, acting more like
+Windows when using Kerberos against a CIFS server in smbclient,
+winbind and other Samba client tools.  This will change which servers
+we will successfully negotiate kerberos connections to.  This is due
+to Samba no longer trusting a server-provided hint which is not
+available from Windows 2008 or later.  For correct operation with all
+clients, all aliases for a server should be recorded as a as a
+servicePrincipalName on the server's record in AD.  (For this reason,
+this behavior change and parameter was also made in Samba 3.5.9)
 
 The impact of 'send spnego principal = no' is to match Windows 2008 and
 not to send this principal, making existing clients give more consistent
@@ -252,10 +253,98 @@
     * Add an Endpoint Mapper daemon.
 
 
-Changes since 3.6.0rc1
+Changes since 3.6.0rc2
 ----------------------
 
 o   Michael Adam <obnox at samba.org>
+    * BUG 8213: Fixes in idmap_autorid.
+    * BUG 8217: Do not stat-check the share path in 'net conf addshare'.
+    * BUG 8281: Fix build of examples/VFS/*.
+
+
+o   Jeremy Allison <jra at samba.org>
+    * BUG 8083: Fix "inherit owner = yes" with vfs_acl_xattr or vfs_acl_tdb
+      module.
+    * BUG 8211: Fix "inherit owner = yes" when "inherit permissions = yes"
+      is set.
+    * BUG 8219: Fix SMB Panic from Windows 7 client.
+    * BUG 8254: Fix "acl check permissions = no".
+    * BUG 8293: Fix log file rotating in SMB2.
+    * BUG 8304: Fix uninitialized variable in error path.
+    * BUG 8307: brl_close_fnum does not call SMB_VFS_BRL_UNLOCK_WINDOWS on all
+      locks.
+    * BUG 8310: toupper_ascii() is broken on big-endian systems.
+    * BUG 8314: Fix smbd crash with unknown user.
+
+
+o   Christian Ambach <ambi at samba.org>
+    * BUG 8231: Fix crash bug in 'net cache get'.
+    * BUG 8244: Fix copying files larger than 2 GB to a Samba share.
+    * BUG 8263: Fix build with --with-fake-kaserver or --with-vfs-afsacl.
+    * BUG 8278: Fix smbd panic when CTDB is unhealthy.
+    * BUG 8286: Fix smbd crash on premature end of smb2 conn.
+
+
+o   Andrew Bartlett <abartlet at samba.org>
+    * BUG 8230: Move .nmbd socket directory to non-hidden name PREFIX/var/nmbd.
+    * Mark 'time offset' parameter as deprecated.
+
+
+o   Gregor Beck <gbeck at sernet.de>
+    * BUG 8193: Add new command 'enumerate_recursive'.
+    * BUG 8253: Fix Winbind panic if verify_idpool() fails.
+
+
+o   Kai Blin <kai at samba.org>
+    * BUG 8289: Fix possible XSS attack (CVE-2011-2694).
+    * BUG 8290: Fix Cross-Site Request Forgery in SWAT (CVE-2011-2522).
+
+
+o   Günther Deschner <gd at samba.org>
+    * BUG 7888: Deal with buggy 3.0 based PDCs.
+    * BUG 8214: Fix smbd crash on printer driver upgrade.
+    * BUG 8235: Fix smbd crash on startup caused by migrate_printer().
+
+
+o   Björn Jacke <bj at sernet.de>
+    * BUG 8262: Fix build of vfs_commit.
+
+
+o   Günter Kukkukk <linux at kukkukk.com>
+    * BUG 8305: Fix segfault in nmbd when using 'smbtree ...'..
+
+
+o   Volker Lendecke <vl at samba.org>
+    * BUG 7841: Explicitly pass domain_sid to wbint_LookupRids().
+    * BUG 8102: Do not allow to change file ACLs from normal domusers.
+    * BUG 8247: Fix Coverity ID 2582: FORWARD_NULL.
+
+
+o   Herb Lewis <hlewis at panasas.com>
+    * BUG 8216: Make Winbind returning correct results with 'sids2xids'.
+
+
+o   Stefan Metzmacher <metze at samba.org>
+    * BUG 8102: Do not allow to change file ACLs from normal domusers.
+    * BUG 8195: Make rpc client code working against NT4 servers.
+    * BUG 8224: Fix the build on FreeBSD.
+    * BUG 8226: Use c99 initializers which are supported by old gcc 2.95
+      compilers.
+    * BUG 8260: Fix DCERPC responses with fragments larger than 1024 bytes.
+    * BUG 8264: Fix Valgrind bugs in svcctl.
+    * BUG 8276: Close all sockets attached to a subnet in close_subnet().
+    * BUG 8292: Fix a major architectural flaw in the SMB2 server code.
+
+
+o   Andreas Schneider <asn at samba.org>
+    * BUG 8215: Fix Winbind unix username lookup.
+    * BUG 8240: Fix Valgrind warnings in winreg/spoolss code.
+
+
+Changee since 3.6.0rc1
+----------------------
+
+o   Michael Adam <obnox at samba.org>
     * BUG 8200: Add support for multiple writeable ldap idmap domains.
 
 

Deleted: branches/samba/experimental/WHATSNEW4.txt
===================================================================
--- branches/samba/experimental/WHATSNEW4.txt	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/WHATSNEW4.txt	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,141 +0,0 @@
-What's new in Samba 4 alpha14
-=============================
-
-Samba 4 is the ambitious next version of the Samba suite that is being
-developed in parallel to the stable 3.x series. The main emphasis in
-this branch is support for the Active Directory logon protocols used
-by Windows 2000 and above.
-
-Samba4 alpha14 follows on from the alpha release series we have been
-publishing since September 2007.
-
-WARNINGS
-========
-
-Samba4 alpha14 is not a final Samba release.  That is more a reference
-to Samba4's lack of the features we expect you will need than a
-statement of code quality, but clearly it hasn't seen a broad
-deployment yet.  If you were to upgrade Samba3 (or indeed Windows) to
-Samba4, you would find many things work, but that other key features
-you may have relied on simply are not there yet.
-
-For example, while Samba 3 is an excellent member of a Active
-Directory domain, Samba4 is happier as a domain controller, and it is
-in this role where it has seen deployment into production.
-
-Samba4 is subjected to an awesome battery of tests on an
-automated basis, we have found Samba4 to be very stable in it's
-behaviour.  We have to recommend against upgrading production servers
-from Samba 3 to Samba 4 at this stage, because there may be the features on
-which you may rely that are not present, or the mapping of
-your configuration and user database may not be complete.
-
-If you are upgrading, or looking to develop, test or deploy Samba4, you should
-backup all configuration and data.
-
-NEW FEATURES
-============
-
-Samba4 supports the server-side of the Active Directory logon environment
-used by Windows 2000 and later, so we can do full domain join
-and domain logon operations with these clients.
-
-Our Domain Controller (DC) implementation includes our own built-in
-LDAP server and Kerberos Key Distribution Center (KDC) as well as the
-Samba3-like logon services provided over CIFS.  We correctly generate
-the infamous Kerberos PAC, and include it with the Kerberos tickets we
-issue.
-
-The new VFS features in Samba 4 adapts the filesystem on the server to
-match the Windows client semantics, allowing Samba 4 to better match
-windows behaviour and application expectations.  This includes file
-annotation information (in streams) and NT ACLs in particular.  The
-VFS is backed with an extensive automated test suite.
-
-A new scripting interface has been added to Samba 4, allowing
-Python programs to interface to Samba's internals.
-
-The Samba 4 architecture is based around an LDAP-like database that
-can use a range of modular backends.  One of the backends supports
-standards compliant LDAP servers (including OpenLDAP), and we are
-working on modules to map between AD-like behaviours and this backend.
-We are aiming for Samba 4 to be powerful frontend to large
-directories.
-
-CHANGES SINCE alpha13
-=====================
-
-We have continued our commitment to provide a full DRS implementation for our
-AD implementation and therefore achieved also this time big steps forward.
-
-Our progress on DRS is being tracked in the Samba wiki:
-http://wiki.samba.org/index.php/Samba4_DRS_TODO_List
-
-Beside this the release includes (among a lot of other things):
-
-* a script for backuping production provision
-Although still in development, samba4 is already used in a couple of production sites
-and such kind of use case is intensifying. This script is intendended for administrators
-to allow them to make a periodic backup of the provision in case of problem.
-
-* the 'net' command has been renamed to 'samba-tool'
-
-CHANGES
-=======
-
-Those familiar with Samba 3 can find a list of user-visible changes
-since that release series in the NEWS file.
-
-KNOWN ISSUES
-============
-
-- Domain member support is in it's infancy, and is not comparable to
-  the support found in Samba3.
-
-- There is no printing support in the current release.
-
-- There is no NetBIOS browsing support in the current release
-
-- The Samba4 port of the CTDB clustering support is not yet complete
-
-- Clock Synchronisation is critical.  Many 'wrong password' errors are
-  actually due to Kerberos objecting to a clock skew between client
-  and server.  (The NTP work in the previous alphas are partly to assist
-  with this problem).
-
-- The DRS replication code fails, and is very new
-
-- Users upgrading existing databases to Samba4 should carefully
-  consult upgrading-samba4.txt.  We have made a number of changes in
-  this release that should make it easier to upgrade in future.
-  Btw: there exists also a script under the "setup" directory of the
-  source distribution called "upgrade_from_s3" which should allow a step-up
-  from Samba3 to Samba4. It's not included yet in the binary distributions
-  since it's completely experimental!
-
-RUNNING Samba4
-==============
-
-A short guide to setting up Samba 4 can be found on the wiki:
-
-  http://wiki.samba.org/index.php/Samba4/HOWTO
-
-DEVELOPMENT and FEEDBACK
-========================
-
-We need your help! Projects as Samba 4 live from the community feedback. If you
-provide expressive bug reports, some documentation snippets on the wiki or some
-real code patches - all is appreciated if it meets our quality criterias. Here
-you can find further references:
-
-Bugs can be filed at https://bugzilla.samba.org/ but please be aware
-that many features are simply not expected to work at this stage.
-
-The Samba Wiki at http://wiki.samba.org should detail some of these
-development plans.
-
-Development and general discussion about Samba 4 happens mainly on
-the #samba-technical IRC channel (on irc.freenode.net) and
-the samba-technical mailing list (see http://lists.samba.org/ for
-details).
-

Modified: branches/samba/experimental/auth/auth_sam_reply.h
===================================================================
--- branches/samba/experimental/auth/auth_sam_reply.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/auth/auth_sam_reply.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Convert a server info struct into the form for PAC and NETLOGON replies
+
+   Copyright (C) Andrew Bartlett <abartlet at samba.org> 2004
+   Copyright (C) Stefan Metzmacher <metze at samba.org>  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/>.
+*/
+
 #ifndef __AUTH_AUTH_SAM_REPLY_H__
 #define __AUTH_AUTH_SAM_REPLY_H__
 

Modified: branches/samba/experimental/docs/manpages/eventlogadm.8
===================================================================
--- branches/samba/experimental/docs/manpages/eventlogadm.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/eventlogadm.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: eventlogadm
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "EVENTLOGADM" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "EVENTLOGADM" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/findsmb.1
===================================================================
--- branches/samba/experimental/docs/manpages/findsmb.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/findsmb.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: findsmb
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "FINDSMB" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "FINDSMB" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/idmap_ad.8
===================================================================
--- branches/samba/experimental/docs/manpages/idmap_ad.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/idmap_ad.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: idmap_ad
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "IDMAP_AD" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "IDMAP_AD" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/idmap_adex.8
===================================================================
--- branches/samba/experimental/docs/manpages/idmap_adex.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/idmap_adex.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: idmap_adex
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "IDMAP_ADEX" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "IDMAP_ADEX" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/idmap_autorid.8
===================================================================
--- branches/samba/experimental/docs/manpages/idmap_autorid.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/idmap_autorid.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: idmap_autorid
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "IDMAP_AUTORID" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "IDMAP_AUTORID" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -100,7 +100,7 @@
 
 	idmap config * : backend = autorid
 	idmap config * : range = 1000000\-19999999
-	autorid:rangesize = 1000000
+	idmap config * : rangesize = 1000000
 
 	idmap config TRUSTED : backend  = ad
 	idmap config TRUSTED : range    = 50000 \- 99999

Modified: branches/samba/experimental/docs/manpages/idmap_hash.8
===================================================================
--- branches/samba/experimental/docs/manpages/idmap_hash.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/idmap_hash.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: idmap_hash
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "IDMAP_HASH" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "IDMAP_HASH" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/idmap_ldap.8
===================================================================
--- branches/samba/experimental/docs/manpages/idmap_ldap.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/idmap_ldap.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: idmap_ldap
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "IDMAP_LDAP" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "IDMAP_LDAP" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/idmap_nss.8
===================================================================
--- branches/samba/experimental/docs/manpages/idmap_nss.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/idmap_nss.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: idmap_nss
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "IDMAP_NSS" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "IDMAP_NSS" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/idmap_rid.8
===================================================================
--- branches/samba/experimental/docs/manpages/idmap_rid.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/idmap_rid.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: idmap_rid
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "IDMAP_RID" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "IDMAP_RID" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/idmap_tdb.8
===================================================================
--- branches/samba/experimental/docs/manpages/idmap_tdb.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/idmap_tdb.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: idmap_tdb
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "IDMAP_TDB" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "IDMAP_TDB" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/idmap_tdb2.8
===================================================================
--- branches/samba/experimental/docs/manpages/idmap_tdb2.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/idmap_tdb2.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: idmap_tdb2
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "IDMAP_TDB2" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "IDMAP_TDB2" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/libsmbclient.7
===================================================================
--- branches/samba/experimental/docs/manpages/libsmbclient.7	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/libsmbclient.7	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: libsmbclient
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: 7
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "LIBSMBCLIENT" "7" "06/07/2011" "Samba 3\&.6" "7"
+.TH "LIBSMBCLIENT" "7" "07/26/2011" "Samba 3\&.6" "7"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/lmhosts.5
===================================================================
--- branches/samba/experimental/docs/manpages/lmhosts.5	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/lmhosts.5	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: lmhosts
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: File Formats and Conventions
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "LMHOSTS" "5" "06/07/2011" "Samba 3\&.6" "File Formats and Conventions"
+.TH "LMHOSTS" "5" "07/26/2011" "Samba 3\&.6" "File Formats and Conventions"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/log2pcap.1
===================================================================
--- branches/samba/experimental/docs/manpages/log2pcap.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/log2pcap.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: log2pcap
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "LOG2PCAP" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "LOG2PCAP" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/net.8
===================================================================
--- branches/samba/experimental/docs/manpages/net.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/net.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: net
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "NET" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "NET" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -1101,12 +1101,18 @@
 net registry enumerate   \- Enumerate registry keys and values\&.
 .RE
 .RS 4
+net registry enumerate_recursive \- Enumerate registry key and its subkeys\&.
+.RE
+.RS 4
 net registry createkey   \- Create a new registry key\&.
 .RE
 .RS 4
 net registry deletekey   \- Delete a registry key\&.
 .RE
 .RS 4
+net registry deletekey_recursive \- Delete a registry key with subkeys\&.
+.RE
+.RS 4
 net registry getvalue    \- Print a registry value\&.
 .RE
 .RS 4
@@ -1143,7 +1149,12 @@
 .SS "REGISTRY ENUMERATE key "
 .PP
 Enumerate subkeys and values of
+\fIkey\fR\&.
+.SS "REGISTRY ENUMERATE_RECURSIVE key "
+.PP
+Enumerate values of
 \fIkey\fR
+and its subkeys\&.
 .SS "REGISTRY CREATEKEY key "
 .PP
 Create a new
@@ -1153,6 +1164,11 @@
 .PP
 Delete the given
 \fIkey\fR
+and its values from the registry, if it has no subkeys\&.
+.SS "REGISTRY DELETEKEY_RECURSIVE key "
+.PP
+Delete the given
+\fIkey\fR
 and all of its subkeys and values from the registry\&.
 .SS "REGISTRY GETVALUE key name"
 .PP

Modified: branches/samba/experimental/docs/manpages/nmbd.8
===================================================================
--- branches/samba/experimental/docs/manpages/nmbd.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/nmbd.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: nmbd
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "NMBD" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "NMBD" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/nmblookup.1
===================================================================
--- branches/samba/experimental/docs/manpages/nmblookup.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/nmblookup.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: nmblookup
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "NMBLOOKUP" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "NMBLOOKUP" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/ntlm_auth.1
===================================================================
--- branches/samba/experimental/docs/manpages/ntlm_auth.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/ntlm_auth.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: ntlm_auth
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "NTLM_AUTH" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "NTLM_AUTH" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/pam_winbind.8
===================================================================
--- branches/samba/experimental/docs/manpages/pam_winbind.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/pam_winbind.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: pam_winbind
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: 8
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "PAM_WINBIND" "8" "06/07/2011" "Samba 3\&.6" "8"
+.TH "PAM_WINBIND" "8" "07/26/2011" "Samba 3\&.6" "8"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/pam_winbind.conf.5
===================================================================
--- branches/samba/experimental/docs/manpages/pam_winbind.conf.5	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/pam_winbind.conf.5	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: pam_winbind.conf
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: 5
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "PAM_WINBIND\&.CONF" "5" "06/07/2011" "Samba 3\&.6" "5"
+.TH "PAM_WINBIND\&.CONF" "5" "07/26/2011" "Samba 3\&.6" "5"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/pdbedit.8
===================================================================
--- branches/samba/experimental/docs/manpages/pdbedit.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/pdbedit.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: pdbedit
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "PDBEDIT" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "PDBEDIT" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/profiles.1
===================================================================
--- branches/samba/experimental/docs/manpages/profiles.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/profiles.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: profiles
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "PROFILES" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "PROFILES" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/rpcclient.1
===================================================================
--- branches/samba/experimental/docs/manpages/rpcclient.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/rpcclient.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: rpcclient
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "RPCCLIENT" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "RPCCLIENT" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/samba.7
===================================================================
--- branches/samba/experimental/docs/manpages/samba.7	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/samba.7	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: samba
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: Miscellanea
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SAMBA" "7" "06/07/2011" "Samba 3\&.6" "Miscellanea"
+.TH "SAMBA" "7" "07/26/2011" "Samba 3\&.6" "Miscellanea"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/sharesec.1
===================================================================
--- branches/samba/experimental/docs/manpages/sharesec.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/sharesec.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: sharesec
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SHARESEC" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "SHARESEC" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smb.conf.5
===================================================================
--- branches/samba/experimental/docs/manpages/smb.conf.5	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smb.conf.5	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smb.conf
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: File Formats and Conventions
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMB\&.CONF" "5" "06/07/2011" "Samba 3\&.6" "File Formats and Conventions"
+.TH "SMB\&.CONF" "5" "07/26/2011" "Samba 3\&.6" "File Formats and Conventions"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -9744,8 +9744,22 @@
 .\" time offset
 .PP
 .RS 4
-This parameter is a setting in minutes to add to the normal GMT to local time conversion\&. This is useful if you are serving a lot of PCs that have incorrect daylight saving time handling\&.
+This deprecated parameter is a setting in minutes to add to the normal GMT to local time conversion\&. This is useful if you are serving a lot of PCs that have incorrect daylight saving time handling\&.
+.if n \{\
 .sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This option is deprecated, and will be removed in the next major release
+.sp .5v
+.RE
 Default:
 \fI\fItime offset\fR\fR\fI = \fR\fI0\fR\fI \fR
 .sp

Modified: branches/samba/experimental/docs/manpages/smbcacls.1
===================================================================
--- branches/samba/experimental/docs/manpages/smbcacls.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbcacls.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbcacls
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBCACLS" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "SMBCACLS" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbclient.1
===================================================================
--- branches/samba/experimental/docs/manpages/smbclient.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbclient.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbclient
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBCLIENT" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "SMBCLIENT" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbcontrol.1
===================================================================
--- branches/samba/experimental/docs/manpages/smbcontrol.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbcontrol.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbcontrol
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBCONTROL" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "SMBCONTROL" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbcquotas.1
===================================================================
--- branches/samba/experimental/docs/manpages/smbcquotas.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbcquotas.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbcquotas
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBCQUOTAS" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "SMBCQUOTAS" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbd.8
===================================================================
--- branches/samba/experimental/docs/manpages/smbd.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbd.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbd
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBD" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "SMBD" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbget.1
===================================================================
--- branches/samba/experimental/docs/manpages/smbget.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbget.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbget
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBGET" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "SMBGET" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbgetrc.5
===================================================================
--- branches/samba/experimental/docs/manpages/smbgetrc.5	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbgetrc.5	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbgetrc
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: File Formats and Conventions
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBGETRC" "5" "06/07/2011" "Samba 3\&.6" "File Formats and Conventions"
+.TH "SMBGETRC" "5" "07/26/2011" "Samba 3\&.6" "File Formats and Conventions"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbpasswd.5
===================================================================
--- branches/samba/experimental/docs/manpages/smbpasswd.5	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbpasswd.5	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbpasswd
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: File Formats and Conventions
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBPASSWD" "5" "06/07/2011" "Samba 3\&.6" "File Formats and Conventions"
+.TH "SMBPASSWD" "5" "07/26/2011" "Samba 3\&.6" "File Formats and Conventions"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbpasswd.8
===================================================================
--- branches/samba/experimental/docs/manpages/smbpasswd.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbpasswd.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbpasswd
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBPASSWD" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "SMBPASSWD" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbspool.8
===================================================================
--- branches/samba/experimental/docs/manpages/smbspool.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbspool.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbspool
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBSPOOL" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "SMBSPOOL" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbstatus.1
===================================================================
--- branches/samba/experimental/docs/manpages/smbstatus.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbstatus.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbstatus
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBSTATUS" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "SMBSTATUS" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbta-util.8
===================================================================
--- branches/samba/experimental/docs/manpages/smbta-util.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbta-util.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbta-util
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBTA\-UTIL" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "SMBTA\-UTIL" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbtar.1
===================================================================
--- branches/samba/experimental/docs/manpages/smbtar.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbtar.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbtar
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBTAR" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "SMBTAR" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/smbtree.1
===================================================================
--- branches/samba/experimental/docs/manpages/smbtree.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/smbtree.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smbtree
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMBTREE" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "SMBTREE" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/swat.8
===================================================================
--- branches/samba/experimental/docs/manpages/swat.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/swat.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: swat
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SWAT" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "SWAT" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/tdbbackup.8
===================================================================
--- branches/samba/experimental/docs/manpages/tdbbackup.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/tdbbackup.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: tdbbackup
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "TDBBACKUP" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "TDBBACKUP" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/tdbdump.8
===================================================================
--- branches/samba/experimental/docs/manpages/tdbdump.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/tdbdump.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: tdbdump
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "TDBDUMP" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "TDBDUMP" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/tdbtool.8
===================================================================
--- branches/samba/experimental/docs/manpages/tdbtool.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/tdbtool.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: tdbtool
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "TDBTOOL" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "TDBTOOL" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/testparm.1
===================================================================
--- branches/samba/experimental/docs/manpages/testparm.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/testparm.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: testparm
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "TESTPARM" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "TESTPARM" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_acl_tdb.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_acl_tdb.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_acl_tdb.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_acl_tdb
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_ACL_TDB" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_ACL_TDB" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_acl_xattr.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_acl_xattr.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_acl_xattr.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_acl_xattr
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_ACL_XATTR" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_ACL_XATTR" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_audit.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_audit.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_audit.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_audit
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_AUDIT" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_AUDIT" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_cacheprime.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_cacheprime.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_cacheprime.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_cacheprime
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_CACHEPRIME" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_CACHEPRIME" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_cap.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_cap.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_cap.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_cap
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_CAP" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_CAP" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_catia.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_catia.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_catia.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_catia
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_CATIA" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_CATIA" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_commit.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_commit.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_commit.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_commit
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_COMMIT" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_COMMIT" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_crossrename.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_crossrename.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_crossrename.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_crossrename
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_CROSSRENAME" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_CROSSRENAME" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_default_quota.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_default_quota.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_default_quota.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_default_quota
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_DEFAULT_QUOTA" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_DEFAULT_QUOTA" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_dirsort.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_dirsort.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_dirsort.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_dirsort
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_DIRSORT" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_DIRSORT" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_extd_audit.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_extd_audit.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_extd_audit.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_extd_audit
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_EXTD_AUDIT" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_EXTD_AUDIT" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_fake_perms.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_fake_perms.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_fake_perms.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_fake_perms
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_FAKE_PERMS" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_FAKE_PERMS" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_fileid.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_fileid.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_fileid.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_fileid
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_FILEID" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_FILEID" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_full_audit.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_full_audit.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_full_audit.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_full_audit
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_FULL_AUDIT" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_FULL_AUDIT" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_gpfs.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_gpfs.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_gpfs.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_gpfs
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_GPFS" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_GPFS" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_netatalk.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_netatalk.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_netatalk.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_netatalk
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_NETATALK" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_NETATALK" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_notify_fam.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_notify_fam.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_notify_fam.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_notify_fam
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_NOTIFY_FAM" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_NOTIFY_FAM" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_prealloc.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_prealloc.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_prealloc.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_prealloc
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_PREALLOC" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_PREALLOC" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_preopen.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_preopen.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_preopen.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_preopen
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_PREOPEN" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_PREOPEN" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_readahead.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_readahead.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_readahead.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_readahead
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_READAHEAD" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_READAHEAD" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_readonly.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_readonly.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_readonly.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_readonly
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_READONLY" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_READONLY" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_recycle.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_recycle.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_recycle.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_recycle
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_RECYCLE" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_RECYCLE" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_scannedonly.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_scannedonly.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_scannedonly.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_scannedonly
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_SCANNEDONLY" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_SCANNEDONLY" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_shadow_copy.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_shadow_copy.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_shadow_copy.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_shadow_copy
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_SHADOW_COPY" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_SHADOW_COPY" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_shadow_copy2.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_shadow_copy2.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_shadow_copy2.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_shadow_copy2
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_SHADOW_COPY2" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_SHADOW_COPY2" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_smb_traffic_analyzer.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_smb_traffic_analyzer.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_smb_traffic_analyzer.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: smb_traffic_analyzer
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "SMB_TRAFFIC_ANALYZER" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "SMB_TRAFFIC_ANALYZER" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_streams_depot.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_streams_depot.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_streams_depot.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_streams_depot
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_STREAMS_DEPOT" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_STREAMS_DEPOT" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_streams_xattr.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_streams_xattr.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_streams_xattr.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_streams_xattr
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_STREAMS_XATTR" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_STREAMS_XATTR" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_time_audit.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_time_audit.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_time_audit.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_time_audit
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_TIME_AUDIT" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_TIME_AUDIT" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfs_xattr_tdb.8
===================================================================
--- branches/samba/experimental/docs/manpages/vfs_xattr_tdb.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfs_xattr_tdb.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfs_xattr_tdb
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFS_XATTR_TDB" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "VFS_XATTR_TDB" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/vfstest.1
===================================================================
--- branches/samba/experimental/docs/manpages/vfstest.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/vfstest.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: vfstest
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "VFSTEST" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "VFSTEST" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/wbinfo.1
===================================================================
--- branches/samba/experimental/docs/manpages/wbinfo.1	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/wbinfo.1	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: wbinfo
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: User Commands
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "WBINFO" "1" "06/07/2011" "Samba 3\&.6" "User Commands"
+.TH "WBINFO" "1" "07/26/2011" "Samba 3\&.6" "User Commands"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/winbind_krb5_locator.7
===================================================================
--- branches/samba/experimental/docs/manpages/winbind_krb5_locator.7	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/winbind_krb5_locator.7	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: winbind_krb5_locator
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: 7
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "WINBIND_KRB5_LOCATOR" "7" "06/07/2011" "Samba 3\&.6" "7"
+.TH "WINBIND_KRB5_LOCATOR" "7" "07/26/2011" "Samba 3\&.6" "7"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs/manpages/winbindd.8
===================================================================
--- branches/samba/experimental/docs/manpages/winbindd.8	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs/manpages/winbindd.8	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,12 +2,12 @@
 .\"     Title: winbindd
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 06/07/2011
+.\"      Date: 07/26/2011
 .\"    Manual: System Administration tools
 .\"    Source: Samba 3.6
 .\"  Language: English
 .\"
-.TH "WINBINDD" "8" "06/07/2011" "Samba 3\&.6" "System Administration tools"
+.TH "WINBINDD" "8" "07/26/2011" "Samba 3\&.6" "System Administration tools"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------

Modified: branches/samba/experimental/docs-xml/manpages-3/idmap_autorid.8.xml
===================================================================
--- branches/samba/experimental/docs-xml/manpages-3/idmap_autorid.8.xml	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs-xml/manpages-3/idmap_autorid.8.xml	2011-07-28 16:06:15 UTC (rev 3863)
@@ -109,7 +109,7 @@
 
 	idmap config * : backend = autorid
 	idmap config * : range = 1000000-19999999
-	autorid:rangesize = 1000000
+	idmap config * : rangesize = 1000000
 
 	idmap config TRUSTED : backend  = ad
 	idmap config TRUSTED : range    = 50000 - 99999

Deleted: branches/samba/experimental/docs-xml/manpages-3/ldb.3.xml
===================================================================
--- branches/samba/experimental/docs-xml/manpages-3/ldb.3.xml	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs-xml/manpages-3/ldb.3.xml	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,265 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-<refentry id="ldb.3">
-
-<refmeta>
-	<refentrytitle>ldb</refentrytitle>
-	<manvolnum>3</manvolnum>
-	<refmiscinfo class="source">Samba</refmiscinfo>
-	<refmiscinfo class="manual">C Library Functions</refmiscinfo>
-	<refmiscinfo class="version">3.6</refmiscinfo>
-</refmeta>
-
-<refnamediv>
-	<refname>ldb</refname>
-	<refclass>The Samba Project</refclass>
-	<refpurpose>A light-weight database library</refpurpose>
-</refnamediv>
-
-<refsynopsisdiv>
-	<synopsis>#include <ldb.h></synopsis>
-</refsynopsisdiv>
-
-<refsect1>
-	<title>description</title>
-
-	<para>
-ldb is a light weight embedded database library and API. With a
-programming interface that is very similar to LDAP, ldb can store its
-data either in a tdb(3) database or in a real LDAP database.
-	</para>
-
-	<para>
-When used with the tdb backend ldb does not require any database
-daemon. Instead, ldb function calls are processed immediately by the
-ldb library, which does IO directly on the database, while allowing
-multiple readers/writers using operating system byte range locks. This
-leads to an API with very low overheads, often resulting in speeds of
-more than 10x what can be achieved with a more traditional LDAP
-architecture.
-	</para>
-
-	<para>
-In a taxonomy of databases ldb would sit half way between key/value
-pair databases (such as berkley db or tdb) and a full LDAP
-database. With a structured attribute oriented API like LDAP and good
-indexing capabilities, ldb can be used for quite sophisticated
-applications that need a light weight database, without the
-administrative overhead of a full LDAP installation.
-	</para>
-
-	<para>
-Included with ldb are a number of useful command line tools for
-manipulating a ldb database. These tools are similar in style to the
-equivalent ldap command line tools.
-	</para>
-
-	<para>
-In its default mode of operation with a tdb backend, ldb can also be
-seen as a "schema-less LDAP". By default ldb does not require a
-schema, which greatly reduces the complexity of getting started with
-ldb databases. As the complexity of you application grows you can take
-advantage of some of the optional schema-like attributes that ldb
-offers, or you can migrate to using the full LDAP api while keeping
-your exiting ldb code.
-	</para>
-
-	<para>
-If you are new to ldb, then I suggest starting with the manual pages
-for ldbsearch(1) and ldbedit(1), and experimenting with a local
-database. Then I suggest you look at the ldb_connect(3) and
-ldb_search(3) manual pages.
-	</para>
-</refsect1>
-
-<refsect1>
-	<title>TOOLS</title>
-
-	<itemizedlist>
-		<listitem><para>
-			<application>ldbsearch(1)</application>
-			  - command line ldb search utility
-		</para></listitem>
-
-		<listitem><para>
-			<application>ldbedit(1)</application>
-			 - edit all or part of a ldb database using your favourite editor
-		</para></listitem>
-
-		<listitem><para>
-			<application>ldbadd(1)</application>
-			 - add records to a ldb database using LDIF formatted input
-		</para></listitem>
-
-		<listitem><para>
-			<application>ldbdel(1)</application>
-			 - delete records from a ldb database
-		</para></listitem>
-
-		<listitem><para>
-			<application>ldbmodify(1)</application>
-			 - modify records in a ldb database using LDIF formatted input
-		</para></listitem>
-	</itemizedlist>
-</refsect1>
-
-<refsect1>
-	<title>FUNCTIONS</title>
-
-	<itemizedlist>
-		<listitem><para>
-			<function>ldb_connect(3)</function>
-			 - connect to a ldb backend
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_search(3)</function>
-			 - perform a database search
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_add(3)</function>
-			 - add a record to the database
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_delete(3)</function>
-			 - delete a record from the database
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_modify(3)</function>
-			 - modify a record in the database
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_errstring(3)</function>
-			 - retrieve extended error information from the last operation
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_ldif_write(3)</function>
-			 - write a LDIF formatted message
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_ldif_write_file(3)</function>
-			 - write a LDIF formatted message to a file
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_ldif_read(3)</function>
-			 - read a LDIF formatted message
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_ldif_read_free(3)</function>
-			 - free the result of a ldb_ldif_read()
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_ldif_read_file(3)</function>
-			 - read a LDIF message from a file
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_ldif_read_string(3)</function>
-			 - read a LDIF message from a string
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_msg_find_element(3)</function>
-			 - find an element in a ldb_message
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_val_equal_exact(3)</function>
-			 - compare two ldb_val structures
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_msg_find_val(3)</function>
-			 - find an element by value
-		</para></listitem>
-
-		<listitem><para>
-			<function>ldb_msg_add_empty(3)</function>
-			 - add an empty message element to a ldb_message
-		</para></listitem>
-
-
-		<listitem><para>
-			<function>ldb_msg_add(3)</function>
-			 - add a non-empty message element to a ldb_message
-		</para></listitem>
-
-
-		<listitem><para>
-			<function>ldb_msg_element_compare(3)</function>
-			 - compare two ldb_message_element structures
-		</para></listitem>
-
-
-		<listitem><para>
-			<function>ldb_msg_find_int(3)</function>
-			 - return an integer value from a ldb_message
-		</para></listitem>
-
-
-		<listitem><para>
-			<function>ldb_msg_find_uint(3)</function>
-			 - return an unsigned integer value from a ldb_message
-		</para></listitem>
-
-
-		<listitem><para>
-			<function>ldb_msg_find_double(3)</function>
-			 - return a double value from a ldb_message
-		</para></listitem>
-
-
-		<listitem><para>
-			<function>ldb_msg_find_string(3)</function>
-			 - return a string value from a ldb_message
-		</para></listitem>
-
-
-		<listitem><para>
-			<function>ldb_set_alloc(3)</function>
-			 - set the memory allocation function to be used by ldb
-		</para></listitem>
-
-
-		<listitem><para>
-			<function>ldb_set_debug(3)</function>
-			 - set a debug handler to be used by ldb
-		</para></listitem>
-
-
-		<listitem><para>
-			<function>ldb_set_debug_stderr(3)</function>
-			 - set a debug handler for stderr output
-		</para></listitem>
-	</itemizedlist>
-</refsect1>
-
-<refsect1>
-	<title>Author</title>
-
-	<para>
-		ldb was written by 
-		 <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>.
-	</para>
-
-	<para>
-If you wish to report a problem or make a suggestion then please see
-the <ulink url="http://ldb.samba.org/"/> web site for
-current contact and maintainer information.
-	</para>
-
-	<para>
-ldb is released under the GNU Lesser General Public License version 2
-or later. Please see the file COPYING for license details.
-	</para>
-</refsect1>
-</refentry>

Deleted: branches/samba/experimental/docs-xml/manpages-3/ldbadd.1.xml
===================================================================
--- branches/samba/experimental/docs-xml/manpages-3/ldbadd.1.xml	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs-xml/manpages-3/ldbadd.1.xml	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,108 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-<refentry id="ldbadd.1">
-
-<refmeta>
-	<refentrytitle>ldbadd</refentrytitle>
-	<manvolnum>1</manvolnum>
-	<refmiscinfo class="source">Samba</refmiscinfo>
-	<refmiscinfo class="manual">User Commands</refmiscinfo>
-	<refmiscinfo class="version">3.6</refmiscinfo>
-</refmeta>
-
-
-<refnamediv>
-	<refname>ldbadd</refname>
-	<refpurpose>Command-line utility for adding records to an LDB</refpurpose>
-</refnamediv>
-
-<refsynopsisdiv>
-	<cmdsynopsis>
-		<command>ldbadd</command>
-		<arg choice="opt">-h</arg>
-		<arg choice="opt">-H LDB-URL</arg>
-		<arg choice="opt">ldif-file1</arg>
-		<arg choice="opt">ldif-file2</arg>
-		<arg choice="opt">...</arg>
-	</cmdsynopsis>
-</refsynopsisdiv>
-
-<refsect1>
-	<title>DESCRIPTION</title>
-
-	<para>ldbadd adds records to an ldb(7) database. It reads 
-		the ldif(5) files specified on the command line and adds 
-		the records from these files to the LDB database, which is specified 
-		by the -H option or the LDB_URL environment variable.
-	</para>
-
-	<para>If - is specified as a ldb file, the ldif input is read from 
-		standard input.</para>
-
-</refsect1>
-
-
-<refsect1>
-	<title>OPTIONS</title>
-
-	<variablelist>
-		<varlistentry>
-		<term>-h</term>
-		<listitem><para>
-		Show list of available options.</para></listitem>
-		</varlistentry>
-
-		<varlistentry>
-			<term>-H <ldb-url></term>
-			<listitem><para>
-				LDB URL to connect to. See ldb(7) for details.
-			</para></listitem>
-		</varlistentry>
-		
-	</variablelist>
-	
-</refsect1>
-
-<refsect1>
-	<title>ENVIRONMENT</title>
-
-	<variablelist>
-		<varlistentry><term>LDB_URL</term>
-			<listitem><para>LDB URL to connect to (can be overrided by using the 
-					-H command-line option.)</para></listitem>
-		</varlistentry>
-	</variablelist>
-	
-</refsect1>
-
-<refsect1>
-	<title>VERSION</title>
-
-	<para>This man page is correct for version 3.6 of the Samba suite.</para>
-</refsect1>
-
-<refsect1>
-	<title>SEE ALSO</title>
-
-	<para>ldb(7), ldbmodify, ldbdel, ldif(5)</para>
-
-</refsect1>
-
-<refsect1>
-	<title>AUTHOR</title>
-
-	<para> ldb was written by 
-		 <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>.
-	</para>
-
-	<para>
-If you wish to report a problem or make a suggestion then please see
-the <ulink url="http://ldb.samba.org/"/> web site for
-current contact and maintainer information.
-	</para>
-
-	<para>This manpage was written by Jelmer Vernooij.</para>
-	
-</refsect1>
-
-</refentry>

Deleted: branches/samba/experimental/docs-xml/manpages-3/ldbdel.1.xml
===================================================================
--- branches/samba/experimental/docs-xml/manpages-3/ldbdel.1.xml	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs-xml/manpages-3/ldbdel.1.xml	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,108 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-<refentry id="ldbdel.1">
-
-<refmeta>
-	<refentrytitle>ldbdel</refentrytitle>
-	<manvolnum>1</manvolnum>
-	<refmiscinfo class="source">Samba</refmiscinfo>
-	<refmiscinfo class="manual">User Commands</refmiscinfo>
-	<refmiscinfo class="version">3.6</refmiscinfo>
-</refmeta>
-
-
-<refnamediv>
-	<refname>ldbdel</refname>
-	<refpurpose>Command-line program for deleting LDB records</refpurpose>
-</refnamediv>
-
-<refsynopsisdiv>
-	<cmdsynopsis>
-		<command>ldbdel</command>
-		<arg choice="opt">-h</arg>
-		<arg choice="opt">-H LDB-URL</arg>
-		<arg choice="opt">dn</arg>
-		<arg choice="opt">...</arg>
-	</cmdsynopsis>
-</refsynopsisdiv>
-
-<refsect1>
-	<title>DESCRIPTION</title>
-
-	<para>ldbdel deletes records from an ldb(7) database. 
-		It deletes the records identified by the dn's specified 
-		on the command-line. </para>
-
-	<para>ldbdel uses either the database that is specified with 
-		the -H option or the database specified by the LDB_URL environment
-		variable.</para>
-
-</refsect1>
-
-
-<refsect1>
-	<title>OPTIONS</title>
-
-	<variablelist>
-		<varlistentry>
-		<term>-h</term>
-		<listitem><para>
-		Show list of available options.</para></listitem>
-		</varlistentry>
-
-		<varlistentry>
-			<term>-H <ldb-url></term>
-			<listitem><para>
-				LDB URL to connect to. See ldb(7) for details.
-			</para></listitem>
-		</varlistentry>
-		
-	</variablelist>
-	
-</refsect1>
-
-<refsect1>
-	<title>ENVIRONMENT</title>
-
-	<variablelist>
-		<varlistentry><term>LDB_URL</term>
-			<listitem><para>LDB URL to connect to (can be overrided by using the 
-					-H command-line option.)</para></listitem>
-		</varlistentry>
-	</variablelist>
-	
-</refsect1>
-
-<refsect1>
-	<title>VERSION</title>
-
-	<para>This man page is correct for version 3.6 of the Samba suite.</para>
-</refsect1>
-
-<refsect1>
-	<title>SEE ALSO</title>
-
-	<para>ldb(7), ldbmodify, ldbadd, ldif(5)</para>
-
-</refsect1>
-
-<refsect1>
-	<title>AUTHOR</title>
-
-		<para> ldb was written by 
-		 <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>.
-	</para>
-
-	<para>
-If you wish to report a problem or make a suggestion then please see
-the <ulink url="http://ldb.samba.org/"/> web site for
-current contact and maintainer information.
-	</para>
-
-	<para>ldbdel was written by Andrew Tridgell.</para>
-
-	<para>This manpage was written by Jelmer Vernooij.</para>
-	
-</refsect1>
-
-</refentry>

Deleted: branches/samba/experimental/docs-xml/manpages-3/ldbedit.1.xml
===================================================================
--- branches/samba/experimental/docs-xml/manpages-3/ldbedit.1.xml	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs-xml/manpages-3/ldbedit.1.xml	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,203 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-<refentry id="ldbedit.1">
-
-    <refmeta>
-	<refentrytitle>ldbedit</refentrytitle>
-	<manvolnum>1</manvolnum>
-	<refmiscinfo class="source">Samba</refmiscinfo>
-	<refmiscinfo class="manual">User Commands</refmiscinfo>
-	<refmiscinfo class="version">3.6</refmiscinfo>
-    </refmeta>
-
-
-    <refnamediv>
-	<refname>ldbedit</refname>
-	<refpurpose>Edit LDB databases using your preferred editor</refpurpose>
-    </refnamediv>
-
-    <refsynopsisdiv>
-	<cmdsynopsis>
-	    <command>ldbedit</command>
-	    <arg choice="opt">-?</arg>
-	    <arg choice="opt">--usage</arg>
-	    <arg choice="opt">-s base|one|sub</arg>
-	    <arg choice="opt">-b basedn</arg>
-	    <arg choice="opt">-a</arg>
-	    <arg choice="opt">-e editor</arg>
-	    <arg choice="opt">-H LDB-URL</arg>
-	    <arg choice="opt">expression</arg>
-	    <arg rep="repeat" choice="opt">attributes</arg>
-	</cmdsynopsis>
-</refsynopsisdiv>
-
-<refsect1>
-	<title>DESCRIPTION</title>
-
-	<para>ldbedit is a utility that allows you to edit LDB entries (in 
-	    tdb files, sqlite files or LDAP servers) using your preferred editor.
-	    ldbedit generates an LDIF file based on your query, allows you to edit
-	    the LDIF, and then merges that LDIF back into the LDB backend.
-	</para>
-
-</refsect1>
-
-
-    <refsect1>
-	<title>OPTIONS</title>
-	
-	<variablelist>
-	    <varlistentry>
-		<term>-?</term>
-		<term>--help</term>
-		<listitem>
-		    <para>
-			Show list of available options, and a phrase describing what that option
-			does.
-		    </para>
-		</listitem>
-	    </varlistentry>
-
-	    <varlistentry>
-		<term>--usage</term>
-		<listitem>
-		    <para>
-			Show list of available options. This is similar to the help option, 
-			however it does not provide any description, and is hence shorter.
-		    </para>
-		</listitem>
-	    </varlistentry>
-
-	    <varlistentry>
-		<term>-H <ldb-url></term>
-		<listitem>
-		    <para>
-			LDB URL to connect to. For a tdb database,
-			this will be of the form
-			tdb://<replaceable>filename</replaceable>.
-			For a LDAP connection over unix domain
-			sockets, this will be of the form
-			ldapi://<replaceable>socket</replaceable>. For
-			a (potentially remote) LDAP connection over
-			TCP, this will be of the form
-			ldap://<replaceable>hostname</replaceable>. For
-			an SQLite database, this will be of the form
-			sqlite://<replaceable>filename</replaceable>.
-		    </para>
-		</listitem>
-	    </varlistentry>
-
-	    <varlistentry>
-		<term>-s one|sub|base</term>
-		<listitem><para>Search scope to use. One-level, subtree or base.</para></listitem>
-	    </varlistentry>
-
-	    <varlistentry>
-		<term>-a</term>
-		<term>-all</term>
-		<listitem>
-		    <para>Edit all records. This allows you to
-			apply the same change to a number of records
-			at once. You probably want to combine this
-			with an expression of the form
-			"objectclass=*".
-		    </para>
-		</listitem>
-	    </varlistentry>
-
-	    <varlistentry>
-		<term>-e editor</term>
-		<term>--editor editor</term>
-		<listitem>
-		    <para>Specify the editor that should be used (overrides 
-			the VISUAL and EDITOR environment
-			variables). If this option is not used, and
-			neither VISUAL nor EDITOR environment variables
-			are set, then the vi editor will be used.
-		    </para>
-		</listitem>
-	    </varlistentry>
-
-	    <varlistentry>
-		<term>-b basedn</term>
-		<listitem><para>Specify Base Distinguished Name to use.</para></listitem>
-	    </varlistentry>
-
-	    <varlistentry>
-		<term>-v</term>
-		<term>--verbose</term>
-		<listitem>
-		    <para>Make ldbedit more verbose about the
-			operations that are being performed. Without
-			this option, ldbedit will only provide a
-			summary change line.
-		    </para>
-		</listitem>
-	    </varlistentry>
-		
-	</variablelist>
-	
-    </refsect1>
-
-    <refsect1>
-	<title>ENVIRONMENT</title>
-
-	<variablelist>
-	    <varlistentry>
-		<term>LDB_URL</term>
-		<listitem>
-		    <para>LDB URL to connect to. This can be
-		    overridden by using the -H command-line option.)
-		    </para>
-		</listitem>
-	    </varlistentry>
-	    <varlistentry>
-		<term>VISUAL and EDITOR</term>
-		<listitem>
-		    <para>
-			Environment variables used to determine what 
-			editor to use. VISUAL takes precedence over
-			EDITOR, and both are overridden by the
-			-e command-line option.
-		    </para>
-		</listitem>
-	    </varlistentry>
-	</variablelist>
-	
-    </refsect1>
-
-    <refsect1>
-	<title>VERSION</title>
-	
-	<para>This man page is correct for version 3.6 of the Samba suite.</para>
-    </refsect1>
-
-    <refsect1>
-	<title>SEE ALSO</title>
-	
-	<para>ldb(7), ldbmodify(1), ldbdel(1), ldif(5), vi(1)</para>
-
-    </refsect1>
-
-    <refsect1>
-	<title>AUTHOR</title>
-
-	<para>
-	    ldb was written by 
-	    <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>.
-	</para>
-
-	<para>
-	    If you wish to report a problem or make a suggestion then please see
-	    the <ulink url="http://ldb.samba.org/"/> web site for
-	    current contact and maintainer information.
-	</para>
-
-	<para>
-	    This manpage was written by Jelmer Vernooij and updated
-	    by Brad Hards.
-	</para>
-	
-    </refsect1>
-
-</refentry>

Deleted: branches/samba/experimental/docs-xml/manpages-3/ldbmodify.1.xml
===================================================================
--- branches/samba/experimental/docs-xml/manpages-3/ldbmodify.1.xml	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs-xml/manpages-3/ldbmodify.1.xml	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-<refentry id="ldbmodify.1">
-
-<refmeta>
-	<refentrytitle>ldbmodify</refentrytitle>
-	<manvolnum>1</manvolnum>
-	<refmiscinfo class="source">Samba</refmiscinfo>
-	<refmiscinfo class="manual">User Commands</refmiscinfo>
-	<refmiscinfo class="version">3.6</refmiscinfo>
-</refmeta>
-
-
-<refnamediv>
-	<refname>ldbmodify</refname>
-	<refpurpose>Modify records in a LDB database</refpurpose>
-</refnamediv>
-
-<refsynopsisdiv>
-	<cmdsynopsis>
-		<command>ldbmodify</command>
-		<arg choice="opt">-H LDB-URL</arg>
-		<arg choice="opt">ldif-file</arg>
-	</cmdsynopsis>
-</refsynopsisdiv>
-
-<refsect1>
-	<title>DESCRIPTION</title>
-
-	<para>
-		ldbmodify changes, adds and deletes records in a LDB database. 
-		The changes that should be made to the LDB database are read from 
-		the specified LDIF-file. If - is specified as the filename, input is read from stdin.
-	</para>
-
-	<para>For now, see ldapmodify(1) for details on the LDIF file format.</para>
-
-</refsect1>
-
-
-<refsect1>
-	<title>OPTIONS</title>
-
-	<variablelist>
-		<varlistentry>
-			<term>-H <ldb-url></term>
-			<listitem><para>
-				LDB URL to connect to. See ldb(7) for details.
-			</para></listitem>
-		</varlistentry>
-	</variablelist>
-</refsect1>
-
-<refsect1>
-	<title>ENVIRONMENT</title>
-
-	<variablelist>
-		<varlistentry><term>LDB_URL</term>
-			<listitem><para>LDB URL to connect to (can be overrided by using the 
-					-H command-line option.)</para></listitem>
-		</varlistentry>
-	</variablelist>
-	
-</refsect1>
-
-<refsect1>
-	<title>VERSION</title>
-
-	<para>This man page is correct for version 3.6 of the Samba suite.</para>
-</refsect1>
-
-<refsect1>
-	<title>SEE ALSO</title>
-
-	<para>ldb(7), ldbedit</para>
-
-</refsect1>
-
-<refsect1>
-	<title>AUTHOR</title>
-
-	<para> ldb was written by 
-		 <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>.
-	</para>
-
-	<para>
-If you wish to report a problem or make a suggestion then please see
-the <ulink url="http://ldb.samba.org/"/> web site for
-current contact and maintainer information.
-	</para>
-
-	<para>This manpage was written by Jelmer Vernooij.</para>
-	
-</refsect1>
-
-</refentry>

Deleted: branches/samba/experimental/docs-xml/manpages-3/ldbrename.1.xml
===================================================================
--- branches/samba/experimental/docs-xml/manpages-3/ldbrename.1.xml	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs-xml/manpages-3/ldbrename.1.xml	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,110 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-<refentry id="ldbrename.1">
-
-<refmeta>
-	<refentrytitle>ldbrename</refentrytitle>
-	<manvolnum>1</manvolnum>
-        <refmiscinfo class="source">Samba</refmiscinfo>
-        <refmiscinfo class="manual">User Commands</refmiscinfo>
-        <refmiscinfo class="version">3.6</refmiscinfo>
-</refmeta>
-
-
-<refnamediv>
-	<refname>ldbrename</refname>
-	<refpurpose>Edit LDB databases using your favorite editor</refpurpose>
-</refnamediv>
-
-<refsynopsisdiv>
-	<cmdsynopsis>
-		<command>ldbrename</command>
-		<arg choice="opt">-h</arg>
-		<arg choice="opt">-o options</arg>
-		<arg choice="req">olddn</arg>
-		<arg choice="req">newdb</arg>
-	</cmdsynopsis>
-</refsynopsisdiv>
-
-<refsect1>
-	<title>DESCRIPTION</title>
-
-	<para>ldbrename is a utility that allows you to rename trees in 
-		an LDB database based by DN. This utility takes 
-		two arguments: the original 
-		DN name of the top element and the DN to change it to.
-	</para>
-
-</refsect1>
-
-
-<refsect1>
-	<title>OPTIONS</title>
-
-	<variablelist>
-		<varlistentry>
-		<term>-h</term>
-		<listitem><para>
-		Show list of available options.</para></listitem>
-		</varlistentry>
-
-		<varlistentry>
-			<term>-H <ldb-url></term>
-			<listitem><para>
-				LDB URL to connect to. See ldb(7) for details.
-			</para></listitem>
-		</varlistentry>
-
-		<varlistentry>
-			<term>-o options</term>
-			<listitem><para>Extra ldb options, such as 
-			modules.</para></listitem>
-		</varlistentry>
-		
-	</variablelist>
-	
-</refsect1>
-
-<refsect1>
-	<title>ENVIRONMENT</title>
-
-	<variablelist>
-		<varlistentry><term>LDB_URL</term>
-			<listitem><para>LDB URL to connect to (can be overrided by using the 
-					-H command-line option.)</para></listitem>
-		</varlistentry>
-	</variablelist>
-	
-</refsect1>
-
-<refsect1>
-	<title>VERSION</title>
-
-	<para>This man page is correct for version 3.6 of the Samba suite.</para>
-</refsect1>
-
-<refsect1>
-	<title>SEE ALSO</title>
-
-	<para>ldb(7), ldbmodify, ldbdel, ldif(5)</para>
-
-</refsect1>
-
-<refsect1>
-	<title>AUTHOR</title>
-
-	<para> ldb was written by 
-		 <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>.
-	</para>
-
-	<para>
-If you wish to report a problem or make a suggestion then please see
-the <ulink url="http://ldb.samba.org/"/> web site for
-current contact and maintainer information.
-	</para>
-
-	<para>This manpage was written by Jelmer Vernooij.</para>
-	
-</refsect1>
-
-</refentry>

Deleted: branches/samba/experimental/docs-xml/manpages-3/ldbsearch.1.xml
===================================================================
--- branches/samba/experimental/docs-xml/manpages-3/ldbsearch.1.xml	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs-xml/manpages-3/ldbsearch.1.xml	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-<refentry id="ldbsearch.1">
-
-<refmeta>
-	<refentrytitle>ldbsearch</refentrytitle>
-	<manvolnum>1</manvolnum>
-	<refmiscinfo class="source">Samba</refmiscinfo>
-	<refmiscinfo class="manual">User Commands</refmiscinfo>
-	<refmiscinfo class="version">3.6</refmiscinfo>
-</refmeta>
-
-
-<refnamediv>
-	<refname>ldbsearch</refname>
-	<refpurpose>Search for records in a LDB database</refpurpose>
-</refnamediv>
-
-<refsynopsisdiv>
-	<cmdsynopsis>
-		<command>ldbsearch</command>
-		<arg choice="opt">-h</arg>
-		<arg choice="opt">-s base|one|sub</arg>
-		<arg choice="opt">-b basedn</arg>
-		<arg chioce="opt">-i</arg>
-		<arg choice="opt">-H LDB-URL</arg>
-		<arg choice="opt">expression</arg>
-		<arg choice="opt">attributes</arg>
-	</cmdsynopsis>
-</refsynopsisdiv>
-
-<refsect1>
-	<title>DESCRIPTION</title>
-
-	<para>ldbsearch searches a LDB database for records matching the 
-		specified expression (see the ldapsearch(1) manpage for 
-		a description of the expression format). For each 
-		record, the specified attributes are printed.
-	</para>
-
-</refsect1>
-
-
-<refsect1>
-	<title>OPTIONS</title>
-
-	<variablelist>
-		<varlistentry>
-		<term>-h</term>
-		<listitem><para>
-		Show list of available options.</para></listitem>
-		</varlistentry>
-
-		<varlistentry>
-			<term>-H <ldb-url></term>
-			<listitem><para>
-				LDB URL to connect to. See ldb(7) for details.
-			</para></listitem>
-		</varlistentry>
-
-		<varlistentry>
-			<term>-s one|sub|base</term>
-			<listitem><para>Search scope to use. One-level, subtree or base.</para></listitem>
-		</varlistentry>
-
-		<varlistentry>
-			<term>-i</term>
-			<listitem><para>Read search expressions from stdin. </para></listitem>
-		</varlistentry>
-
-		<varlistentry>
-			<term>-b basedn</term>
-			<listitem><para>Specify Base DN to use.</para></listitem>
-		</varlistentry>
-		
-	</variablelist>
-	
-</refsect1>
-
-<refsect1>
-	<title>ENVIRONMENT</title>
-
-	<variablelist>
-		<varlistentry><term>LDB_URL</term>
-			<listitem><para>LDB URL to connect to (can be overrided by using the 
-					-H command-line option.)</para></listitem>
-		</varlistentry>
-	</variablelist>
-	
-</refsect1>
-
-<refsect1>
-	<title>VERSION</title>
-
-	<para>This man page is correct for version 3.6 of the Samba suite.</para>
-</refsect1>
-
-<refsect1>
-	<title>SEE ALSO</title>
-
-	<para>ldb(7), ldbedit(1)</para>
-
-</refsect1>
-
-<refsect1>
-	<title>AUTHOR</title>
-
-	<para> ldb was written by 
-		 <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>.
-	</para>
-
-	<para>
-If you wish to report a problem or make a suggestion then please see
-the <ulink url="http://ldb.samba.org/"/> web site for
-current contact and maintainer information.
-	</para>
-
-	<para>This manpage was written by Jelmer Vernooij.</para>
-	
-</refsect1>
-
-</refentry>

Modified: branches/samba/experimental/docs-xml/manpages-3/net.8.xml
===================================================================
--- branches/samba/experimental/docs-xml/manpages-3/net.8.xml	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs-xml/manpages-3/net.8.xml	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1854,8 +1854,10 @@
 <para>The registry commands are:
 <simplelist>
 <member>net registry enumerate   - Enumerate registry keys and values.</member>
+<member>net registry enumerate_recursive - Enumerate registry key and its subkeys.</member>
 <member>net registry createkey   - Create a new registry key.</member>
 <member>net registry deletekey   - Delete a registry key.</member>
+<member>net registry deletekey_recursive - Delete a registry key with subkeys.</member>
 <member>net registry getvalue    - Print a registry value.</member>
 <member>net registry getvalueraw - Print a registry value (raw format).</member>
 <member>net registry setvalue    - Set a new registry value.</member>
@@ -1878,11 +1880,17 @@
 
 <refsect3>
   <title>REGISTRY ENUMERATE <replaceable>key</replaceable> </title>
-  <para>Enumerate subkeys and values of <emphasis>key</emphasis>
+  <para>Enumerate subkeys and values of <emphasis>key</emphasis>.
   </para>
 </refsect3>
 
 <refsect3>
+  <title>REGISTRY ENUMERATE_RECURSIVE <replaceable>key</replaceable> </title>
+  <para>Enumerate values of <emphasis>key</emphasis> and its subkeys.
+  </para>
+</refsect3>
+
+<refsect3>
   <title>REGISTRY CREATEKEY <replaceable>key</replaceable> </title>
   <para>Create a new <emphasis>key</emphasis> if not yet existing.
   </para>
@@ -1890,6 +1898,13 @@
 
 <refsect3>
   <title>REGISTRY DELETEKEY <replaceable>key</replaceable> </title>
+  <para>Delete the given <emphasis>key</emphasis> and its
+  values from the registry, if it has no subkeys.
+  </para>
+</refsect3>
+
+<refsect3>
+  <title>REGISTRY DELETEKEY_RECURSIVE <replaceable>key</replaceable> </title>
   <para>Delete the given <emphasis>key</emphasis> and all of its
   subkeys and values from the registry.
   </para>

Modified: branches/samba/experimental/docs-xml/smbdotconf/misc/timeoffset.xml
===================================================================
--- branches/samba/experimental/docs-xml/smbdotconf/misc/timeoffset.xml	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/docs-xml/smbdotconf/misc/timeoffset.xml	2011-07-28 16:06:15 UTC (rev 3863)
@@ -4,10 +4,12 @@
 		 advanced="1" developer="1"
 		 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
 <description>
-	<para>This parameter is a setting in minutes to add 
+	<para>This deprecated parameter is a setting in minutes to add
 	to the normal GMT to local time conversion. This is useful if 
 	you are serving a lot of PCs that have incorrect daylight 
 	saving time handling.</para>
+
+	<note><para>This option is deprecated, and will be removed in the next major release</para></note>
 </description>
 
 <value type="default">0</value>

Modified: branches/samba/experimental/examples/VFS/shadow_copy_test.c
===================================================================
--- branches/samba/experimental/examples/VFS/shadow_copy_test.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/examples/VFS/shadow_copy_test.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -19,6 +19,8 @@
  */
 
 #include "includes.h"
+#include "ntioctl.h"
+#include "smbd/proto.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
@@ -50,7 +52,10 @@
 	  Directories are always displayed...    
 */
 
-static int test_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels)
+static int test_get_shadow_copy_data(vfs_handle_struct *handle,
+				    files_struct *fsp,
+				    struct shadow_copy_data *shadow_copy_data,
+				    bool labels)
 {
 	uint32 num = 3;
 	uint32 i;
@@ -59,7 +64,7 @@
 	
 	if (labels) {	
 		if (num) {
-			shadow_copy_data->labels = TALLOC_ZERO_ARRAY(shadow_copy_data->mem_ctx,SHADOW_COPY_LABEL,num);
+			shadow_copy_data->labels = TALLOC_ZERO_ARRAY(shadow_copy_data,SHADOW_COPY_LABEL,num);
 		} else {
 			shadow_copy_data->labels = NULL;
 		}
@@ -81,5 +86,7 @@
 
 NTSTATUS vfs_shadow_copy_test_init(void)
 {
-	return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy_test", &vfs_test_shadow_copy_fns);
+	return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
+				"shadow_copy_test",
+				&vfs_test_shadow_copy_fns);
 }

Modified: branches/samba/experimental/examples/VFS/skel_opaque.c
===================================================================
--- branches/samba/experimental/examples/VFS/skel_opaque.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/examples/VFS/skel_opaque.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -23,6 +23,7 @@
 
 
 #include "includes.h"
+#include "smbd/proto.h"
 
 /* PLEASE,PLEASE READ THE VFS MODULES CHAPTER OF THE 
    SAMBA DEVELOPERS GUIDE!!!!!!
@@ -65,7 +66,7 @@
 	return -1;
 }
 
-static int skel_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels)
+static int skel_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, struct shadow_copy_data *shadow_copy_data, bool labels)
 {
 	errno = ENOSYS;
 	return -1;

Modified: branches/samba/experimental/examples/VFS/skel_transparent.c
===================================================================
--- branches/samba/experimental/examples/VFS/skel_transparent.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/examples/VFS/skel_transparent.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -23,6 +23,7 @@
 
 
 #include "includes.h"
+#include "smbd/proto.h"
 
 /* PLEASE,PLEASE READ THE VFS MODULES CHAPTER OF THE 
    SAMBA DEVELOPERS GUIDE!!!!!!
@@ -64,7 +65,7 @@
 	return SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, dq);
 }
 
-static int skel_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels)
+static int skel_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, struct shadow_copy_data *shadow_copy_data, bool labels)
 {
 	return SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp, shadow_copy_data, labels);
 }

Deleted: branches/samba/experimental/howto-ol-backend-s4.txt
===================================================================
--- branches/samba/experimental/howto-ol-backend-s4.txt	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/howto-ol-backend-s4.txt	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,131 +0,0 @@
-Samba4  OpenLDAP-Backend Quick-Howto
-====================================
-
-oliver at itc.li  -  August 2009
-
-
-This Mini-Howto describes in a very simplified way 
-how to setup Samba 4 (S4) (pre)Alpha 13 with the
-OpenLDAP (OL) -Backend.
-Use of OpenLDAP from CVS after 2010-04-22 is required
-
-The current instructions are at:
-
-http://wiki.samba.org/index.php/Samba4/LDAP_Backend/OpenLDAP
-
-1.) Download and compile OpenLDAP. 
-
-The use of (older) Versions shipped with Distributions often
-causes trouble, so dont use them. Configure-Example:
-
-#> ./configure --enable-overlays=yes --with-tls=yes --with-cyrus-sasl=yes
-#> make depend && make && make install
-
-Note: openssl and cyrus-sasl libs should be installed
-before compilation.
-
-
-
-
-2.) Final provision:
-
-(you can add --adminpass=<yourpass> to the parameters,
-otherwise a random password will be generated for 
-cn=Administrator,cn=users,<Your Base-DN>):
-
-#> setup/provision \
-   --ldap-backend-type=openldap \
-   --slapd-path="/usr/local/libexec/slapd"
-   --username=samba-admin --realm=ldap.local.site \
-   --domain=LDAP --server-role='domain controller'\
-   --adminpass=linux
-
-At the End of the final provision you should get
-the following output (only partial here). Read it carefully:
-
---------
-...
-A Kerberos configuration suitable for Samba 4 has been generated at /usr/local/samba/private/krb5.conf
-
-Use later the following commandline to start slapd, then Samba:
-/usr/local/libexec/slapd -f /usr/local/samba/private/ldap/slapd.conf -h ldapi://%2Fusr%2Flocal%2Fsamba%2Fprivate%2Fldap%2Fldapi
-
-This slapd-Commandline is also stored under: /usr/local/samba/private/ldap/slapd_command_file.sh
-Please install the phpLDAPadmin configuration located at /usr/local/samba/private/phpldapadmin-config.php into /etc/phpldapadmin/config.php
-Once the above files are installed, your Samba4 server will be ready to use
-Server Role:    domain controller
-Hostname:       ldapmaster
-NetBIOS Domain: LDAP
-DNS Domain:     ldap.local.site
-DOMAIN SID:     S-1-5-21-429312062-2328781357-2130201529
-Admin password: linux
-
---------
-
-Our slapd in "provision-mode" wiil be shut down automatically 
-after final provision ends.
-
-
-3.) Run OL and S4:
-
-After you completed the other necessary steps (krb and named-specific),
-start first OL with the commandline displayed in the output under (3),
-(remember: the slapd-Commandline is also stored in the file ../slapd_command_file.sh)
-then S4.
-
-
-
-4.) Special Setup-Types:
-
-OpenLDAP-Online Configuration is now in use by default (olc):
-
-The olc will be setup automatically
-under ../private/slapd.d/.
-olc is accessible via "cn=samba-admin,cn=samba" and Base-DN "cn=config"
-olc is intended primarily for use in conjunction with MMR
-
-Attention: You have to start OL with the commandline
-displayed in the output under (3), but you have to set a 
-listening port of slapd manually:
-
-(e.g. -h ldap://ldapmaster.ldap.local.site:9000)
-
-Attention: You _should_not_ edit the olc-Sections
-"config" and "ldif", as these are vital to the olc itself.
-
-
-b) MultiMaster-Configuration (MMR):
-Use the provision Parameter:
-
- --ol-mmr-urls=<list of whitespace separated ldap-urls (and Ports <> 389!).
-
-e.g.:
---ol-mmr-urls="ldap://ldapmaster1.ldap.local.site:9000 \ 
-   ldap://ldapmaster2.ldap.local.site:9000"
-
-Attention: You have to start OL with the commandline
-displayed in the output under (3), but you have to set a 
-listening port of slapd manually
-(e.g. -h ldap://ldapmaster1.ldap.local.site:9000)
-
-The Ports must be different from 389, as these are occupied by S4.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

Deleted: branches/samba/experimental/howto4.txt
===================================================================
--- branches/samba/experimental/howto4.txt	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/howto4.txt	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,7 +0,0 @@
-Samba4 howto
-============
-
-For current versions of the Samba4 HOWTO, please see our wiki:
-
-  http://wiki.samba.org/index.php/Samba4/HOWTO
-

Modified: branches/samba/experimental/lib/util/data_blob.h
===================================================================
--- branches/samba/experimental/lib/util/data_blob.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/lib/util/data_blob.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,7 +1,10 @@
 /* 
    Unix SMB/CIFS implementation.
    DATA BLOB
-   
+
+   Copyright (C) Andrew Tridgell 2001
+   Copyright (C) Andrew Bartlett 2001
+
    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

Modified: branches/samba/experimental/lib/util/time.h
===================================================================
--- branches/samba/experimental/lib/util/time.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/lib/util/time.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,7 +1,12 @@
 /* 
    Unix SMB/CIFS implementation.
    time utility functions
-   
+
+   Copyright (C) Andrew Tridgell 		1992-2004
+   Copyright (C) Stefan (metze) Metzmacher	2002
+   Copyright (C) Jeremy Allison			2007
+   Copyright (C) Andrew Bartlett                2011
+
    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

Modified: branches/samba/experimental/lib/util/util_ldb.h
===================================================================
--- branches/samba/experimental/lib/util/util_ldb.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/lib/util/util_ldb.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,26 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   common share info functions
+
+   Copyright (C) Andrew Tridgell 2004
+   Copyright (C) Tim Potter 2004
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 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/>.
+*/
+
+
 #ifndef __LIB_UTIL_UTIL_LDB_H__
 #define __LIB_UTIL_UTIL_LDB_H__
 

Modified: branches/samba/experimental/lib/util/util_tdb.h
===================================================================
--- branches/samba/experimental/lib/util/util_tdb.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/lib/util/util_tdb.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,24 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   tdb utility functions
+
+   Copyright (C) Andrew Tridgell 1992-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/>.
+*/
+
 #ifndef _____LIB_UTIL_UTIL_TDB_H__
 #define _____LIB_UTIL_UTIL_TDB_H__
 

Modified: branches/samba/experimental/lib/util/wrap_xattr.h
===================================================================
--- branches/samba/experimental/lib/util/wrap_xattr.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/lib/util/wrap_xattr.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,24 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   POSIX NTVFS backend - xattr support using filesystem xattrs
+
+   Copyright (C) Andrew Tridgell 2004
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 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/>.
+*/
+
 #ifndef __LIB_UTIL_WRAP_XATTR_H__
 #define __LIB_UTIL_WRAP_XATTR_H__
 

Modified: branches/samba/experimental/libcli/auth/msrpc_parse.h
===================================================================
--- branches/samba/experimental/libcli/auth/msrpc_parse.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/libcli/auth/msrpc_parse.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,24 @@
+/*
+   Unix SMB/CIFS implementation.
+   simple kerberos5/SPNEGO routines
+   Copyright (C) Andrew Tridgell 2001
+   Copyright (C) Jim McDonough <jmcd at us.ibm.com> 2002
+   Copyright (C) Andrew Bartlett 2002-2003
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #ifndef _LIBCLI_AUTH_MSRPC_PARSE_H__
 #define _LIBCLI_AUTH_MSRPC_PARSE_H__
 

Modified: branches/samba/experimental/libcli/ldap/ldap_ndr.h
===================================================================
--- branches/samba/experimental/libcli/ldap/ldap_ndr.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/libcli/ldap/ldap_ndr.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+   Unix SMB/CIFS mplementation.
+
+   wrap/unwrap NDR encoded elements for ldap calls
+
+   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/>.
+
+*/
+
 #ifndef __LIBCLI_LDAP_LDAP_NDR_H__
 #define __LIBCLI_LDAP_LDAP_NDR_H__
 

Modified: branches/samba/experimental/libcli/nbt/nbt_proto.h
===================================================================
--- branches/samba/experimental/libcli/nbt/nbt_proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/libcli/nbt/nbt_proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,24 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   manipulate nbt name structures
+
+   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/>.
+*/
+
 #ifndef _____LIBCLI_NBT_NBT_PROTO_H__
 #define _____LIBCLI_NBT_NBT_PROTO_H__
 

Modified: branches/samba/experimental/libcli/smbreadline/smbreadline.h
===================================================================
--- branches/samba/experimental/libcli/smbreadline/smbreadline.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/libcli/smbreadline/smbreadline.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,23 @@
+/*
+   Unix SMB/CIFS implementation.
+   Samba readline wrapper implementation
+   Copyright (C) Simo Sorce 2001
+   Copyright (C) Andrew Tridgell 2001
+
+   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/>.
+*/
+
 #ifndef __SMBREADLINE_H__
 #define __SMBREADLINE_H__
 

Modified: branches/samba/experimental/libds/common/flag_mapping.h
===================================================================
--- branches/samba/experimental/libds/common/flag_mapping.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/libds/common/flag_mapping.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+   Unix SMB/CIFS implementation.
+   helper mapping functions for the UF and ACB flags
+
+   Copyright (C) Stefan (metze) Metzmacher 2002
+   Copyright (C) Andrew Tridgell 2004
+   Copyright (C) Matthias Dieter Wallnöfer 2010
+
+   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/>.
+*/
+
 #ifndef __LIBDS_COMMON_FLAG_MAPPING_H__
 #define __LIBDS_COMMON_FLAG_MAPPING_H__
 

Modified: branches/samba/experimental/librpc/ndr/ndr_backupkey.h
===================================================================
--- branches/samba/experimental/librpc/ndr/ndr_backupkey.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/librpc/ndr/ndr_backupkey.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,2 +1,23 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   routines for top backup key protocol marshalling/unmarshalling
+
+   Copyright (C) Matthieu Patou 2010
+
+   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/>.
+*/
+
 _PUBLIC_ enum ndr_err_code ndr_push_bkrp_access_check_v2(struct ndr_push *ndr, int ndr_flags, const struct bkrp_access_check_v2 *r);
 _PUBLIC_ enum ndr_err_code ndr_pull_bkrp_access_check_v2(struct ndr_pull *ndr, int ndr_flags, struct bkrp_access_check_v2 *r);

Modified: branches/samba/experimental/librpc/ndr/ndr_compression.h
===================================================================
--- branches/samba/experimental/librpc/ndr/ndr_compression.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/librpc/ndr/ndr_compression.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   libndr compression support
+
+   Copyright (C) Stefan Metzmacher 2005
+   Copyright (C) Matthieu Suiche 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 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/>.
+*/
+
 #ifndef __LIBRPC_NDR_NDR_COMPRESSION_H__
 #define __LIBRPC_NDR_NDR_COMPRESSION_H__
 

Modified: branches/samba/experimental/librpc/ndr/ndr_dns.h
===================================================================
--- branches/samba/experimental/librpc/ndr/ndr_dns.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/librpc/ndr/ndr_dns.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,28 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   manipulate dns name structures
+
+   Copyright (C) 2010 Kai Blin  <kai at samba.org>
+
+   Heavily based on nbtname.c which is:
+
+   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/>.
+*/
+
 void ndr_print_dns_string(struct ndr_print *ndr,
 			  const char *name,
 			  const char *s);

Modified: branches/samba/experimental/librpc/ndr/ndr_spoolss_buf.h
===================================================================
--- branches/samba/experimental/librpc/ndr/ndr_spoolss_buf.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/librpc/ndr/ndr_spoolss_buf.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,26 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   routines for marshalling/unmarshalling spoolss subcontext buffer structures
+
+   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
+   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/>.
+*/
+
 #ifndef ___SPACE_SRC_SAMBA_SOURCES_SAMBA_GIT_SOURCE3____SOURCE4_LIBRPC_NDR_NDR_SPOOLSS_BUF_H__
 #define ___SPACE_SRC_SAMBA_SOURCES_SAMBA_GIT_SOURCE3____SOURCE4_LIBRPC_NDR_NDR_SPOOLSS_BUF_H__
 

Modified: branches/samba/experimental/librpc/ndr/ndr_table.h
===================================================================
--- branches/samba/experimental/librpc/ndr/ndr_table.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/librpc/ndr/ndr_table.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   dcerpc utility functions
+
+   Copyright (C) Andrew Tridgell 2003
+   Copyright (C) Jelmer Vernooij 2004
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 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/>.
+*/
+
 #ifndef _NDR_TABLE_PROTO_H_
 #define _NDR_TABLE_PROTO_H_
 

Modified: branches/samba/experimental/nsswitch/pam_winbind.h
===================================================================
--- branches/samba/experimental/nsswitch/pam_winbind.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/nsswitch/pam_winbind.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,46 @@
+/*
+ * Copyright (c) Andrew Tridgell  <tridge at samba.org>   2000
+ * Copyright (c) Tim Potter       <tpot at samba.org>     2000
+ * Copyright (c) Andrew Bartlettt <abartlet at samba.org> 2002
+ * Copyright (c) Guenther Deschner <gd at samba.org>      2005-2008
+ * Copyright (c) Jan Rêkorajski 1999.
+ * Copyright (c) Andrew G. Morgan 1996-8.
+ * Copyright (c) Alex O. Yuriev, 1996.
+ * Copyright (c) Cristian Gafton 1996.
+ * Copyright (C) Elliot Lee <sopwith at redhat.com> 1996, Red Hat Software.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, and the entire permission notice in its entirety,
+ *    including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions.  (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 /* pam_winbind header file
    (Solaris needs some macros from Linux for common PAM code)
 
@@ -4,6 +47,9 @@
    Shirish Kalele 2000
 */
 
+#ifndef _NSSWITCH_PAM_WINBIND_H_
+#define _NSSWITCH_PAM_WINBIND_H_
+
 #include "../lib/replace/replace.h"
 #include "system/syslog.h"
 #include "system/time.h"
@@ -175,3 +221,5 @@
 #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)
+
+#endif /* _NSSWITCH_PAM_WINBIND_H_ */

Modified: branches/samba/experimental/nsswitch/winbind_client.h
===================================================================
--- branches/samba/experimental/nsswitch/winbind_client.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/nsswitch/winbind_client.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,30 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   winbind client common code
+
+   Copyright (C) Tim Potter 2000
+   Copyright (C) Andrew Tridgell 2000
+   Copyright (C) Andrew Bartlett 2002
+
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _NSSWITCH_WINBIND_CLIENT_H_
+#define _NSSWITCH_WINBIND_CLIENT_H_
+
 #include "winbind_nss_config.h"
 #include "winbind_struct_protocol.h"
 
@@ -19,3 +46,5 @@
 
 #define winbind_on() \
 	(setenv(WINBINDD_DONT_ENV, "0", 1) == 0)
+
+#endif /* _NSSWITCH_WINBIND_CLIENT_H_ */

Modified: branches/samba/experimental/packaging/RHEL/makerpms.sh
===================================================================
--- branches/samba/experimental/packaging/RHEL/makerpms.sh	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/packaging/RHEL/makerpms.sh	2011-07-28 16:06:15 UTC (rev 3863)
@@ -20,7 +20,7 @@
 
 USERID=`id -u`
 GRPID=`id -g`
-VERSION='3.6.0rc2'
+VERSION='3.6.0rc3'
 REVISION=''
 SPECFILE="samba.spec"
 RPMVER=`rpm --version | awk '{print $3}'`

Modified: branches/samba/experimental/packaging/RHEL/samba.spec
===================================================================
--- branches/samba/experimental/packaging/RHEL/samba.spec	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/packaging/RHEL/samba.spec	2011-07-28 16:06:15 UTC (rev 3863)
@@ -5,7 +5,7 @@
 Vendor: Samba Team
 Packager: Samba Team <samba at samba.org>
 Name:         samba
-Version:      3.6.0rc2
+Version:      3.6.0rc3
 Release:      1
 Epoch:        0
 License: GNU GPL version 3

Modified: branches/samba/experimental/packaging/RHEL-CTDB/samba.spec
===================================================================
--- branches/samba/experimental/packaging/RHEL-CTDB/samba.spec	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/packaging/RHEL-CTDB/samba.spec	2011-07-28 16:06:15 UTC (rev 3863)
@@ -5,7 +5,7 @@
 Vendor: Samba Team
 Packager: Samba Team <samba at samba.org>
 Name:         samba
-Version:      3.6.0rc2
+Version:      3.6.0rc3
 Release:      1GITHASH
 Epoch:        0
 License: GNU GPL version 3

Deleted: branches/samba/experimental/prog_guide4.txt
===================================================================
--- branches/samba/experimental/prog_guide4.txt	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/prog_guide4.txt	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,777 +0,0 @@
-
-
-THIS IS INCOMPLETE! I'M ONLY COMMITING IT IN ORDER TO SOLICIT COMMENTS
-FROM A FEW PEOPLE. DON'T TAKE THIS AS THE FINAL VERSION YET.
-
-
-Samba4 Programming Guide
-========================
-
-.. contents::
-
-The internals of Samba4 are quite different from previous versions of
-Samba, so even if you are an experienced Samba developer please take
-the time to read through this document.
-
-This document will explain both the broad structure of Samba4, and
-some of the common coding elements such as memory management and
-dealing with macros.
-
-
-Coding Style
-------------
-
-In past versions of Samba we have basically let each programmer choose
-their own programming style. Unfortunately the result has often been
-that code that other members of the team find difficult to read. For
-Samba version 4 I would like to standardise on a common coding style
-to make the whole tree more readable. For those of you who are
-horrified at the idea of having to learn a new style, I can assure you
-that it isn't as painful as you might think. I was forced to adopt a
-new style when I started working on the Linux kernel, and after some
-initial pain found it quite easy.
-
-That said, I don't want to invent a new style, instead I would like to
-adopt the style used by the Linux kernel. It is a widely used style
-with plenty of support tools available. See Documentation/CodingStyle
-in the Linux source tree. This is the style that I have used to write
-all of the core infrastructure for Samba4 and I think that we should
-continue with that style.
-
-I also think that we should most definately *not* adopt an automatic
-reformatting system in cvs (or whatever other source code system we
-end up using in the future). Such automatic formatters are, in my
-experience, incredibly error prone and don't understand the necessary
-exceptions. I don't mind if people use automated tools to reformat
-their own code before they commit it, but please do not run such
-automated tools on large slabs of existing code without being willing
-to spend a *lot* of time hand checking the results.
-
-Finally, I think that for code that is parsing or formatting protocol
-packets the code layout should strongly reflect the packet
-format. That means ordring the code so that it parses in the same
-order as the packet is stored on the wire (where possible) and using
-white space to align packet offsets so that a reader can immediately
-map any line of the code to the corresponding place in the packet.
-
-
-Static and Global Data
-----------------------
-
-The basic rule is "avoid static and global data like the plague". What
-do I mean by static data? The way to tell if you have static data in a
-file is to use the "size" utility in Linux. For example if we run::
-
-  size libcli/raw/*.o
-
-in Samba4 then you get the following::
-
-   text    data     bss     dec     hex filename
-   2015       0       0    2015     7df libcli/raw/clikrb5.o
-    202       0       0     202      ca libcli/raw/clioplock.o
-     35       0       0      35      23 libcli/raw/clirewrite.o
-   3891       0       0    3891     f33 libcli/raw/clisession.o
-    869       0       0     869     365 libcli/raw/clisocket.o
-   4962       0       0    4962    1362 libcli/raw/clispnego.o
-   1223       0       0    1223     4c7 libcli/raw/clitransport.o
-   2294       0       0    2294     8f6 libcli/raw/clitree.o
-   1081       0       0    1081     439 libcli/raw/raweas.o
-   6765       0       0    6765    1a6d libcli/raw/rawfile.o
-   6824       0       0    6824    1aa8 libcli/raw/rawfileinfo.o
-   2944       0       0    2944     b80 libcli/raw/rawfsinfo.o
-    541       0       0     541     21d libcli/raw/rawioctl.o
-   1728       0       0    1728     6c0 libcli/raw/rawnegotiate.o
-    723       0       0     723     2d3 libcli/raw/rawnotify.o
-   3779       0       0    3779     ec3 libcli/raw/rawreadwrite.o
-   6597       0       0    6597    19c5 libcli/raw/rawrequest.o
-   5580       0       0    5580    15cc libcli/raw/rawsearch.o
-   3034       0       0    3034     bda libcli/raw/rawsetfileinfo.o
-   5187       0       0    5187    1443 libcli/raw/rawtrans.o
-   2033       0       0    2033     7f1 libcli/raw/smb_signing.o
-
-notice that the "data" and "bss" columns are all zero? That is
-good. If there are any non-zero values in data or bss then that
-indicates static data and is bad (as a rule of thumb).
-
-Lets compare that result to the equivalent in Samba3::
-
-   text    data     bss     dec     hex filename
-   3978       0       0    3978     f8a libsmb/asn1.o
-  18963       0     288   19251    4b33 libsmb/cliconnect.o
-   2815       0    1024    3839     eff libsmb/clidgram.o
-   4038       0       0    4038     fc6 libsmb/clientgen.o
-   3337     664     256    4257    10a1 libsmb/clierror.o
-  10043       0       0   10043    273b libsmb/clifile.o
-    332       0       0     332     14c libsmb/clifsinfo.o
-    166       0       0     166      a6 libsmb/clikrb5.o
-   5212       0       0    5212    145c libsmb/clilist.o
-   1367       0       0    1367     557 libsmb/climessage.o
-    259       0       0     259     103 libsmb/clioplock.o
-   1584       0       0    1584     630 libsmb/cliprint.o
-   7565       0     256    7821    1e8d libsmb/cliquota.o
-   7694       0       0    7694    1e0e libsmb/clirap.o
-  27440       0       0   27440    6b30 libsmb/clirap2.o
-   2905       0       0    2905     b59 libsmb/clireadwrite.o
-   1698       0       0    1698     6a2 libsmb/clisecdesc.o
-   5517       0       0    5517    158d libsmb/clispnego.o
-    485       0       0     485     1e5 libsmb/clistr.o
-   8449       0       0    8449    2101 libsmb/clitrans.o
-   2053       0       4    2057     809 libsmb/conncache.o
-   3041       0     256    3297     ce1 libsmb/credentials.o
-   1261       0    1024    2285     8ed libsmb/doserr.o
-  14560       0       0   14560    38e0 libsmb/errormap.o
-   3645       0       0    3645     e3d libsmb/namecache.o
-  16815       0       8   16823    41b7 libsmb/namequery.o
-   1626       0       0    1626     65a libsmb/namequery_dc.o
-  14301       0    1076   15377    3c11 libsmb/nmblib.o
-  24516       0    2048   26564    67c4 libsmb/nterr.o
-   8661       0       8    8669    21dd libsmb/ntlmssp.o
-   3188       0       0    3188     c74 libsmb/ntlmssp_parse.o
-   4945       0       0    4945    1351 libsmb/ntlmssp_sign.o
-   1303       0       0    1303     517 libsmb/passchange.o
-   1221       0       0    1221     4c5 libsmb/pwd_cache.o
-   2475       0       4    2479     9af libsmb/samlogon_cache.o
-  10768      32       0   10800    2a30 libsmb/smb_signing.o
-   4524       0      16    4540    11bc libsmb/smbdes.o
-   5708       0       0    5708    164c libsmb/smbencrypt.o
-   7049       0    3072   10121    2789 libsmb/smberr.o
-   2995       0       0    2995     bb3 libsmb/spnego.o
-   3186       0       0    3186     c72 libsmb/trustdom_cache.o
-   1742       0       0    1742     6ce libsmb/trusts_util.o
-    918       0      28     946     3b2 libsmb/unexpected.o
-
-notice all of the non-zero data and bss elements? Every bit of that
-data is a bug waiting to happen.
-
-Static data is evil as it has the following consequences:
-- it makes code much less likely to be thread-safe
-- it makes code much less likely to be recursion-safe
-- it leads to subtle side effects when the same code is called from multiple places
-- doesn't play well with shared libraries or plugins
-
-Static data is particularly evil in library code (such as our internal
-smb and rpc libraries). If you can get rid of all static data in
-libraries then you can make some fairly strong guarantees about the
-behaviour of functions in that library, which really helps.
-
-Of course, it is possible to write code that uses static data and is
-safe, it's just much harder to do that than just avoid static data in
-the first place. We have been tripped up countless times by subtle
-bugs in Samba due to the use of static data, so I think it is time to
-start avoiding it in new code. Much of the core infrastructure of
-Samba4 was specifically written to avoid static data, so I'm going to
-be really annoyed if everyone starts adding lots of static data back
-in.
-
-So, how do we avoid static data? The basic method is to use context
-pointers. When reading the Samba4 code you will notice that just about
-every function takes a pointer to a context structure as its first
-argument. Any data that the function needs that isn't an explicit
-argument to the function can be found by traversing that context. 
-
-Note that this includes all of the little caches that we have lying
-all over the code in Samba3. I'm referring to the ones that generally
-have a "static int initialised" and then some static string or integer
-that remembers the last return value of the function. Get rid of them!
-If you are *REALLY* absolutely completely certain that your personal
-favourite mini-cache is needed then you should do it properly by
-putting it into the appropriate context rather than doing it the lazy
-way by putting it inside the target function. I would suggest however
-that the vast majority of those little caches are useless - don't
-stick it in unless you have really firm benchmarking results that show
-that it is needed and helps by a significant amount.
-
-Note that Samba4 is not yet completely clean of static data like
-this. I've gotten the smbd/ directory down to 24 bytes of static data,
-and libcli/raw/ down to zero. I've also gotten the ntvfs layer and all
-backends down to just 8 bytes in ntvfs_base.c. The rest still needs
-some more work.
-
-Also note that truly constant data is OK, and will not in fact show up
-in the data and bss columns in "size" anyway (it will be included in
-"text"). So you can have constant tables of protocol data.
-
-
-How to use talloc
------------------
-
-Please see the separate document, lib/talloc/talloc_guide.txt
-You _must_ read this if you want to program in Samba4.
-
-
-Interface Structures
---------------------
-
-One of the biggest changes in Samba4 is the universal use of interface
-structures. Go take a look through libcli/raw/interfaces.h now to get
-an idea of what I am talking about.
-
-In Samba3 many of the core wire structures in the SMB protocol were
-never explicitly defined in Samba. Instead, our parse and generation
-functions just worked directly with wire buffers. The biggest problem
-with this is that is tied our parse code with our "business logic"
-much too closely, which meant the code got extremely confusing to
-read.
-
-In Samba4 we have explicitly defined interface structures for
-everything in the protocol. When we receive a buffer we always parse
-it completely into one of these structures, then we pass a pointer to
-that structure to a backend handler. What we must *not* do is make any
-decisions about the data inside the parse functions. That is critical
-as different backends will need different portions of the data. This
-leads to a golden rule for Samba4:
-
-  "don't design interfaces that lose information"
-
-In Samba3 our backends often received "condensed" versions of the
-information sent from clients, but this inevitably meant that some
-backends could not get at the data they needed to do what they wanted,
-so from now on we should expose the backends to all of the available
-information and let them choose which bits they want.
-
-Ok, so now some of you will be thinking "this sounds just like our
-msrpc code from Samba3", and while to some extent this is true there
-are extremely important differences in the approach that are worth
-pointing out.
-
-In the Samba3 msrpc code we used explicit parse structures for all
-msrpc functions. The problem is that we didn't just put all of the
-real variables in these structures, we also put in all the artifacts
-as well. A good example is the security descriptor strucrure that
-looks like this in Samba3::
-
-	typedef struct security_descriptor_info
-	{
-		uint16 revision; 
-		uint16 type;    
-
-		uint32 off_owner_sid;
-		uint32 off_grp_sid;
-		uint32 off_sacl;
-		uint32 off_dacl;
-
-		SEC_ACL *dacl;
-		SEC_ACL *sacl;
-		DOM_SID *owner_sid; 
-		DOM_SID *grp_sid;
-	} SEC_DESC;
-
-The problem with this structure is all the off_* variables. Those are
-not part of the interface, and do not appear in any real descriptions
-of Microsoft security descriptors. They are parsing artifacts
-generated by the IDL compiler that Microsoft use. That doesn't mean
-they aren't needed on the wire - indeed they are as they tell the
-parser where to find the following four variables, but they should
-*NOT* be in the interface structure.
-
-In Samba3 there were unwritten rules about which variables in a
-structure a high level caller has to fill in and which ones are filled
-in by the marshalling code. In Samba4 those rules are gone, because
-the redundent artifact variables are gone. The high level caller just
-sets up the real variables and the marshalling code worries about
-generating the right offsets.
-
-The same rule applies to strings. In many places in the SMB and MSRPC
-protocols complex strings are used on the wire, with complex rules
-about padding, format, alighment, termination etc. None of that
-information is useful to a high level calling routine or to a backend - its 
-all just so much wire fluff. So, in Samba4 these strings are
-just "char \*" and are always in our internal multi-byte format (which
-is usually UTF8). It is up to the parse functions to worry about
-translating the format and getting the padding right.
-
-The one exception to this is the use of the WIRE_STRING type, but that
-has a very good justification in terms of regression testing. Go and
-read the comment in smb_interfaces.h about that now.
-
-So, here is another rule to code by. When writing an interface
-structure think carefully about what variables in the structure can be
-left out as they are redundent. If some length is effectively defined
-twice on the wire then only put it once in the packet. If a length can
-be inferred from a null termination then do that and leave the length
-out of the structure completely. Don't put redundent stuff in
-structures!
-
-
-Async Design
-------------
-
-Samba4 has an asynchronous design. That affects *lots* of the code,
-and the implications of the asynchronous design needs to be considered
-just about everywhere.
-
-The first aspect of the async design to look at is the SMB client
-library. Lets take a look at the following three functions in
-libcli/raw/rawfile.c::
-
-	struct cli_request *smb_raw_seek_send(struct cli_tree *tree, struct smb_seek *parms);
-	NTSTATUS smb_raw_seek_recv(struct cli_request *req, struct smb_seek *parms);
-	NTSTATUS smb_raw_seek(struct cli_tree *tree, struct smb_seek *parms);
-
-Go and read them now then come back.
-
-Ok, first notice there there are 3 separate functions, whereas the
-equivalent code in Samba3 had just one. Also note that the 3rd
-function is extremely simple - its just a wrapper around calling the
-first two in order.
-
-The three separate functions are needed because we need to be able to
-generate SMB calls asynchronously. The first call, which for smb calls
-is always called smb_raw_XXXX_send(), constructs and sends a SMB
-request and returns a "struct cli_request" which acts as a handle for
-the request. The caller is then free to do lots of other calls if it
-wants to, then when it is ready it can call the smb_raw_XXX_recv()
-function to receive the reply.
-
-If all you want is a synchronous call then call the 3rd interface, the
-one called smb_raw_XXXX(). That just calls the first two in order, and
-blocks waiting for the reply.
-
-But what if you want to be called when the reply comes in? Yes, thats
-possible. You can do things like this::
-
-    struct cli_request *req;
-
-    req = smb_raw_XXX_send(tree, params);
-
-    req->async.fn = my_callback;
-    req->async.private = my_private_data;
-
-then in your callback function you can call the smb_raw_XXXX_recv()
-function to receive the reply. Your callback will receive the "req"
-pointer, which you can use to retrieve your private data from
-req->async.private.
-
-Then all you need to do is ensure that the main loop in the client
-library gets called. You can either do that by polling the connection
-using cli_transport_pending() and cli_request_receive_next() or you
-can use transport->idle.func to setup an idle function handler to call
-back to your main code. Either way, you can build a fully async
-application.
-
-In order to support all of this we have to make sure that when we
-write a piece of library code (SMB, MSRPC etc) that we build the
-separate _send() and _recv() functions. It really is worth the effort.
-
-Now about async in smbd, a much more complex topic.
-
-The SMB protocol is inherently async. Some functions (such as change
-notify) often don't return for hours, while hundreds of other
-functions pass through the socket. Take a look at the RAW-MUX test in
-the Samba4 smbtorture to see some really extreme examples of the sort
-of async operations that Windows supports. I particularly like the
-open/open/close sequence where the 2nd open (which conflicts with the
-first) succeeds because the subsequent close is answered out of order.
-
-In Samba3 we handled this stuff very badly. We had awful "pending
-request" queues that allocated full 128k packet buffers, and even with
-all that crap we got the semantics wrong. In Samba4 I intend to make
-sure we get this stuff right.
-
-So, how do we do this? We now have an async interface between smbd and
-the NTVFS backends. Whenever smbd calls into a backend the backend has
-an option of answer the request in a synchronous fashion if it wants
-to just like in Samba3, but it also has the option of answering the
-request asynchronously. The only backend that currently does this is
-the CIFS backend, but I hope the other backends will soon do this to.
-
-To make this work you need to do things like this in the backend::
-
-  req->control_flags |= REQ_CONTROL_ASYNC;
-
-that tells smbd that the backend has elected to reply later rather
-than replying immediately. The backend must *only* do this if
-req->async.send_fn is not NULL. If send_fn is NULL then it means that
-the smbd front end cannot handle this function being replied to in an
-async fashion.
-
-If the backend does this then it is up to the backend to call
-req->async.send_fn() when it is ready to reply. It the meantime smbd
-puts the call on hold and goes back to answering other requests on the
-socket.
-
-Inside smbd you will find that there is code to support this. The most
-obvious change is that smbd splits each SMB reply function into two
-parts - just like the client library has a _send() and _recv()
-function, so smbd has a _send() function and the parse function for
-each SMB.
-
-As an example go and have a look at reply_getatr_send() and
-reply_getatr() in smb_server/smb/reply.c. Read them? Good.
-
-Notice that reply_getatr() sets up the req->async structure to contain
-the send function. Thats how the backend gets to do an async reply, it
-calls this function when it is ready. Also notice that reply_getatr()
-only does the parsing of the request, and does not do the reply
-generation. That is done by the _send() function.
-
-
-NTVFS
------
-
-One of the most noticeable changes in Samba4 is the introduction of
-the NTVFS layer. This provided the initial motivation for the design
-of Samba4 and in many ways lies at the heart of the design.
-
-In Samba3 the main file serving process (smbd) combined the handling
-of the SMB protocol with the mapping to POSIX semantics in the same
-code. If you look in smbd/reply.c in Samba3 you see numerous places
-where POSIX assumptions are mixed tightly with SMB parsing code. We
-did have a VFS layer in Samba3, but it was a POSIX-like VFS layer, so
-no matter how you wrote a plugin you could not bypass the POSIX
-mapping decisions that had already been made before the VFS layer was
-called.
-
-In Samba4 things are quite different. All SMB parsing is performed in
-the smbd front end, then fully parsed requests are passed to the NTVFS
-backend. That backend makes any semantic mapping decisions and fills
-in the 'out' portion of the request. The front end is then responsible
-for putting those results into wire format and sending them to the
-client.
-
-Lets have a look at one of those request structures. Go and read the
-definition of "union smb_write" and "enum write_level" in
-libcli/raw/interfaces.h. (no, don't just skip reading it, really go
-and read it. Yes, that means you!).
-
-Notice the union? That's how Samba4 allows a single NTVFS backend
-interface to handle the several different ways of doing a write
-operation in the SMB protocol. Now lets look at one section of that
-union::
-
-	/* SMBwriteX interface */
-	struct {
-		enum smb_write_level level;
-		struct {
-			union smb_handle file;
-			uint64_t offset;
-			uint16_t wmode;
-			uint16_t remaining;
-			uint32_t count;
-			const uint8_t *data;
-		} in;
-		struct {
-			uint32_t nwritten;
-			uint16_t remaining;
-		} out;
-	} writex, generic;
-
-see the "in" and "out" sections? The "in" section is for parameters
-that the SMB client sends on the wire as part of the request. The smbd
-front end parse code parses the wire request and fills in all those
-parameters. It then calls the NTVFS interface which looks like this::
-
-  NTSTATUS (*write)(struct request_context *req, union smb_write *io);
-
-and the NTVFS backend does the write request. The backend then fills
-in the "out" section of the writex structure and gives the union back
-to the front end (either by returning, or if done in an async fashion
-then by calling the async send function. See the async discussion
-elsewhere in this document).
-
-The NTVFS backend knows which particular function is being requested
-by looking at io->generic.level. Notice that this enum is also
-repeated inside each of the sub-structures in the union, so the
-backend could just as easily look at io->writex.level and would get
-the same variable.
-
-Notice also that some levels (such as splwrite) don't have an "out"
-section. This happens because there is no return value apart from a
-status code from those SMB calls.
-
-So what about status codes? The status code is returned directly by
-the backend NTVFS interface when the call is performed
-synchronously. When performed asynchronously then the status code is
-put into req->async.status before the req->async.send_fn() callback is
-called.
-
-Currently the most complete NTVFS backend is the CIFS backend. I don't
-expect this backend will be used much in production, but it does
-provide the ideal test case for our NTVFS design. As it offers the
-full capabilities that are possible with a CIFS server we can be sure
-that we don't have any gaping holes in our APIs, and that the front
-end code is flexible enough to handle any advances in the NT style
-feature sets of Unix filesystems that make come along.
-
-
-Process Models
---------------
-
-In Samba3 we supported just one process model. It just so happens that
-the process model that Samba3 supported is the "right" one for most
-users, but there are situations where this model wasn't ideal.
-
-In Samba4 you can choose the smbd process model on the smbd command
-line.
-
-
-DCERPC binding strings
-----------------------
-
-When connecting to a dcerpc service you need to specify a binding
-string.
-
-The format is:
-
-  TRANSPORT:host[flags]
-
-where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP
-
-"host" is an IP or hostname or netbios name. If the binding string
-identifies the server side of an endpoint, "host" may be an empty
-string.
-
-"flags" can include a SMB pipe name if using the ncacn_np transport or
-a TCP port number if using the ncacn_ip_tcp transport, otherwise they
-will be auto-determined.
-
-other recognised flags are:
-
-  sign      : enable ntlmssp signing
-  seal      : enable ntlmssp sealing
-  spnego    : use SPNEGO instead of NTLMSSP authentication
-  krb5      : use KRB5 instead of NTLMSSP authentication
-  connect   : enable rpc connect level auth (auth, but no sign or seal)
-  validate  : enable the NDR validator
-  print     : enable debugging of the packets
-  bigendian : use bigendian RPC
-  padcheck  : check reply data for non-zero pad bytes
-
-
-Here are some examples:
-
-   ncacn_np:myserver
-   ncacn_np:myserver[samr]
-   ncacn_np:myserver[\pipe\samr]
-   ncacn_np:myserver[/pipe/samr]
-   ncacn_np:myserver[samr,sign,print]
-   ncacn_np:myserver[sign,spnego]
-   ncacn_np:myserver[\pipe\samr,sign,seal,bigendian]
-   ncacn_np:myserver[/pipe/samr,seal,validate]
-   ncacn_np:
-   ncacn_np:[/pipe/samr]
-   ncacn_ip_tcp:myserver
-   ncacn_ip_tcp:myserver[1024]
-   ncacn_ip_tcp:myserver[sign,seal]
-   ncacn_ip_tcp:myserver[spnego,seal]
-
-
-IDEA: Maybe extend UNC names like this?
-
- smbclient //server/share
- smbclient //server/share[sign,seal,spnego]
-
-DCERPC Handles
---------------
-The various handles that are used in the RPC servers should be created and
-fetch using the dcesrv_handle_* functions.
-
-Use dcesrv_handle_new(struct dcesrv_connection \*, uint8 handle_type) to obtain
-a new handle of the specified type. Handle types are unique within each
-pipe.
-
-The handle can later be fetched again using::
-
-	struct dcesrv_handle *dcesrv_handle_fetch(struct dcesrv_connection *dce_conn, struct policy_handle *p, uint8 handle_type)
-
-and destroyed by::
-
-	dcesrv_handle_destroy(struct dcesrv_handle *).
-
-User data should be stored in the 'data' member of the dcesrv_handle struct.
-
-
-MSRPC
------
-
-
-
- - ntvfs
- - testing
- - command line handling
- - libcli structure
- - posix reliance
- - uid/gid handling
- - process models
- - static data
- - msrpc
-
-
-don't zero structures! avoid ZERO_STRUCT() and talloc_zero()
-
-
-GMT vs TZ in printout of QFILEINFO timezones
-
-put in full UNC path in tconx
-
-test timezone handling by using a server in different zone from client
-
-do {} while (0) system
-
-NT_STATUS_IS_OK() is NOT the opposite of NT_STATUS_IS_ERR()
-
-need to implement secondary parts of trans2 and nttrans in server and
-client
-
-document access_mask in openx reply
-
-check all capabilities and flag1, flag2 fields (eg. EAs)
-
-large files -> pass thru levels
-
-setpathinfo is very fussy about null termination of the file name
-
-the overwrite flag doesn't seem to work on setpathinfo RENAME_INFORMATION
-
-END_OF_FILE_INFORMATION and ALLOCATION_INFORMATION don't seem to work
-via setpathinfo
-
-on w2k3 setpathinfo DISPOSITION_INFORMATION fails, but does have an
-effect. It leaves the file with SHARING_VIOLATION.
-
-on w2k3 trans2 setpathinfo with any invalid low numbered level causes
-the file to get into a state where DELETE_PENDING is reported, and the
-file cannot be deleted until you reboot
-
-trans2 qpathinfo doesn't see the delete_pending flag correctly, but
-qfileinfo does!
-
-get rid of strtok
-
-add programming documentation note about lp_set_cmdline()
-
-need to add a wct checking function in all client parsing code,
-similar to REQ_CHECK_WCT()
-
-need to make sure that NTTIME is a round number of seconds when
-converted from time_t
-
-not using a zero next offset in SMB_FILE_STREAM_INFORMATION for last
-entry causes explorer exception under win2000
-
-
-if the server sets the session key the same for a second SMB socket as
-an initial socket then the client will not re-authenticate, it will go
-straight to a tconx, skipping session setup and will use all the
-existing parameters! This allows two sockets with the same keys!?
-
-
-removed blocking lock code, we now queue the whole request the same as
-we queue any other pending request. This allows for things like a
-close() while a pending blocking lock is being processed to operate
-sanely.
-
-disabled change notify code
-
-disabled oplock code
-
-
-
-MILESTONES
-==========
-
-
-client library and test code
-----------------------------
-
-  convert client library to new structure
-  get smbtorture working
-  get smbclient working
-  expand client library for all requests
-  write per-request test suite
-  gentest randomised test suite
-  separate client code as a library for non-Samba use
-
-server code
------------
-  add remaining core SMB requests
-  add IPC layer
-  add nttrans layer
-  add rpc layer
-  fix auth models (share, server, rpc)
-  get net command working
-  connect CIFS backend to server level auth
-  get nmbd working
-  get winbindd working
-  reconnect printing code
-  restore removed smbd options
-  add smb.conf macro substitution code
-  add async backend notification 
-  add generic timer event mechanism
-
-clustering code
----------------
-
-  write CIFS backend
-  new server models (break 1-1)
-  test clustered models
-  add fulcrum statistics gathering
-
-docs
-----
-
-  conference paper
-  developer docs
-
-svn instructions
-
-Ideas
------
-
- - store all config in config.ldb
-
- - load from smb.conf if modtime changes
-
- - dump full system config with ldbsearch
-
- - will need the ability to form a ldif difference file
-
- - advanced web admin via a web ldb editor
-
- - normal web admin via web forms -> ldif
-
- - config.ldb will replace smb.conf, secrets.tdb, shares.tdb etc
-
- - subsystems in smbd will load config parameters for a share
-   using ldbsearch at tconx time
-
- - need a loadparm equivalent module that provides parameter defaults
-
- - start smbd like this:  "smbd -C tdb://etc/samba/config.ldb" or
-   "smbd -C ldapi://var/run/ldapi"
-
- - write a tool that generates a template ldap schema from an existing
-   ldb+tdb file
-
- - no need to HUP smbd to reload config
-
- - how to handle configuration comments? same problem as SWAT
-
-
-BUGS:
-  add a test case for last_entry_offset in trans2 find interfaces
-  conn refused
-  connect -> errno
-  no 137 resolution not possible
-  should not fallback to anon when pass supplied
-  should check pass-thu cap bit, and skip lots of tests
-  possibly allow the test suite to say "allow oversized replies" for trans2 and other calls
-  handle servers that don't have the setattre call in torture
-  add max file coponent length test and max path len test
-  check for alloc failure in all core reply.c and trans2.c code where allocation size depends on client parameter
-
-case-insenstive idea:
-  all filenames on disk lowercase
-  real case in extended attribute
-  keep cache of what dirs are all lowercase
-  when searching for name, don't search if dir is definately all lowercase
-  when creating file, use dnotify to tell if someone else creates at
-  same time
-
-solve del *.* idea:
-  make mangle cache dynamic size
-  fill during a dir scan
-  setup a timer
-  destroy cache after 30 sec
-  destroy if a 2nd dir scan happens on same dir
-

Modified: branches/samba/experimental/release-scripts/create-tarball
===================================================================
--- branches/samba/experimental/release-scripts/create-tarball	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/release-scripts/create-tarball	2011-07-28 16:06:15 UTC (rev 3863)
@@ -3,7 +3,6 @@
 ## option defaults
 OPT_BRANCH=""
 OPT_DOCSDIR=""
-OPT_TAG=""
 OPT_KEYID=""
 
 TOPDIR="`dirname $0`/.."
@@ -32,7 +31,6 @@
     echo "    --help             Print command usage"
     echo "    --branch <name>    Specify the branch to to create the archive file from"
     echo "    --copy-docs <dir>  Copy documentation from <dir> rather than building"
-    echo "    --tag <name>       Tag name for release"
     echo "    --keyid <email>    The GnuPG key ID used to sign the release tag"
     echo ""
 }
@@ -67,15 +65,6 @@
 		OPT_DOCSDIR="$1"
 		shift
 		;;
-	    --tag)
-		shift
-		if [ -z "$1" ]; then
-		    printUsage
-		    return 1
-		fi
-		OPT_TAG="$1"
-		shift
-		;;
 	    --keyid)
 		shift
 		if [ -z "$1" ]; then
@@ -145,13 +134,10 @@
 ##
 function createReleaseTag
 {
-    if [ -z "${OPT_TAG}" ]; then
-	echo "Tagging disabled"
-	return 0
-    fi
+    tagname="$1"
 
-    if [ "x`git tag -l ${OPT_TAG}`" != "x" ]; then
-	echo -n "Tag exists.  Do you wish to overwrite? (y/N): "
+    if [ "x`git tag -l ${tagname}`" != "x" ]; then
+	echo -n "Tag '${tagname}' exists.  Do you wish to overwrite? (y/N): "
 	read answer
 
 	if [ "x$answer" != "xy" ]; then
@@ -168,8 +154,8 @@
 	fi
     fi
 
-    git tag -u ${OPT_KEYID} ${OPT_TAG}
-    exitOnError $? "Failed to create tag"
+    git tag -u ${OPT_KEYID} ${tagname}
+    exitOnError $? "Failed to create tag '${tagname}'"
 
     return 0
 }
@@ -241,7 +227,7 @@
 
     popd
 
-    createReleaseTag
+    createReleaseTag "samba-${version}"
     exitOnError $? "Failed to create release tag"
 
     return 0

Modified: branches/samba/experimental/source3/Makefile.in
===================================================================
--- branches/samba/experimental/source3/Makefile.in	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/Makefile.in	2011-07-28 16:06:15 UTC (rev 3863)
@@ -346,7 +346,9 @@
 
 LIBCLI_SPOOLSS_OBJ = librpc/gen_ndr/ndr_spoolss_c.o \
 		     rpc_client/cli_spoolss.o \
-		     rpc_client/init_spoolss.o
+		     rpc_client/init_spoolss.o \
+		     rpc_client/cli_winreg_spoolss.o \
+		     printing/nt_printing_os2.o
 
 LIBCLI_EVENTLOG_OBJ = librpc/gen_ndr/ndr_eventlog_c.o
 
@@ -948,6 +950,7 @@
 		   printing/nt_printing.o \
 		   printing/nt_printing_tdb.o \
 		   printing/nt_printing_migrate.o \
+		   printing/nt_printing_migrate_internal.o \
 		   printing/nt_printing_ads.o \
 		   librpc/gen_ndr/ndr_ntprinting.o \
 		    ../librpc/ndr/ndr_ntprinting.o \
@@ -1185,7 +1188,7 @@
 	   rpc_client/init_samr.o \
 	   registry/reg_parse.o registry/reg_format.o \
 	   registry/reg_parse_internal.o registry/reg_import.o \
-	   lib/cbuf.o lib/srprs.o
+	   lib/cbuf.o lib/srprs.o printing/nt_printing_migrate.o
 
 # these are not processed by make proto
 NET_OBJ2 = utils/net_registry_util.o utils/net_help_common.o
@@ -1612,7 +1615,8 @@
 
 
 everything:: all libtalloc libsmbclient libnetapi debug2html smbfilter talloctort replacetort smbconftort modules torture \
-	$(EVERYTHING_PROGS)
+	$(EVERYTHING_PROGS) \
+	vfs_examples
 
 .SUFFIXES:
 .SUFFIXES: .c .o .lo
@@ -3542,3 +3546,14 @@
 
 bin/ndrdump4: $(BINARY_PREREQS)
 	$(MAKE) -f Makefile-smbtorture4 bin/ndrdump4
+
+.PHONY: vfs_examples
+
+vfs_examples:
+	( \
+	cd ../examples/VFS && \
+	./autogen.sh && \
+	./configure && \
+	make clean && \
+	make \
+	)

Modified: branches/samba/experimental/source3/VERSION
===================================================================
--- branches/samba/experimental/source3/VERSION	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/VERSION	2011-07-28 16:06:15 UTC (rev 3863)
@@ -56,7 +56,7 @@
 # e.g. SAMBA_VERSION_RC_RELEASE=1                      #
 #  ->  "3.0.0rc1"                                      #
 ########################################################
-SAMBA_VERSION_RC_RELEASE=2
+SAMBA_VERSION_RC_RELEASE=3
 
 ########################################################
 # To mark SVN snapshots this should be set to 'yes'    #

Modified: branches/samba/experimental/source3/auth/auth_server.c
===================================================================
--- branches/samba/experimental/source3/auth/auth_server.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/auth/auth_server.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -277,16 +277,23 @@
 					 const struct auth_usersupplied_info *user_info,
 					 struct auth_serversupplied_info **server_info)
 {
-	struct server_security_state *state = talloc_get_type_abort(
-		my_private_data, struct server_security_state);
-	struct cli_state *cli;
+	struct server_security_state *state = NULL;
+	struct cli_state *cli = NULL;
 	static bool tested_password_server = False;
 	static bool bad_password_server = False;
 	NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
 	bool locally_made_cli = False;
 
-	DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));
+	DEBUG(10, ("check_smbserver_security: Check auth for: [%s]\n",
+		user_info->mapped.account_name));
 
+	if (my_private_data == NULL) {
+		DEBUG(10,("check_smbserver_security: "
+			"password server is not connected\n"));
+		return NT_STATUS_LOGON_FAILURE;
+	}
+
+	state = talloc_get_type_abort(my_private_data, struct server_security_state);
 	cli = state->cli;
 
 	if (cli) {

Modified: branches/samba/experimental/source3/auth/pass_check.c
===================================================================
--- branches/samba/experimental/source3/auth/pass_check.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/auth/pass_check.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -518,9 +518,9 @@
 
 	for (i = offset; i < (len - (N - 1)); i++) {
 		char c = s[i];
-		if (!islower_ascii(c))
+		if (!islower_m(c))
 			continue;
-		s[i] = toupper_ascii(c);
+		s[i] = toupper_m(c);
 		nt_status = string_combinations2(s, i + 1, fn, N - 1,
 						 private_data);
 		if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {

Modified: branches/samba/experimental/source3/auth/proto.h
===================================================================
--- branches/samba/experimental/source3/auth/proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/auth/proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,4 +1,38 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  Password and authentication handling
+ *
+ *  Copyright (C) Andrew Tridgell		1992-2001
+ *  Copyright (C) Luke Kenneth Casson Leighton	1996-2000
+ *  Copyright (C) Jeremy Allison		1997-2001
+ *  Copyright (C) John H Terpsta		1999-2001
+ *  Copyright (C) Tim Potter			2000
+ *  Copyright (C) Andrew Bartlett		2001-2003
+ *  Copyright (C) Jelmer Vernooij		2002
+ *  Copyright (C) Rafal Szczesniak		2002
+ *  Copyright (C) Gerald Carter			2003
+ *  Copyright (C) Volker Lendecke		2006,2010
+ *  Copyright (C) Michael Adam			2007
+ *  Copyright (C) Dan Sledz			2009
+ *  Copyright (C) Simo Sorce			2010
+ *
+ *  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/>.
+ */
 
+#ifndef _AUTH_PROTO_H_
+#define _AUTH_PROTO_H_
+
 /* The following definitions come from auth/auth.c  */
 
 NTSTATUS smb_register_auth(int version, const char *name, auth_init_function init);
@@ -266,3 +300,5 @@
 				struct PAC_LOGON_INFO *logon_info,
 				bool mapped_to_guest,
 				struct auth_serversupplied_info **server_info);
+
+#endif /* _AUTH_PROTO_H_ */

Modified: branches/samba/experimental/source3/client/clitar.c
===================================================================
--- branches/samba/experimental/source3/client/clitar.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/client/clitar.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -490,7 +490,7 @@
 {
 	char *s1_0=s1;
 
-	while(*s1 && *s2 && (*s1 == *s2 || tolower_ascii(*s1) == tolower_ascii(*s2) ||
+	while(*s1 && *s2 && (*s1 == *s2 || tolower_m(*s1) == tolower_m(*s2) ||
 				(*s1 == '\\' && *s2=='/') || (*s1 == '/' && *s2=='\\'))) {
 		s1++; s2++;
 	}

Modified: branches/samba/experimental/source3/configure
===================================================================
--- branches/samba/experimental/source3/configure	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/configure	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1676,7 +1676,7 @@
                           ($ac_default_prefix/var/ncalrpc)
   --with-nmbdsocketdir=DIR
                           Where to put the nmbd socket directory
-                          (${lockdir}/.nmbd)
+                          ($ac_default_prefix/var/nmbd)
   --with-swatdir=DIR      Where to put SWAT files ($ac_default_prefix/swat)
   --with-configdir=DIR    Where to put configuration files ($libdir)
   --with-logfilebase=DIR  Where to put log files ($VARDIR)
@@ -3100,7 +3100,7 @@
 lockdir="\${VARDIR}/locks"
 piddir="\${VARDIR}/locks"
 ncalrpcdir="\${VARDIR}/ncalrpc"
-nmbdsocketdir="${lockdir}/.nmbd"
+nmbdsocketdir="\${VARDIR}/nmbd"
 test "${mandir}" || mandir="\${prefix}/man"
 logfilebase="\${VARDIR}"
 privatedir="\${prefix}/private"

Modified: branches/samba/experimental/source3/groupdb/proto.h
===================================================================
--- branches/samba/experimental/source3/groupdb/proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/groupdb/proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,4 +1,29 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  Group Mapping Database
+ *
+ *  Copyright (C) Andrew Tridgell              1992-2006
+ *  Copyright (C) Jean François Micouleau      1998-2001
+ *  Copyright (C) Gerald Carter                2006
+ *  Copyright (C) Volker Lendecke              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/>.
+ */
 
+#ifndef _GROUPDB_PROTO_H_
+#define _GROUPDB_PROTO_H_
+
 /* The following definitions come from groupdb/mapping.c  */
 
 NTSTATUS add_initial_entry(gid_t gid, const char *sid, enum lsa_SidType sid_name_use, const char *nt_name, const char *comment);
@@ -73,3 +98,5 @@
 /* The following definitions come from groupdb/mapping_tdb.c  */
 
 const struct mapping_backend *groupdb_tdb_init(void);
+
+#endif /* _GROUPDB_PROTO_H_ */

Modified: branches/samba/experimental/source3/include/async_smb.h
===================================================================
--- branches/samba/experimental/source3/include/async_smb.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/include/async_smb.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -51,6 +51,8 @@
 bool cli_smb_req_set_pending(struct tevent_req *req);
 uint16_t cli_smb_req_mid(struct tevent_req *req);
 void cli_smb_req_set_mid(struct tevent_req *req, uint16_t mid);
+uint32_t cli_smb_req_seqnum(struct tevent_req *req);
+void cli_smb_req_set_seqnum(struct tevent_req *req, uint32_t seqnum);
 struct tevent_req *cli_smb_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
 				struct cli_state *cli,
 				uint8_t smb_command, uint8_t additional_flags,

Modified: branches/samba/experimental/source3/include/krb5_env.h
===================================================================
--- branches/samba/experimental/source3/include/krb5_env.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/include/krb5_env.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,2 +1,26 @@
+/*
+   Samba Unix/Linux SMB client library
+
+   Copyright (C) 2010 Günther Deschner
+
+   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/>.
+*/
+
+#ifndef _INCLUDE_KRB5_ENV_H_
+#define _INCLUDE_KRB5_ENV_H_
+
 /* Kerberos environment variable names */
 #define KRB5_ENV_CCNAME "KRB5CCNAME"
+
+#endif /* _INCLUDE_KRB5_ENV_H_ */

Modified: branches/samba/experimental/source3/include/krb5_protos.h
===================================================================
--- branches/samba/experimental/source3/include/krb5_protos.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/include/krb5_protos.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,28 @@
+/*
+   Unix SMB/CIFS implementation.
+   simple kerberos5 routines for active directory
+   Copyright (C) Andrew Tridgell 2001
+   Copyright (C) Luke Howard 2002-2003
+   Copyright (C) Andrew Bartlett <abartlet at samba.org> 2005
+   Copyright (C) Guenther Deschner 2005-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/>.
+*/
+
+#ifndef _INCLUDE_KRB5_PROTOS_H_
+#define _INCLUDE_KRB5_PROTOS_H_
+
 struct PAC_DATA;
 struct PAC_SIGNATURE_DATA;
 
@@ -39,6 +64,8 @@
 #define initialize_krb5_error_table()
 #endif
 
+/* The following definitions come from libsmb/clikrb5.c  */
+
 /* Samba wrapper function for krb5 functionality. */
 bool setup_kaddr( krb5_address *pkaddr, struct sockaddr_storage *paddr);
 int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype, bool no_salt);
@@ -146,9 +173,9 @@
 			time_t *tgs_expire,
 			const char *impersonate_princ_s);
 
-/* The following definitions come from libsmb/clikrb5.c  */
-
 bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx,
 			   DATA_BLOB *edata,
 			   DATA_BLOB *edata_out);
 bool unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_pac_data);
+
+#endif /* _INCLUDE_KRB5_PROTOS_H_ */

Modified: branches/samba/experimental/source3/include/mangle.h
===================================================================
--- branches/samba/experimental/source3/include/mangle.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/include/mangle.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,22 @@
+/*
+   Unix SMB/CIFS implementation.
+   Name mangling interface
+   Copyright (C) Andrew Tridgell 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/>.
+*/
+
 #ifndef _MANGLE_H_
 #define _MANGLE_H_
 /*

Modified: branches/samba/experimental/source3/include/nt_printing.h
===================================================================
--- branches/samba/experimental/source3/include/nt_printing.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/include/nt_printing.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -126,15 +126,6 @@
 
 bool nt_printing_init(struct messaging_context *msg_ctx);
 
-WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
-				      const char *devicename,
-				      struct spoolss_DeviceMode **devmode);
-
-WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
-				      struct spoolss_security_descriptor **secdesc);
-
-WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername);
-
 const char *get_short_archi(const char *long_archi);
 
 bool print_access_check(const struct auth_serversupplied_info *server_info,
@@ -155,9 +146,6 @@
 
 WERROR check_published_printers(struct messaging_context *msg_ctx);
 
-bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
-			      struct spoolss_DriverInfo8 *_info8);
-
 bool printer_driver_in_use(TALLOC_CTX *mem_ctx,
 			   const struct auth_serversupplied_info *server_info,
 			   struct messaging_context *msg_ctx,

Modified: branches/samba/experimental/source3/include/proto.h
===================================================================
--- branches/samba/experimental/source3/include/proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/include/proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -329,8 +329,10 @@
 			      size_t *psize);
 bool set_share_security(const char *share_name, struct security_descriptor *psd);
 bool delete_share_security(const char *servicename);
-bool share_access_check(const struct security_token *token, const char *sharename,
-			uint32 desired_access);
+bool share_access_check(const struct security_token *token,
+			const char *sharename,
+			uint32 desired_access,
+			uint32_t *pgranted);
 bool parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, struct security_descriptor **ppsd);
 
 /* The following definitions come from lib/smbrun.c  */
@@ -1049,10 +1051,10 @@
 int strncmp_wa(const smb_ucs2_t *a, const char *b, size_t len);
 smb_ucs2_t *strpbrk_wa(const smb_ucs2_t *s, const char *p);
 smb_ucs2_t *strstr_wa(const smb_ucs2_t *s, const char *ins);
-int toupper_ascii(int c);
-int tolower_ascii(int c);
-int isupper_ascii(int c);
-int islower_ascii(int c);
+smb_ucs2_t toupper_w(smb_ucs2_t v);
+bool isupper_w(smb_ucs2_t v);
+smb_ucs2_t tolower_w(smb_ucs2_t v);
+bool islower_w(smb_ucs2_t v);
 
 /* The following definitions come from lib/version.c  */
 

Modified: branches/samba/experimental/source3/include/smb.h
===================================================================
--- branches/samba/experimental/source3/include/smb.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/include/smb.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -408,6 +408,7 @@
 	bool printer;
 	bool ipc;
 	bool read_only; /* Attributes for the current user of the share. */
+	uint32_t share_access;
 	/* Does this filesystem honor
 	   sub second timestamps on files
 	   and directories when setting time ? */

Modified: branches/samba/experimental/source3/include/smb_krb5.h
===================================================================
--- branches/samba/experimental/source3/include/smb_krb5.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/include/smb_krb5.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+   Unix SMB/CIFS implementation.
+   simple kerberos5 routines for active directory
+   Copyright (C) Andrew Tridgell 2001
+   Copyright (C) Luke Howard 2002-2003
+   Copyright (C) Andrew Bartlett <abartlet at samba.org> 2005
+   Copyright (C) Guenther Deschner 2005-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/>.
+*/
+
 #ifndef _HEADER_smb_krb5_h
 #define _HEADER_smb_krb5_h
 

Modified: branches/samba/experimental/source3/include/smb_ldap.h
===================================================================
--- branches/samba/experimental/source3/include/smb_ldap.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/include/smb_ldap.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+   Unix SMB/CIFS implementation.
+   Copyright (C) Andrew Tridgell 2001
+   Copyright (C) Remus Koos 2001
+   Copyright (C) Jim McDonough <jmcd at us.ibm.com> 2002
+   Copyright (C) Guenther Deschner 2005
+   Copyright (C) Gerald Carter 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/>.
+*/
+
 #ifndef _SMB_LDAP_H
 #define _SMB_LDAP_H
 

Modified: branches/samba/experimental/source3/include/version.h
===================================================================
--- branches/samba/experimental/source3/include/version.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/include/version.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,8 +2,8 @@
 #define SAMBA_VERSION_MAJOR 3
 #define SAMBA_VERSION_MINOR 6
 #define SAMBA_VERSION_RELEASE 0
-#define SAMBA_VERSION_RC_RELEASE 2
-#define SAMBA_VERSION_OFFICIAL_STRING "3.6.0rc2"
+#define SAMBA_VERSION_RC_RELEASE 3
+#define SAMBA_VERSION_OFFICIAL_STRING "3.6.0rc3"
 #ifdef SAMBA_VERSION_VENDOR_FUNCTION
 #  define SAMBA_VERSION_STRING SAMBA_VERSION_VENDOR_FUNCTION
 #else /* SAMBA_VERSION_VENDOR_FUNCTION */

Modified: branches/samba/experimental/source3/intl/lang_tdb.h
===================================================================
--- branches/samba/experimental/source3/intl/lang_tdb.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/intl/lang_tdb.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,7 +1,30 @@
+/*
+   Unix SMB/CIFS implementation.
+   tdb based replacement for gettext
+   Copyright (C) Andrew Tridgell 2001
 
+   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/>.
+*/
+
+#ifndef _INTL_LANG_TDB_H_
+#define _INTL_LANG_TDB_H_
+
 /* The following definitions come from intl/lang_tdb.c  */
 
 bool lang_tdb_init(const char *lang);
 const char *lang_msg(const char *msgid);
 void lang_msg_free(const char *msgstr);
 char *lang_tdb_current(void);
+
+#endif /* _INTL_LANG_TDB_H_ */

Modified: branches/samba/experimental/source3/lib/afs.c
===================================================================
--- branches/samba/experimental/source3/lib/afs.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/afs.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -23,6 +23,11 @@
 
 #define NO_ASN1_TYPEDEFS 1
 
+#include "secrets.h"
+#include "passdb.h"
+#include "auth.h"
+#include "../librpc/gen_ndr/ndr_netlogon.h"
+
 #include <afs/param.h>
 #include <afs/stds.h>
 #include <afs/afs.h>
@@ -231,16 +236,17 @@
 	}
 
 	afs_username = talloc_sub_advanced(ctx,
-				SNUM(conn), conn->session_info->unix_name,
+				lp_servicename(SNUM(conn)),
+				conn->session_info->unix_name,
 				conn->connectpath, conn->session_info->utok.gid,
 				conn->session_info->sanitized_username,
-				pdb_get_domain(conn->session_info->sam_account),
+				conn->session_info->info3->base.domain.string,
 				afs_username);
 	if (!afs_username) {
 		return false;
 	}
 
-	user_sid = &conn->session_info->security_token->user_sids[0];
+	user_sid = &conn->session_info->security_token->sids[0];
 	afs_username = talloc_string_sub(talloc_tos(),
 					afs_username,
 					"%s",

Modified: branches/samba/experimental/source3/lib/afs_settoken.c
===================================================================
--- branches/samba/experimental/source3/lib/afs_settoken.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/afs_settoken.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -23,6 +23,8 @@
 
 #define NO_ASN1_TYPEDEFS 1
 
+#include "system/filesys.h"
+
 #include <afs/param.h>
 #include <afs/stds.h>
 #include <afs/afs.h>

Modified: branches/samba/experimental/source3/lib/charcnv.c
===================================================================
--- branches/samba/experimental/source3/lib/charcnv.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/charcnv.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1132,7 +1132,7 @@
 		   terminated if STR_TERMINATE isn't set. */
 
 		for (i = 0; i < (ret / 2) && i < (dest_len / 2) && dest_ucs2[i]; i++) {
-			smb_ucs2_t v = toupper_m(dest_ucs2[i]);
+			smb_ucs2_t v = toupper_w(dest_ucs2[i]);
 			if (v != dest_ucs2[i]) {
 				dest_ucs2[i] = v;
 			}

Modified: branches/samba/experimental/source3/lib/eventlog/proto.h
===================================================================
--- branches/samba/experimental/source3/lib/eventlog/proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/eventlog/proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,4 +1,29 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  Eventlog utility  routines
+ *
+ *  Copyright (C) Marcin Krzysztof Porwit    2005
+ *  Copyright (C) Brian Moran                2005
+ *  Copyright (C) Gerald (Jerry) Carter      2005
+ *  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
+ *  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/>.
+ */
 
+#ifndef _LIB_EVENTLOG_PROTO_H_
+#define _LIB_EVENTLOG_PROTO_H_
+
 /* The following definitions come from lib/eventlog/eventlog.c  */
 
 TDB_CONTEXT *elog_init_tdb( char *tdbfilename );
@@ -33,3 +58,5 @@
 				  ELOG_TDB *etdb,
 				  DATA_BLOB *blob_p,
 				  uint32_t *num_records_p);
+
+#endif /* _LIB_EVENTLOG_PROTO_H_ */

Modified: branches/samba/experimental/source3/lib/idmap_cache.h
===================================================================
--- branches/samba/experimental/source3/lib/idmap_cache.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/idmap_cache.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,26 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * ID Mapping Cache
+ *
+ * Copyright (C) Volker Lendecke	2008
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 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/>.
+ */
+
+#ifndef _LIB_IDMAP_CACHE_H_
+#define _LIB_IDMAP_CACHE_H_
+
 /* The following definitions come from lib/idmap_cache.c  */
 
 bool idmap_cache_find_sid2uid(const struct dom_sid *sid, uid_t *puid,
@@ -12,3 +35,5 @@
 bool idmap_cache_del_uid(uid_t uid);
 bool idmap_cache_del_gid(gid_t gid);
 bool idmap_cache_del_sid(const struct dom_sid *sid);
+
+#endif /* _LIB_IDMAP_CACHE_H_ */

Modified: branches/samba/experimental/source3/lib/ms_fnmatch.c
===================================================================
--- branches/samba/experimental/source3/lib/ms_fnmatch.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/ms_fnmatch.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -129,7 +129,7 @@
 				if (is_case_sensitive) {
 					return -1;
 				}
-				if (toupper_m(c) != toupper_m(*n)) {
+				if (toupper_w(c) != toupper_w(*n)) {
 					return -1;
 				}
 			}

Modified: branches/samba/experimental/source3/lib/netapi/libnetapi.h
===================================================================
--- branches/samba/experimental/source3/lib/netapi/libnetapi.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/netapi/libnetapi.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,22 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  NetApi Support
+ *  Copyright (C) Guenther Deschner 2007-2008
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 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/>.
+ */
+
 #ifndef __LIBNETAPI_LIBNETAPI__
 #define __LIBNETAPI_LIBNETAPI__
 NET_API_STATUS NetJoinDomain(const char * server /* [in] [unique] */,

Modified: branches/samba/experimental/source3/lib/privileges.h
===================================================================
--- branches/samba/experimental/source3/lib/privileges.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/privileges.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,28 @@
+/*
+   Unix SMB/CIFS implementation.
+   Privileges handling functions
+   Copyright (C) Jean François Micouleau	1998-2001
+   Copyright (C) Simo Sorce			2002-2003
+   Copyright (C) Gerald (Jerry) Carter          2005
+   Copyright (C) Michael Adam			2007
+
+   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/>.
+*/
+
+#ifndef _LIB_PRIVILEGES_H_
+#define _LIB_PRIVILEGES_H_
+
 #include "../libcli/security/privileges.h"
 
 /* The following definitions come from lib/privileges.c  */
@@ -16,3 +41,5 @@
 NTSTATUS privilege_delete_account(const struct dom_sid *sid);
 bool is_privileged_sid( const struct dom_sid *sid );
 bool grant_all_privileges( const struct dom_sid *sid );
+
+#endif /* _LIB_PRIVILEGES_H_ */

Modified: branches/samba/experimental/source3/lib/sharesec.c
===================================================================
--- branches/samba/experimental/source3/lib/sharesec.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/sharesec.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -410,8 +410,10 @@
  Can this user access with share with the required permissions ?
 ********************************************************************/
 
-bool share_access_check(const struct security_token *token, const char *sharename,
-			uint32 desired_access)
+bool share_access_check(const struct security_token *token,
+			const char *sharename,
+			uint32 desired_access,
+			uint32_t *pgranted)
 {
 	uint32 granted;
 	NTSTATUS status;
@@ -428,6 +430,10 @@
 
 	TALLOC_FREE(psd);
 
+	if (pgranted != NULL) {
+		*pgranted = granted;
+	}
+
 	return NT_STATUS_IS_OK(status);
 }
 

Modified: branches/samba/experimental/source3/lib/smbldap.c
===================================================================
--- branches/samba/experimental/source3/lib/smbldap.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/smbldap.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1165,8 +1165,9 @@
 /*******************************************************************
  connect to the ldap server under system privilege.
 ******************************************************************/
-static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_struct)
+static int smbldap_connect_system(struct smbldap_state *ldap_state)
 {
+	LDAP *ldap_struct = ldap_state->ldap_struct;
 	int rc;
 	int version;
 
@@ -1177,7 +1178,8 @@
 		/* get the default dn and password only if they are not set already */
 		if (!fetch_ldap_pw(&bind_dn, &bind_secret)) {
 			DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
-			return LDAP_INVALID_CREDENTIALS;
+			rc = LDAP_INVALID_CREDENTIALS;
+			goto done;
 		}
 		smbldap_set_creds(ldap_state, false, bind_dn, bind_secret);
 		SAFE_FREE(bind_dn);
@@ -1223,7 +1225,7 @@
 			       ld_error ? ld_error : "(unknown)"));
 		SAFE_FREE(ld_error);
 		ldap_state->num_failures++;
-		return rc;
+		goto done;
 	}
 
 	ldap_state->num_failures = 0;
@@ -1238,6 +1240,11 @@
 	DEBUG(3, ("ldap_connect_system: successful connection to the LDAP server\n"));
 	DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n", 
 		ldap_state->paged_results ? "does" : "does not"));
+done:
+	if (rc != 0) {
+		ldap_unbind(ldap_struct);
+		ldap_state->ldap_struct = NULL;
+	}
 	return rc;
 }
 
@@ -1292,9 +1299,7 @@
 		return rc;
 	}
 
-	if ((rc = smbldap_connect_system(ldap_state, ldap_state->ldap_struct))) {
-		ldap_unbind(ldap_state->ldap_struct);
-		ldap_state->ldap_struct = NULL;
+	if ((rc = smbldap_connect_system(ldap_state))) {
 		return rc;
 	}
 
@@ -1306,7 +1311,7 @@
 
 	if (ldap_state->event_context != NULL) {
 		ldap_state->idle_event = event_add_timed(
-			ldap_state->event_context, NULL,
+			ldap_state->event_context, ldap_state,
 			timeval_current_ofs(SMBLDAP_IDLE_TIME, 0),
 			smbldap_idle_fn, ldap_state);
 	}
@@ -1331,6 +1336,8 @@
 
 	smbldap_delete_state(ldap_state);
 
+	TALLOC_FREE(ldap_state->idle_event);
+
 	DEBUG(5,("The connection to the LDAP server was closed\n"));
 	/* maybe free the results here --metze */
 
@@ -1819,7 +1826,7 @@
 
 		/* this needs to be made monotonic clock aware inside tevent: */
 		state->idle_event = event_add_timed(
-			event_ctx, NULL,
+			event_ctx, state,
 			timeval_add(&now_abs, SMBLDAP_IDLE_TIME, 0),
 			smbldap_idle_fn,
 			private_data);
@@ -1845,14 +1852,18 @@
 	SAFE_FREE((*ldap_state)->bind_dn);
 	SAFE_FREE((*ldap_state)->bind_secret);
 
-	TALLOC_FREE((*ldap_state)->idle_event);
+	TALLOC_FREE(*ldap_state);
 
-	*ldap_state = NULL;
-
 	/* No need to free any further, as it is talloc()ed */
 }
 
+static int smbldap_state_destructor(struct smbldap_state *state)
+{
+	smbldap_free_struct(&state);
+	return 0;
+}
 
+
 /**********************************************************************
  Intitalise the 'general' ldap structures, on which ldap operations may be conducted
  *********************************************************************/
@@ -1875,6 +1886,7 @@
 
 	(*smbldap_state)->event_context = event_ctx;
 
+	talloc_set_destructor(*smbldap_state, smbldap_state_destructor);
 	return NT_STATUS_OK;
 }
 

Modified: branches/samba/experimental/source3/lib/username.c
===================================================================
--- branches/samba/experimental/source3/lib/username.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/username.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -196,9 +196,9 @@
 
 	for (i=offset;i<(len-(N-1));i++) {
 		char c = s[i];
-		if (!islower_ascii((int)c))
+		if (!islower_m((int)c))
 			continue;
-		s[i] = toupper_ascii(c);
+		s[i] = toupper_m(c);
 		ret = uname_string_combinations2(s, mem_ctx, i+1, fn, N-1);
 		if(ret)
 			return(ret);

Modified: branches/samba/experimental/source3/lib/util_str.c
===================================================================
--- branches/samba/experimental/source3/lib/util_str.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/util_str.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -243,7 +243,7 @@
 			psz1++;
 		while (isspace((int)*psz2))
 			psz2++;
-		if (toupper_ascii(*psz1) != toupper_ascii(*psz2) ||
+		if (toupper_m(*psz1) != toupper_m(*psz2) ||
 				*psz1 == '\0' || *psz2 == '\0')
 			break;
 		psz1++;
@@ -460,7 +460,7 @@
 	}
 
 	for(p = tmp; *p != 0; p++) {
-		if(isupper_m(*p)) {
+		if(isupper_w(*p)) {
 			break;
 		}
 	}
@@ -485,7 +485,7 @@
 	}
 
 	for(p = tmp; *p != 0; p++) {
-		if(islower_m(*p)) {
+		if(islower_w(*p)) {
 			break;
 		}
 	}
@@ -1406,7 +1406,7 @@
 	   (ie. they match for the first 128 chars) */
 
 	while (*s && !(((unsigned char)s[0]) & 0x80)) {
-		*s = tolower_ascii((unsigned char)*s);
+		*s = tolower_m((unsigned char)*s);
 		s++;
 	}
 

Modified: branches/samba/experimental/source3/lib/util_unistr.c
===================================================================
--- branches/samba/experimental/source3/lib/util_unistr.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/lib/util_unistr.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -254,7 +254,7 @@
 	bool ret = False;
 
 	while (*(COPY_UCS2_CHAR(&cp,s))) {
-		smb_ucs2_t v = tolower_m(cp);
+		smb_ucs2_t v = tolower_w(cp);
 		if (v != cp) {
 			COPY_UCS2_CHAR(s,&v);
 			ret = True;
@@ -276,7 +276,7 @@
 	smb_ucs2_t cp;
 	bool ret = False;
 	while (*(COPY_UCS2_CHAR(&cp,s))) {
-		smb_ucs2_t v = toupper_m(cp);
+		smb_ucs2_t v = toupper_w(cp);
 		if (v != cp) {
 			COPY_UCS2_CHAR(s,&v);
 			ret = True;
@@ -334,11 +334,11 @@
 {
 	smb_ucs2_t cpa, cpb;
 
-	while ((*COPY_UCS2_CHAR(&cpb,b)) && toupper_m(*(COPY_UCS2_CHAR(&cpa,a))) == toupper_m(cpb)) {
+	while ((*COPY_UCS2_CHAR(&cpb,b)) && toupper_w(*(COPY_UCS2_CHAR(&cpa,a))) == toupper_w(cpb)) {
 		a++;
 		b++;
 	}
-	return (tolower_m(*(COPY_UCS2_CHAR(&cpa,a))) - tolower_m(*(COPY_UCS2_CHAR(&cpb,b))));
+	return (tolower_w(*(COPY_UCS2_CHAR(&cpa,a))) - tolower_w(*(COPY_UCS2_CHAR(&cpb,b))));
 }
 
 /*******************************************************************
@@ -350,12 +350,12 @@
 	smb_ucs2_t cpa, cpb;
 	size_t n = 0;
 
-	while ((n < len) && *COPY_UCS2_CHAR(&cpb,b) && (toupper_m(*(COPY_UCS2_CHAR(&cpa,a))) == toupper_m(cpb))) {
+	while ((n < len) && *COPY_UCS2_CHAR(&cpb,b) && (toupper_w(*(COPY_UCS2_CHAR(&cpa,a))) == toupper_w(cpb))) {
 		a++;
 		b++;
 		n++;
 	}
-	return (len - n)?(tolower_m(*(COPY_UCS2_CHAR(&cpa,a))) - tolower_m(*(COPY_UCS2_CHAR(&cpb,b)))):0;
+	return (len - n)?(tolower_w(*(COPY_UCS2_CHAR(&cpa,a))) - tolower_w(*(COPY_UCS2_CHAR(&cpb,b)))):0;
 }
 
 /*******************************************************************
@@ -607,40 +607,36 @@
 	return NULL;
 }
 
-/*************************************************************
- ascii only toupper - saves the need for smbd to be in C locale.
-*************************************************************/
-
-int toupper_ascii(int c)
+smb_ucs2_t toupper_w(smb_ucs2_t v)
 {
-	smb_ucs2_t uc = toupper_m(UCS2_CHAR(c));
-	return UCS2_TO_CHAR(uc);
+	smb_ucs2_t ret;
+	/* LE to native. */
+	codepoint_t cp = SVAL(&v,0);
+	cp = toupper_m(cp);
+	/* native to LE. */
+	SSVAL(&ret,0,cp);
+	return ret;
 }
 
-/*************************************************************
- ascii only tolower - saves the need for smbd to be in C locale.
-*************************************************************/
-
-int tolower_ascii(int c)
+bool isupper_w(smb_ucs2_t v)
 {
-	smb_ucs2_t uc = tolower_m(UCS2_CHAR(c));
-	return UCS2_TO_CHAR(uc);
+	codepoint_t cp = SVAL(&v,0);
+	return isupper_m(cp);
 }
 
-/*************************************************************
- ascii only isupper - saves the need for smbd to be in C locale.
-*************************************************************/
-
-int isupper_ascii(int c)
+smb_ucs2_t tolower_w(smb_ucs2_t v)
 {
-	return isupper_m(UCS2_CHAR(c));
+	smb_ucs2_t ret;
+	/* LE to native. */
+	codepoint_t cp = SVAL(&v,0);
+	cp = tolower_m(cp);
+	/* native to LE. */
+	SSVAL(&ret,0,cp);
+	return ret;
 }
 
-/*************************************************************
- ascii only islower - saves the need for smbd to be in C locale.
-*************************************************************/
-
-int islower_ascii(int c)
+bool islower_w(smb_ucs2_t v)
 {
-	return islower_m(UCS2_CHAR(c));
+	codepoint_t cp = SVAL(&v,0);
+	return islower_m(cp);
 }

Modified: branches/samba/experimental/source3/libads/ads_ldap_protos.h
===================================================================
--- branches/samba/experimental/source3/libads/ads_ldap_protos.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libads/ads_ldap_protos.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,4 +1,30 @@
 /*
+   Unix SMB/CIFS implementation.
+   ads (active directory) utility library
+   Copyright (C) Andrew Tridgell 2001
+   Copyright (C) Remus Koos 2001
+   Copyright (C) Jim McDonough <jmcd at us.ibm.com> 2002
+   Copyright (C) Guenther Deschner 2005
+   Copyright (C) Gerald Carter 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/>.
+*/
+
+#ifndef _LIBADS_ADS_LDAP_PROTOS_H_
+#define _LIBADS_ADS_LDAP_PROTOS_H_
+
+/*
  * Prototypes for ads
  */
 
@@ -112,3 +138,5 @@
 				TALLOC_CTX *mem_ctx,
 				char ***ous,
 				size_t *num_ous);
+
+#endif /* _LIBADS_ADS_LDAP_PROTOS_H_ */

Modified: branches/samba/experimental/source3/libads/ads_proto.h
===================================================================
--- branches/samba/experimental/source3/libads/ads_proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libads/ads_proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,37 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  ads (active directory) utility library
+ *
+ *  Copyright (C) Andrew Bartlett			2001
+ *  Copyright (C) Andrew Tridgell			2001
+ *  Copyright (C) Remus Koos (remuskoos at yahoo.com)	2001
+ *  Copyright (C) Alexey Kotovich			2002
+ *  Copyright (C) Jim McDonough <jmcd at us.ibm.com>	2002-2003
+ *  Copyright (C) Luke Howard				2003
+ *  Copyright (C) Guenther Deschner			2003-2008
+ *  Copyright (C) Rakesh Patel				2004
+ *  Copyright (C) Dan Perry				2004
+ *  Copyright (C) Jeremy Allison			2004
+ *  Copyright (C) Gerald Carter				2006
+ *  Copyright (C) Stefan Metzmacher			2007
+ *
+ *  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/>.
+ */
+
+#ifndef _LIBADS_ADS_PROTO_H_
+#define _LIBADS_ADS_PROTO_H_
+
 /* The following definitions come from libads/ads_struct.c  */
 
 char *ads_build_path(const char *realm, const char *sep, const char *field, int reverse);
@@ -152,3 +186,5 @@
 /* The following definitions come from libads/util.c  */
 
 ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_principal);
+
+#endif /* _LIBADS_ADS_PROTO_H_ */

Modified: branches/samba/experimental/source3/libads/ads_status.h
===================================================================
--- branches/samba/experimental/source3/libads/ads_status.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libads/ads_status.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+   Unix SMB/CIFS implementation.
+   ads (active directory) utility library
+   Copyright (C) Andrew Tridgell 2001
+   Copyright (C) Remus Koos 2001
+   Copyright (C) Andrew Bartlett 2001
+
+
+   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/>.
+*/
+
 #ifndef _LIBADS_ADS_STATUS_H_
 #define _LIBADS_ADS_STATUS_H_
 

Modified: branches/samba/experimental/source3/libads/cldap.h
===================================================================
--- branches/samba/experimental/source3/libads/cldap.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libads/cldap.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,28 @@
+/*
+   Samba Unix/Linux SMB client library
+   net ads cldap functions
+   Copyright (C) 2001 Andrew Tridgell (tridge at samba.org)
+   Copyright (C) 2003 Jim McDonough (jmcd at us.ibm.com)
+   Copyright (C) 2008 Guenther Deschner (gd at samba.org)
+   Copyright (C) 2009 Stefan Metzmacher (metze at 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
+   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/>.
+*/
+
+#ifndef _LIBADS_CLDAP_H_
+#define _LIBADS_CLDAP_H_
+
 #include "../libcli/netlogon/netlogon.h"
 
 /* The following definitions come from libads/cldap.c  */
@@ -10,3 +35,5 @@
 			  const char *server,
 			  const char *realm,
 			  struct NETLOGON_SAM_LOGON_RESPONSE_EX *reply5);
+
+#endif /* _LIBADS_CLDAP_H_ */

Modified: branches/samba/experimental/source3/libads/kerberos_proto.h
===================================================================
--- branches/samba/experimental/source3/libads/kerberos_proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libads/kerberos_proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,35 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  kerberos utility library
+ *
+ *  Copyright (C) Andrew Tridgell			2001
+ *  Copyright (C) Remus Koos (remuskoos at yahoo.com)	2001
+ *  Copyright (C) Luke Howard				2002-2003
+ *  Copyright (C) Jim McDonough <jmcd at us.ibm.com>	2003
+ *  Copyright (C) Guenther Deschner			2003-2008
+ *  Copyright (C) Andrew Bartlett <abartlet at samba.org>	2004-2005
+ *  Copyright (C) Jeremy Allison			2004,2007
+ *  Copyright (C) Stefan Metzmacher			2004-2005
+ *  Copyright (C) Nalin Dahyabhai <nalin at redhat.com>	2004
+ *  Copyright (C) Gerald Carter				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/>.
+ */
+
+#ifndef _LIBADS_KERBEROS_PROTO_H_
+#define _LIBADS_KERBEROS_PROTO_H_
+
 struct PAC_LOGON_INFO;
 
 #include "libads/ads_status.h"
@@ -69,3 +101,5 @@
 				 const char *auth_principal, const char *auth_password,
 				 const char *target_principal, const char *new_password,
 				 int time_offset);
+
+#endif /* _LIBADS_KERBEROS_PROTO_H_ */

Modified: branches/samba/experimental/source3/libads/ldap_schema.h
===================================================================
--- branches/samba/experimental/source3/libads/ldap_schema.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libads/ldap_schema.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,26 @@
+/*
+   Unix SMB/CIFS implementation.
+   ads (active directory) utility library
+   Copyright (C) Guenther Deschner 2005-2007
+   Copyright (C) Gerald (Jerry) Carter 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/>.
+*/
+
+#ifndef _LIBADS_LDAP_SCHEMA_H_
+#define _LIBADS_LDAP_SCHEMA_H_
+
 /* used to remember the names of the posix attributes in AD */
 /* see the rfc2307 & sfu nss backends */
 
@@ -55,3 +78,5 @@
 					  ADS_STRUCT *ads,
 					  enum wb_posix_mapping map_type,
 					  struct posix_schema **s ) ;
+
+#endif /* _LIBADS_LDAP_SCHEMA_H_ */

Modified: branches/samba/experimental/source3/libgpo/gpo_proto.h
===================================================================
--- branches/samba/experimental/source3/libgpo/gpo_proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libgpo/gpo_proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,4 +1,26 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  Group Policy Object Support
+ *
+ *  Copyright (C) Guenther Deschner 2006-2008
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 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/>.
+ */
 
+#ifndef _LIBGPO_GPO_PROTO_H_
+#define _LIBGPO_GPO_PROTO_H_
+
 /* The following definitions come from libgpo/gpo_filesync.c  */
 
 NTSTATUS gpo_copy_file(TALLOC_CTX *mem_ctx,
@@ -75,3 +97,5 @@
 				struct gp_registry_entry *entry,
 				const struct security_token *token,
 				uint32_t flags);
+
+#endif /* _LIBGPO_GPO_PROTO_H_ */

Modified: branches/samba/experimental/source3/libnet/libnet_join.h
===================================================================
--- branches/samba/experimental/source3/libnet/libnet_join.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libnet/libnet_join.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,26 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  libnet Join Support
+ *  Copyright (C) Gerald (Jerry) Carter 2006
+ *  Copyright (C) Guenther Deschner 2007-2008
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 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/>.
+ */
+
+#ifndef _LIBNET_LIBNET_JOIN_H_
+#define _LIBNET_LIBNET_JOIN_H_
+
 /* The following definitions come from libnet/libnet_join.c  */
 
 NTSTATUS libnet_join_ok(const char *netbios_domain_name,
@@ -11,3 +34,5 @@
 		   struct libnet_JoinCtx *r);
 WERROR libnet_Unjoin(TALLOC_CTX *mem_ctx,
 		     struct libnet_UnjoinCtx *r);
+
+#endif /* _LIBNET_LIBNET_JOIN_H_ */

Modified: branches/samba/experimental/source3/librpc/gen_ndr/ndr_wbint.c
===================================================================
--- branches/samba/experimental/source3/librpc/gen_ndr/ndr_wbint.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/librpc/gen_ndr/ndr_wbint.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2349,6 +2349,10 @@
 static enum ndr_err_code ndr_push_wbint_LookupRids(struct ndr_push *ndr, int flags, const struct wbint_LookupRids *r)
 {
 	if (flags & NDR_IN) {
+		if (r->in.domain_sid == NULL) {
+			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+		}
+		NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, r->in.domain_sid));
 		if (r->in.rids == NULL) {
 			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
 		}
@@ -2377,6 +2381,7 @@
 static enum ndr_err_code ndr_pull_wbint_LookupRids(struct ndr_pull *ndr, int flags, struct wbint_LookupRids *r)
 {
 	uint32_t _ptr_domain_name;
+	TALLOC_CTX *_mem_save_domain_sid_0;
 	TALLOC_CTX *_mem_save_rids_0;
 	TALLOC_CTX *_mem_save_domain_name_0;
 	TALLOC_CTX *_mem_save_domain_name_1;
@@ -2385,6 +2390,13 @@
 		ZERO_STRUCT(r->out);
 
 		if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+			NDR_PULL_ALLOC(ndr, r->in.domain_sid);
+		}
+		_mem_save_domain_sid_0 = NDR_PULL_GET_MEM_CTX(ndr);
+		NDR_PULL_SET_MEM_CTX(ndr, r->in.domain_sid, LIBNDR_FLAG_REF_ALLOC);
+		NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, r->in.domain_sid));
+		NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domain_sid_0, LIBNDR_FLAG_REF_ALLOC);
+		if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
 			NDR_PULL_ALLOC(ndr, r->in.rids);
 		}
 		_mem_save_rids_0 = NDR_PULL_GET_MEM_CTX(ndr);
@@ -2444,6 +2456,10 @@
 	if (flags & NDR_IN) {
 		ndr_print_struct(ndr, "in", "wbint_LookupRids");
 		ndr->depth++;
+		ndr_print_ptr(ndr, "domain_sid", r->in.domain_sid);
+		ndr->depth++;
+		ndr_print_dom_sid(ndr, "domain_sid", r->in.domain_sid);
+		ndr->depth--;
 		ndr_print_ptr(ndr, "rids", r->in.rids);
 		ndr->depth++;
 		ndr_print_wbint_RidArray(ndr, "rids", r->in.rids);

Modified: branches/samba/experimental/source3/librpc/gen_ndr/ndr_wbint_c.c
===================================================================
--- branches/samba/experimental/source3/librpc/gen_ndr/ndr_wbint_c.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/librpc/gen_ndr/ndr_wbint_c.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -4235,6 +4235,7 @@
 struct tevent_req *dcerpc_wbint_LookupRids_send(TALLOC_CTX *mem_ctx,
 						struct tevent_context *ev,
 						struct dcerpc_binding_handle *h,
+						struct dom_sid *_domain_sid /* [in] [ref] */,
 						struct wbint_RidArray *_rids /* [in] [ref] */,
 						const char **_domain_name /* [out] [ref,charset(UTF8)] */,
 						struct wbint_Principals *_names /* [out] [ref] */)
@@ -4251,6 +4252,7 @@
 	state->out_mem_ctx = NULL;
 
 	/* In parameters */
+	state->orig.in.domain_sid = _domain_sid;
 	state->orig.in.rids = _rids;
 
 	/* Out parameters */
@@ -4337,6 +4339,7 @@
 
 NTSTATUS dcerpc_wbint_LookupRids(struct dcerpc_binding_handle *h,
 				 TALLOC_CTX *mem_ctx,
+				 struct dom_sid *_domain_sid /* [in] [ref] */,
 				 struct wbint_RidArray *_rids /* [in] [ref] */,
 				 const char **_domain_name /* [out] [ref,charset(UTF8)] */,
 				 struct wbint_Principals *_names /* [out] [ref] */,
@@ -4346,6 +4349,7 @@
 	NTSTATUS status;
 
 	/* In parameters */
+	r.in.domain_sid = _domain_sid;
 	r.in.rids = _rids;
 
 	status = dcerpc_wbint_LookupRids_r(h, mem_ctx, &r);

Modified: branches/samba/experimental/source3/librpc/gen_ndr/ndr_wbint_c.h
===================================================================
--- branches/samba/experimental/source3/librpc/gen_ndr/ndr_wbint_c.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/librpc/gen_ndr/ndr_wbint_c.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -410,6 +410,7 @@
 struct tevent_req *dcerpc_wbint_LookupRids_send(TALLOC_CTX *mem_ctx,
 						struct tevent_context *ev,
 						struct dcerpc_binding_handle *h,
+						struct dom_sid *_domain_sid /* [in] [ref] */,
 						struct wbint_RidArray *_rids /* [in] [ref] */,
 						const char **_domain_name /* [out] [ref,charset(UTF8)] */,
 						struct wbint_Principals *_names /* [out] [ref] */);
@@ -418,6 +419,7 @@
 				      NTSTATUS *result);
 NTSTATUS dcerpc_wbint_LookupRids(struct dcerpc_binding_handle *h,
 				 TALLOC_CTX *mem_ctx,
+				 struct dom_sid *_domain_sid /* [in] [ref] */,
 				 struct wbint_RidArray *_rids /* [in] [ref] */,
 				 const char **_domain_name /* [out] [ref,charset(UTF8)] */,
 				 struct wbint_Principals *_names /* [out] [ref] */,

Modified: branches/samba/experimental/source3/librpc/gen_ndr/wbint.h
===================================================================
--- branches/samba/experimental/source3/librpc/gen_ndr/wbint.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/librpc/gen_ndr/wbint.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -307,6 +307,7 @@
 
 struct wbint_LookupRids {
 	struct {
+		struct dom_sid *domain_sid;/* [ref] */
 		struct wbint_RidArray *rids;/* [ref] */
 	} in;
 

Modified: branches/samba/experimental/source3/librpc/idl/wbint.idl
===================================================================
--- branches/samba/experimental/source3/librpc/idl/wbint.idl	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/librpc/idl/wbint.idl	2011-07-28 16:06:15 UTC (rev 3863)
@@ -164,6 +164,7 @@
 	);
 
     NTSTATUS wbint_LookupRids(
+	[in] dom_sid *domain_sid,
 	[in] wbint_RidArray *rids,
 	[out,string,charset(UTF8)] char **domain_name,
 	[out] wbint_Principals *names

Modified: branches/samba/experimental/source3/librpc/ndr/util.h
===================================================================
--- branches/samba/experimental/source3/librpc/ndr/util.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/librpc/ndr/util.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,4 +1,29 @@
+/*
+   Unix SMB/CIFS implementation.
 
+   libndr interface
+
+   Copyright (C) Andrew Tridgell 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/>.
+*/
+
+#ifndef _LIBRPC_NDR_UTIL_H_
+#define _LIBRPC_NDR_UTIL_H_
+
 /* The following definitions come from librpc/ndr/util.c  */
 
 _PUBLIC_ void ndr_print_sockaddr_storage(struct ndr_print *ndr, const char *name, const struct sockaddr_storage *ss);
+
+#endif /* _LIBRPC_NDR_UTIL_H_ */

Modified: branches/samba/experimental/source3/libsmb/async_smb.c
===================================================================
--- branches/samba/experimental/source3/libsmb/async_smb.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libsmb/async_smb.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -239,6 +239,14 @@
 	int num_pending = talloc_array_length(cli->pending);
 	int i;
 
+	if (state->mid != 0) {
+		/*
+		 * This is a [nt]trans[2] request which waits
+		 * for more than one reply.
+		 */
+		return;
+	}
+
 	if (num_pending == 1) {
 		/*
 		 * The pending read_smb tevent_req is a child of
@@ -281,6 +289,13 @@
 
 static int cli_smb_req_destructor(struct tevent_req *req)
 {
+	struct cli_smb_state *state = tevent_req_data(
+		req, struct cli_smb_state);
+	/*
+	 * Make sure we really remove it from
+	 * the pending array on destruction.
+	 */
+	state->mid = 0;
 	cli_smb_req_unset_pending(req);
 	return 0;
 }
@@ -343,6 +358,20 @@
 	state->mid = mid;
 }
 
+uint32_t cli_smb_req_seqnum(struct tevent_req *req)
+{
+	struct cli_smb_state *state = tevent_req_data(
+		req, struct cli_smb_state);
+	return state->seqnum;
+}
+
+void cli_smb_req_set_seqnum(struct tevent_req *req, uint32_t seqnum)
+{
+	struct cli_smb_state *state = tevent_req_data(
+		req, struct cli_smb_state);
+	state->seqnum = seqnum;
+}
+
 static size_t iov_len(const struct iovec *iov, int count)
 {
 	size_t result = 0;
@@ -716,7 +745,7 @@
 	if (state->chained_requests == NULL) {
 		state->inbuf = talloc_move(state, &inbuf);
 		talloc_set_destructor(req, NULL);
-		cli_smb_req_destructor(req);
+		cli_smb_req_unset_pending(req);
 		state->chain_num = 0;
 		state->chain_length = 1;
 		tevent_req_done(req);
@@ -760,7 +789,7 @@
 	while (talloc_array_length(cli->pending) > 0) {
 		req = cli->pending[0];
 		talloc_set_destructor(req, NULL);
-		cli_smb_req_destructor(req);
+		cli_smb_req_unset_pending(req);
 		tevent_req_nterror(req, status);
 	}
 }
@@ -783,6 +812,24 @@
 	}
 
 	if (state->inbuf == NULL) {
+		if (min_wct != 0) {
+			return NT_STATUS_INVALID_NETWORK_RESPONSE;
+		}
+		if (pinbuf) {
+			*pinbuf = NULL;
+		}
+		if (pwct) {
+			*pwct = 0;
+		}
+		if (pvwv) {
+			*pvwv = NULL;
+		}
+		if (pnum_bytes) {
+			*pnum_bytes = 0;
+		}
+		if (pbytes) {
+			*pbytes = NULL;
+		}
 		/* This was a request without a reply */
 		return NT_STATUS_OK;
 	}

Modified: branches/samba/experimental/source3/libsmb/cli_np_tstream.c
===================================================================
--- branches/samba/experimental/source3/libsmb/cli_np_tstream.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libsmb/cli_np_tstream.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -28,9 +28,24 @@
 static const struct tstream_context_ops tstream_cli_np_ops;
 
 /*
- * Window uses 1024 hardcoded for read size and trans max data
+ * Windows uses 4280 (the max xmit/recv size negotiated on DCERPC).
+ * This is fits into the max_xmit negotiated at the SMB layer.
+ *
+ * On the sending side they may use SMBtranss if the request does not
+ * fit into a single SMBtrans call.
+ *
+ * Windows uses 1024 as max data size of a SMBtrans request and then
+ * possibly reads the rest of the DCERPC fragment (up to 3256 bytes)
+ * via a SMBreadX.
+ *
+ * For now we just ask for the full 4280 bytes (max data size) in the SMBtrans
+ * request to get the whole fragment at once (like samba 3.5.x and below did.
+ *
+ * It is important that we use do SMBwriteX with the size of a full fragment,
+ * otherwise we may get NT_STATUS_PIPE_BUSY on the SMBtrans request
+ * from NT4 servers. (See bug #8195)
  */
-#define TSTREAM_CLI_NP_BUF_SIZE 1024
+#define TSTREAM_CLI_NP_MAX_BUF_SIZE 4280
 
 struct tstream_cli_np {
 	struct cli_state *cli;
@@ -48,7 +63,7 @@
 	struct {
 		off_t ofs;
 		size_t left;
-		uint8_t buf[TSTREAM_CLI_NP_BUF_SIZE];
+		uint8_t *buf;
 	} read, write;
 };
 
@@ -348,9 +363,26 @@
 		tstream_context_data(state->stream,
 		struct tstream_cli_np);
 	struct tevent_req *subreq;
+	size_t i;
+	size_t left = 0;
 
+	for (i=0; i < state->count; i++) {
+		left += state->vector[i].iov_len;
+	}
+
+	if (left == 0) {
+		TALLOC_FREE(cli_nps->write.buf);
+		tevent_req_done(req);
+		return;
+	}
+
 	cli_nps->write.ofs = 0;
-	cli_nps->write.left = TSTREAM_CLI_NP_BUF_SIZE;
+	cli_nps->write.left = MIN(left, TSTREAM_CLI_NP_MAX_BUF_SIZE);
+	cli_nps->write.buf = talloc_realloc(cli_nps, cli_nps->write.buf,
+					    uint8_t, cli_nps->write.left);
+	if (tevent_req_nomem(cli_nps->write.buf, req)) {
+		return;
+	}
 
 	/*
 	 * copy the pending buffer first
@@ -376,11 +408,6 @@
 		state->ret += len;
 	}
 
-	if (cli_nps->write.ofs == 0) {
-		tevent_req_done(req);
-		return;
-	}
-
 	if (cli_nps->trans.active && state->count == 0) {
 		cli_nps->trans.active = false;
 		cli_nps->trans.write_req = req;
@@ -620,6 +647,10 @@
 		state->ret += len;
 	}
 
+	if (cli_nps->read.left == 0) {
+		TALLOC_FREE(cli_nps->read.buf);
+	}
+
 	if (state->count == 0) {
 		tevent_req_done(req);
 		return;
@@ -638,7 +669,7 @@
 	}
 
 	subreq = cli_read_andx_send(state, state->ev, cli_nps->cli,
-				    cli_nps->fnum, 0, TSTREAM_CLI_NP_BUF_SIZE);
+				    cli_nps->fnum, 0, TSTREAM_CLI_NP_MAX_BUF_SIZE);
 	if (tevent_req_nomem(subreq, req)) {
 		return;
 	}
@@ -674,7 +705,7 @@
 				NULL, 0, 0,
 				cli_nps->write.buf,
 				cli_nps->write.ofs,
-				TSTREAM_CLI_NP_BUF_SIZE);
+				TSTREAM_CLI_NP_MAX_BUF_SIZE);
 	if (tevent_req_nomem(subreq, req)) {
 		return;
 	}
@@ -714,7 +745,7 @@
 		return;
 	}
 
-	if (received > TSTREAM_CLI_NP_BUF_SIZE) {
+	if (received > TSTREAM_CLI_NP_MAX_BUF_SIZE) {
 		tstream_cli_np_readv_disconnect_now(req, EIO, __location__);
 		return;
 	}
@@ -726,8 +757,7 @@
 
 	cli_nps->read.ofs = 0;
 	cli_nps->read.left = received;
-	memcpy(cli_nps->read.buf, rcvbuf, received);
-	TALLOC_FREE(rcvbuf);
+	cli_nps->read.buf = talloc_move(cli_nps, &rcvbuf);
 
 	if (cli_nps->trans.write_req == NULL) {
 		tstream_cli_np_readv_read_next(req);
@@ -789,7 +819,7 @@
 		return;
 	}
 
-	if (received > TSTREAM_CLI_NP_BUF_SIZE) {
+	if (received > TSTREAM_CLI_NP_MAX_BUF_SIZE) {
 		TALLOC_FREE(subreq);
 		tstream_cli_np_readv_disconnect_now(req, EIO, __location__);
 		return;
@@ -803,6 +833,12 @@
 
 	cli_nps->read.ofs = 0;
 	cli_nps->read.left = received;
+	cli_nps->read.buf = talloc_array(cli_nps, uint8_t, received);
+	if (cli_nps->read.buf == NULL) {
+		TALLOC_FREE(subreq);
+		tevent_req_nomem(cli_nps->read.buf, req);
+		return;
+	}
 	memcpy(cli_nps->read.buf, rcvbuf, received);
 	TALLOC_FREE(subreq);
 

Modified: branches/samba/experimental/source3/libsmb/clidgram.h
===================================================================
--- branches/samba/experimental/source3/libsmb/clidgram.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libsmb/clidgram.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,27 @@
+/*
+   Unix SMB/CIFS implementation.
+   client dgram calls
+   Copyright (C) Andrew Tridgell 1994-1998
+   Copyright (C) Richard Sharpe 2001
+   Copyright (C) John Terpstra 2001
+
+   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/>.
+*/
+
+#ifndef _LIBSMB_CLIDGRAM_H_
+#define _LIBSMB_CLIDGRAM_H_
+
 #include "../libcli/netlogon/netlogon.h"
 
 /* The following definitions come from libsmb/clidgram.c  */
@@ -21,3 +45,5 @@
 		   uint32_t *pnt_version,
 		   const char **dc_name,
 		   struct netlogon_samlogon_response **samlogon_response);
+
+#endif /* _LIBSMB_CLIDGRAM_H_ */

Modified: branches/samba/experimental/source3/libsmb/clireadwrite.c
===================================================================
--- branches/samba/experimental/source3/libsmb/clireadwrite.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libsmb/clireadwrite.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -28,6 +28,11 @@
 ****************************************************************************/
 static size_t cli_read_max_bufsize(struct cli_state *cli)
 {
+	size_t data_offset = smb_size - 4;
+	size_t wct = 12;
+
+	size_t useable_space;
+
 	if (!client_is_signing_on(cli) && !cli_encryption_on(cli)
 	    && (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) {
 		return CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE;
@@ -37,13 +42,21 @@
 			? CLI_SAMBA_MAX_LARGE_READX_SIZE
 			: CLI_WINDOWS_MAX_LARGE_READX_SIZE;
 	}
-	return (cli->max_xmit - (smb_size+32)) & ~1023;
+
+	data_offset += wct * sizeof(uint16_t);
+	data_offset += 1; /* pad */
+
+	useable_space = cli->max_xmit - data_offset;
+
+	return useable_space;
 }
 
 /****************************************************************************
   Calculate the recommended write buffer size
 ****************************************************************************/
-static size_t cli_write_max_bufsize(struct cli_state *cli, uint16_t write_mode)
+static size_t cli_write_max_bufsize(struct cli_state *cli,
+				    uint16_t write_mode,
+				    uint8_t wct)
 {
         if (write_mode == 0 &&
 	    !client_is_signing_on(cli) &&
@@ -62,13 +75,15 @@
 	if (((cli->capabilities & CAP_LARGE_WRITEX) == 0)
 	    || client_is_signing_on(cli)
 	    || strequal(cli->dev, "LPT1:")) {
+		size_t data_offset = smb_size - 4;
+		size_t useable_space;
 
-		/*
-		 * Printer devices are restricted to max_xmit writesize in
-		 * Vista and XPSP3 as are signing connections.
-		 */
+		data_offset += wct * sizeof(uint16_t);
+		data_offset += 1; /* pad */
 
-		return (cli->max_xmit - (smb_size+32)) & ~1023;
+		useable_space = cli->max_xmit - data_offset;
+
+		return useable_space;
 	}
 
 	return CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE;
@@ -788,7 +803,7 @@
 	struct cli_write_andx_state *state;
 	bool bigoffset = ((cli->capabilities & CAP_LARGE_FILES) != 0);
 	uint8_t wct = bigoffset ? 14 : 12;
-	size_t max_write = cli_write_max_bufsize(cli, mode);
+	size_t max_write = cli_write_max_bufsize(cli, mode, wct);
 	uint16_t *vwv;
 
 	req = tevent_req_create(mem_ctx, &state, struct cli_write_andx_state);
@@ -1144,7 +1159,7 @@
 	state->pending = 0;
 	state->next_offset = start_offset;
 
-	state->chunk_size = cli_write_max_bufsize(cli, mode);
+	state->chunk_size = cli_write_max_bufsize(cli, mode, 14);
 
 	if (window_size == 0) {
 		window_size = cli->max_mux * state->chunk_size;

Modified: branches/samba/experimental/source3/libsmb/clitrans.c
===================================================================
--- branches/samba/experimental/source3/libsmb/clitrans.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libsmb/clitrans.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -32,7 +32,6 @@
 	struct event_context *ev;
 	uint8_t cmd;
 	uint16_t mid;
-	uint32_t seqnum;
 	const char *pipe_name;
 	uint8_t *pipe_name_conv;
 	size_t pipe_name_conv_len;
@@ -52,13 +51,29 @@
 	struct trans_recvblob rdata;
 	uint16_t recv_flags2;
 
-	TALLOC_CTX *secondary_request_ctx;
-
-	struct iovec iov[4];
+	struct iovec iov[6];
 	uint8_t pad[4];
+	uint8_t zero_pad[4];
 	uint16_t vwv[32];
+
+	struct tevent_req *primary_subreq;
 };
 
+static void cli_trans_cleanup_primary(struct cli_trans_state *state)
+{
+	if (state->primary_subreq) {
+		cli_smb_req_set_mid(state->primary_subreq, 0);
+		cli_smb_req_unset_pending(state->primary_subreq);
+		TALLOC_FREE(state->primary_subreq);
+	}
+}
+
+static int cli_trans_state_destructor(struct cli_trans_state *state)
+{
+	cli_trans_cleanup_primary(state);
+	return 0;
+}
+
 static NTSTATUS cli_pull_trans(uint8_t *inbuf,
 			       uint8_t wct, uint16_t *vwv,
 			       uint16_t num_bytes, uint8_t *bytes,
@@ -173,9 +188,12 @@
 	struct iovec *iov = state->iov;
 	uint8_t *pad = state->pad;
 	uint16_t *vwv = state->vwv;
-	uint16_t param_offset;
-	uint16_t this_param = 0;
-	uint16_t this_data = 0;
+	uint32_t param_offset;
+	uint32_t this_param = 0;
+	uint32_t param_pad;
+	uint32_t data_offset;
+	uint32_t this_data = 0;
+	uint32_t data_pad;
 	uint32_t useable_space;
 	uint8_t cmd;
 
@@ -223,8 +241,19 @@
 		break;
 	}
 
-	useable_space = state->cli->max_xmit - smb_size - sizeof(uint16_t)*wct;
+	param_offset += wct * sizeof(uint16_t);
+	useable_space = state->cli->max_xmit - param_offset;
 
+	param_pad = param_offset % 4;
+	if (param_pad > 0) {
+		param_pad = MIN(param_pad, useable_space);
+		iov[0].iov_base = (void *)state->zero_pad;
+		iov[0].iov_len = param_pad;
+		iov += 1;
+		param_offset += param_pad;
+	}
+	useable_space = state->cli->max_xmit - param_offset;
+
 	if (state->param_sent < state->num_param) {
 		this_param = MIN(state->num_param - state->param_sent,
 				 useable_space);
@@ -233,27 +262,41 @@
 		iov += 1;
 	}
 
+	data_offset = param_offset + this_param;
+	useable_space = state->cli->max_xmit - data_offset;
+
+	data_pad = data_offset % 4;
+	if (data_pad > 0) {
+		data_pad = MIN(data_pad, useable_space);
+		iov[0].iov_base = (void *)state->zero_pad;
+		iov[0].iov_len = data_pad;
+		iov += 1;
+		data_offset += data_pad;
+	}
+	useable_space = state->cli->max_xmit - data_offset;
+
 	if (state->data_sent < state->num_data) {
 		this_data = MIN(state->num_data - state->data_sent,
-				useable_space - this_param);
+				useable_space);
 		iov[0].iov_base = (void *)(state->data + state->data_sent);
 		iov[0].iov_len = this_data;
 		iov += 1;
 	}
 
-	param_offset += wct * sizeof(uint16_t);
-
 	DEBUG(10, ("num_setup=%u, max_setup=%u, "
 		   "param_total=%u, this_param=%u, max_param=%u, "
 		   "data_total=%u, this_data=%u, max_data=%u, "
-		   "param_offset=%u, param_disp=%u, data_disp=%u\n",
+		   "param_offset=%u, param_pad=%u, param_disp=%u, "
+		   "data_offset=%u, data_pad=%u, data_disp=%u\n",
 		   (unsigned)state->num_setup, (unsigned)state->max_setup,
 		   (unsigned)state->num_param, (unsigned)this_param,
 		   (unsigned)state->rparam.max,
 		   (unsigned)state->num_data, (unsigned)this_data,
 		   (unsigned)state->rdata.max,
-		   (unsigned)param_offset,
-		   (unsigned)state->param_sent, (unsigned)state->data_sent));
+		   (unsigned)param_offset, (unsigned)param_pad,
+		   (unsigned)state->param_sent,
+		   (unsigned)data_offset, (unsigned)data_pad,
+		   (unsigned)state->data_sent));
 
 	switch (cmd) {
 	case SMBtrans:
@@ -270,7 +313,7 @@
 		SSVAL(vwv + 9, 0, this_param);
 		SSVAL(vwv +10, 0, param_offset);
 		SSVAL(vwv +11, 0, this_data);
-		SSVAL(vwv +12, 0, param_offset + this_param);
+		SSVAL(vwv +12, 0, data_offset);
 		SCVAL(vwv +13, 0, state->num_setup);
 		SCVAL(vwv +13, 1, 0);	/* reserved */
 		memcpy(vwv + 14, state->setup,
@@ -284,40 +327,40 @@
 		SSVAL(vwv + 3, 0, param_offset);
 		SSVAL(vwv + 4, 0, state->param_sent);
 		SSVAL(vwv + 5, 0, this_data);
-		SSVAL(vwv + 6, 0, param_offset + this_param);
+		SSVAL(vwv + 6, 0, data_offset);
 		SSVAL(vwv + 7, 0, state->data_sent);
 		if (cmd == SMBtranss2) {
 			SSVAL(vwv + 8, 0, state->fid);
 		}
 		break;
 	case SMBnttrans:
-		SCVAL(vwv,  0, state->max_setup);
-		SSVAL(vwv,  1, 0); /* reserved */
-		SIVAL(vwv,  3, state->num_param);
-		SIVAL(vwv,  7, state->num_data);
-		SIVAL(vwv, 11, state->rparam.max);
-		SIVAL(vwv, 15, state->rdata.max);
-		SIVAL(vwv, 19, this_param);
-		SIVAL(vwv, 23, param_offset);
-		SIVAL(vwv, 27, this_data);
-		SIVAL(vwv, 31, param_offset + this_param);
-		SCVAL(vwv, 35, state->num_setup);
-		SSVAL(vwv, 36, state->function);
+		SCVAL(vwv + 0, 0, state->max_setup);
+		SSVAL(vwv + 0, 1, 0); /* reserved */
+		SIVAL(vwv + 1, 1, state->num_param);
+		SIVAL(vwv + 3, 1, state->num_data);
+		SIVAL(vwv + 5, 1, state->rparam.max);
+		SIVAL(vwv + 7, 1, state->rdata.max);
+		SIVAL(vwv + 9, 1, this_param);
+		SIVAL(vwv +11, 1, param_offset);
+		SIVAL(vwv +13, 1, this_data);
+		SIVAL(vwv +15, 1, data_offset);
+		SCVAL(vwv +17, 1, state->num_setup);
+		SSVAL(vwv +18, 0, state->function);
 		memcpy(vwv + 19, state->setup,
 		       sizeof(uint16_t) * state->num_setup);
 		break;
 	case SMBnttranss:
-		SSVAL(vwv,  0, 0); /* reserved */
-		SCVAL(vwv,  2, 0); /* reserved */
-		SIVAL(vwv,  3, state->num_param);
-		SIVAL(vwv,  7, state->num_data);
-		SIVAL(vwv, 11, this_param);
-		SIVAL(vwv, 15, param_offset);
-		SIVAL(vwv, 19, state->param_sent);
-		SIVAL(vwv, 23, this_data);
-		SIVAL(vwv, 27, param_offset + this_param);
-		SIVAL(vwv, 31, state->data_sent);
-		SCVAL(vwv, 35, 0); /* reserved */
+		SSVAL(vwv + 0, 0, 0); /* reserved */
+		SCVAL(vwv + 1, 0, 0); /* reserved */
+		SIVAL(vwv + 1, 1, state->num_param);
+		SIVAL(vwv + 3, 1, state->num_data);
+		SIVAL(vwv + 5, 1, this_param);
+		SIVAL(vwv + 7, 1, param_offset);
+		SIVAL(vwv + 9, 1, state->param_sent);
+		SIVAL(vwv +11, 1, this_data);
+		SIVAL(vwv +13, 1, data_offset);
+		SIVAL(vwv +15, 1, state->data_sent);
+		SCVAL(vwv +17, 1, 0); /* reserved */
 		break;
 	}
 
@@ -414,17 +457,30 @@
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-	state->mid = cli_smb_req_mid(subreq);
 	status = cli_smb_req_send(subreq);
 	if (!NT_STATUS_IS_OK(status)) {
 		tevent_req_nterror(req, status);
 		return tevent_req_post(req, state->ev);
 	}
-	cli_state_seqnum_persistent(cli, state->mid);
 	tevent_req_set_callback(subreq, cli_trans_done, req);
+
+	/*
+	 * Now get the MID of the primary request
+	 * and mark it as persistent. This means
+	 * we will able to send and receive multiple
+	 * SMB pdus using this MID in both directions
+	 * (including correct SMB signing).
+	 */
+	state->mid = cli_smb_req_mid(subreq);
+	cli_smb_req_set_mid(subreq, state->mid);
+	state->primary_subreq = subreq;
+	talloc_set_destructor(state, cli_trans_state_destructor);
+
 	return req;
 }
 
+static void cli_trans_done2(struct tevent_req *subreq);
+
 static void cli_trans_done(struct tevent_req *subreq)
 {
 	struct tevent_req *req = tevent_req_callback_data(
@@ -480,25 +536,25 @@
 
 	if (!sent_all) {
 		int iov_count;
+		struct tevent_req *subreq2;
 
-		TALLOC_FREE(subreq);
-
 		cli_trans_format(state, &wct, &iov_count);
 
-		subreq = cli_smb_req_create(state, state->ev, state->cli,
-					    state->cmd + 1, 0, wct, state->vwv,
-					    iov_count, state->iov);
-		if (tevent_req_nomem(subreq, req)) {
+		subreq2 = cli_smb_req_create(state, state->ev, state->cli,
+					     state->cmd + 1, 0, wct, state->vwv,
+					     iov_count, state->iov);
+		if (tevent_req_nomem(subreq2, req)) {
 			return;
 		}
-		cli_smb_req_set_mid(subreq, state->mid);
+		cli_smb_req_set_mid(subreq2, state->mid);
 
-		status = cli_smb_req_send(subreq);
+		status = cli_smb_req_send(subreq2);
 
 		if (!NT_STATUS_IS_OK(status)) {
 			goto fail;
 		}
-		tevent_req_set_callback(subreq, cli_trans_done, req);
+		tevent_req_set_callback(subreq2, cli_trans_done2, req);
+
 		return;
 	}
 
@@ -523,23 +579,80 @@
 	if ((state->rparam.total == state->rparam.received)
 	    && (state->rdata.total == state->rdata.received)) {
 		state->recv_flags2 = SVAL(inbuf, smb_flg2);
-		TALLOC_FREE(subreq);
-		cli_state_seqnum_remove(state->cli, state->mid);
+		cli_trans_cleanup_primary(state);
 		tevent_req_done(req);
 		return;
 	}
 
 	TALLOC_FREE(inbuf);
 
-	if (!cli_smb_req_set_pending(subreq)) {
-		status = NT_STATUS_NO_MEMORY;
+	return;
+
+ fail:
+	cli_trans_cleanup_primary(state);
+	tevent_req_nterror(req, status);
+}
+
+static void cli_trans_done2(struct tevent_req *subreq2)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq2, struct tevent_req);
+	struct cli_trans_state *state = tevent_req_data(
+		req, struct cli_trans_state);
+	NTSTATUS status;
+	bool sent_all;
+	uint8_t wct;
+	uint32_t seqnum;
+
+	/*
+	 * First backup the seqnum of the secondary request
+	 * and attach it to the primary request.
+	 */
+	seqnum = cli_smb_req_seqnum(subreq2);
+	cli_smb_req_set_seqnum(state->primary_subreq, seqnum);
+
+	status = cli_smb_recv(subreq2, state, NULL, 0, &wct, NULL,
+			      NULL, NULL);
+	TALLOC_FREE(subreq2);
+
+	if (!NT_STATUS_IS_OK(status)) {
 		goto fail;
 	}
+
+	if (wct != 0) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto fail;
+	}
+
+	sent_all = ((state->param_sent == state->num_param)
+		    && (state->data_sent == state->num_data));
+
+	if (!sent_all) {
+		int iov_count;
+
+		cli_trans_format(state, &wct, &iov_count);
+
+		subreq2 = cli_smb_req_create(state, state->ev, state->cli,
+					     state->cmd + 1, 0, wct, state->vwv,
+					     iov_count, state->iov);
+		if (tevent_req_nomem(subreq2, req)) {
+			return;
+		}
+		cli_smb_req_set_mid(subreq2, state->mid);
+
+		status = cli_smb_req_send(subreq2);
+
+		if (!NT_STATUS_IS_OK(status)) {
+			goto fail;
+		}
+		tevent_req_set_callback(subreq2, cli_trans_done2, req);
+		return;
+	}
+
 	return;
 
  fail:
-	cli_state_seqnum_remove(state->cli, state->mid);
-	TALLOC_FREE(subreq);
+	cli_trans_cleanup_primary(state);
 	tevent_req_nterror(req, status);
 }
 
@@ -556,6 +669,8 @@
 		req, struct cli_trans_state);
 	NTSTATUS status;
 
+	cli_trans_cleanup_primary(state);
+
 	if (tevent_req_is_nterror(req, &status)) {
 		return status;
 	}

Modified: branches/samba/experimental/source3/libsmb/errormap_wbc.h
===================================================================
--- branches/samba/experimental/source3/libsmb/errormap_wbc.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libsmb/errormap_wbc.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,29 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  error mapping functions
+ *  Copyright (C) Andrew Tridgell 2001
+ *  Copyright (C) Andrew Bartlett 2001
+ *  Copyright (C) Tim Potter 2000
+ *
+ *  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/>.
+ */
+
+#ifndef _LIBSMB_ERRORMAP_WBC_H_
+#define _LIBSMB_ERRORMAP_WBC_H_
+
 /* The following definitions come from libsmb/errormap_wbc.c  */
 
 NTSTATUS map_nt_error_from_wbcErr(wbcErr wbc_err);
+
+#endif /* _LIBSMB_ERRORMAP_WBC_H_ */

Modified: branches/samba/experimental/source3/libsmb/libsmb.h
===================================================================
--- branches/samba/experimental/source3/libsmb/libsmb.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libsmb/libsmb.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,6 +1,11 @@
 /*
    Unix SMB/CIFS implementation.
 
+   Copyright (C) Andrew Tridgell 1992-1998,2001
+   Copyright (C) Jeremy Allison 1998
+   Copyright (C) Remus Koos 2001
+   Copyright (C) Andrew Bartlett 2001
+
    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

Modified: branches/samba/experimental/source3/libsmb/nmblib.h
===================================================================
--- branches/samba/experimental/source3/libsmb/nmblib.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libsmb/nmblib.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,28 @@
+/*
+   Unix SMB/CIFS implementation.
+   handle unexpected packets
+   NBT netbios library routines
+   Copyright (C) Andrew Tridgell 1994-1998, 2000
+   Copyright (C) Jeremy Allison 2007
+
+   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/>.
+
+*/
+
+#ifndef _LIBSMB_NMBLIB_H_
+#define _LIBSMB_NMBLIB_H_
+
 /* The following definitions come from libsmb/unexpected.c  */
 
 #include "nameserv.h"
@@ -47,3 +72,5 @@
 char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type);
 int name_extract(unsigned char *buf,size_t buf_len, unsigned int ofs, fstring name);
 int name_len(unsigned char *s1, size_t buf_len);
+
+#endif /* _LIBSMB_NMBLIB_H_ */

Modified: branches/samba/experimental/source3/libsmb/proto.h
===================================================================
--- branches/samba/experimental/source3/libsmb/proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libsmb/proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,6 +1,14 @@
 /*
    Unix SMB/CIFS implementation.
 
+   Copyright (C) Andrew Bartlett 2001-2003
+   Copyright (C) Andrew Tridgell 1994-1998,2000-2001
+   Copyright (C) Gerald (Jerry) Carter 2004
+   Copyright (C) Jelmer Vernooij 2003
+   Copyright (C) Jeremy Allison 2001-2009,2011
+   Copyright (C) Stefan Metzmacher 2003,2009
+   Copyright (C) Volker Lendecke 2011
+
    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

Modified: branches/samba/experimental/source3/libsmb/unexpected.c
===================================================================
--- branches/samba/experimental/source3/libsmb/unexpected.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/libsmb/unexpected.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -221,7 +221,7 @@
 
 	nread = read_packet_recv(req, talloc_tos(), &buf, &err);
 	TALLOC_FREE(req);
-	if (nread < sizeof(struct nb_packet_query)) {
+	if (nread < (ssize_t)sizeof(struct nb_packet_query)) {
 		DEBUG(10, ("read_packet_recv returned %d (%s)\n",
 			   (int)nread,
 			   (nread == -1) ? strerror(err) : "wrong length"));

Modified: branches/samba/experimental/source3/locking/brlock.c
===================================================================
--- branches/samba/experimental/source3/locking/brlock.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/locking/brlock.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1485,137 +1485,38 @@
 	files_struct *fsp = br_lck->fsp;
 	uint16 tid = fsp->conn->cnum;
 	int fnum = fsp->fnum;
-	unsigned int i, j, dcount=0;
-	int num_deleted_windows_locks = 0;
+	unsigned int i;
 	struct lock_struct *locks = br_lck->lock_data;
 	struct server_id pid = sconn_server_id(fsp->conn->sconn);
-	bool unlock_individually = False;
-	bool posix_level2_contention_ended = false;
+	struct lock_struct *locks_copy;
+	unsigned int num_locks_copy;
 
-	if(lp_posix_locking(fsp->conn->params)) {
-
-		/* Check if there are any Windows locks associated with this dev/ino
-		   pair that are not this fnum. If so we need to call unlock on each
-		   one in order to release the system POSIX locks correctly. */
-
-		for (i=0; i < br_lck->num_locks; i++) {
-			struct lock_struct *lock = &locks[i];
-
-			if (!procid_equal(&lock->context.pid, &pid)) {
-				continue;
+	/* Copy the current lock array. */
+	if (br_lck->num_locks) {
+		locks_copy = (struct lock_struct *)TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct));
+		if (!locks_copy) {
+			smb_panic("brl_close_fnum: talloc failed");
 			}
-
-			if (lock->lock_type != READ_LOCK && lock->lock_type != WRITE_LOCK) {
-				continue; /* Ignore pending. */
-			}
-
-			if (lock->context.tid != tid || lock->fnum != fnum) {
-				unlock_individually = True;
-				break;
-			}
-		}
-
-		if (unlock_individually) {
-			struct lock_struct *locks_copy;
-			unsigned int num_locks_copy;
-
-			/* Copy the current lock array. */
-			if (br_lck->num_locks) {
-				locks_copy = (struct lock_struct *)TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct));
-				if (!locks_copy) {
-					smb_panic("brl_close_fnum: talloc failed");
-	 			}
-			} else {	
-				locks_copy = NULL;
-			}
-
-			num_locks_copy = br_lck->num_locks;
-
-			for (i=0; i < num_locks_copy; i++) {
-				struct lock_struct *lock = &locks_copy[i];
-
-				if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid) &&
-						(lock->fnum == fnum)) {
-					brl_unlock(msg_ctx,
-						br_lck,
-						lock->context.smblctx,
-						pid,
-						lock->start,
-						lock->size,
-						lock->lock_flav);
-				}
-			}
-			return;
-		}
+	} else {
+		locks_copy = NULL;
 	}
 
-	/* We can bulk delete - any POSIX locks will be removed when the fd closes. */
+	num_locks_copy = br_lck->num_locks;
 
-	/* Remove any existing locks for this fnum (or any fnum if they're POSIX). */
+	for (i=0; i < num_locks_copy; i++) {
+		struct lock_struct *lock = &locks_copy[i];
 
-	for (i=0; i < br_lck->num_locks; i++) {
-		struct lock_struct *lock = &locks[i];
-		bool del_this_lock = False;
-
-		if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid)) {
-			if ((lock->lock_flav == WINDOWS_LOCK) && (lock->fnum == fnum)) {
-				del_this_lock = True;
-				num_deleted_windows_locks++;
-				contend_level2_oplocks_end(br_lck->fsp,
-				    LEVEL2_CONTEND_WINDOWS_BRL);
-			} else if (lock->lock_flav == POSIX_LOCK) {
-				del_this_lock = True;
-
-				/* Only end level2 contention once for posix */
-				if (!posix_level2_contention_ended) {
-					posix_level2_contention_ended = true;
-					contend_level2_oplocks_end(br_lck->fsp,
-					    LEVEL2_CONTEND_POSIX_BRL);
-				}
-			}
+		if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid) &&
+				(lock->fnum == fnum)) {
+			brl_unlock(msg_ctx,
+				br_lck,
+				lock->context.smblctx,
+				pid,
+				lock->start,
+				lock->size,
+				lock->lock_flav);
 		}
-
-		if (del_this_lock) {
-			/* Send unlock messages to any pending waiters that overlap. */
-			for (j=0; j < br_lck->num_locks; j++) {
-				struct lock_struct *pend_lock = &locks[j];
-
-				/* Ignore our own or non-pending locks. */
-				if (!IS_PENDING_LOCK(pend_lock->lock_type)) {
-					continue;
-				}
-
-				/* Optimisation - don't send to this fnum as we're
-				   closing it. */
-				if (pend_lock->context.tid == tid &&
-				    procid_equal(&pend_lock->context.pid, &pid) &&
-				    pend_lock->fnum == fnum) {
-					continue;
-				}
-
-				/* We could send specific lock info here... */
-				if (brl_pending_overlap(lock, pend_lock)) {
-					messaging_send(msg_ctx, pend_lock->context.pid,
-						       MSG_SMB_UNLOCK, &data_blob_null);
-				}
-			}
-
-			/* found it - delete it */
-			if (br_lck->num_locks > 1 && i < br_lck->num_locks - 1) {
-				memmove(&locks[i], &locks[i+1], 
-					sizeof(*locks)*((br_lck->num_locks-1) - i));
-			}
-			br_lck->num_locks--;
-			br_lck->modified = True;
-			i--;
-			dcount++;
-		}
 	}
-
-	if(lp_posix_locking(fsp->conn->params) && num_deleted_windows_locks) {
-		/* Reduce the Windows lock POSIX reference count on this dev/ino pair. */
-		reduce_windows_lock_ref_count(fsp, num_deleted_windows_locks);
-	}
 }
 
 /****************************************************************************

Modified: branches/samba/experimental/source3/locking/proto.h
===================================================================
--- branches/samba/experimental/source3/locking/proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/locking/proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,4 +1,28 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  Locking functions
+ *
+ *  Copyright (C) Andrew Tridgell	1992-2000
+ *  Copyright (C) Jeremy Allison	1992-2006
+ *  Copyright (C) Volker Lendecke	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/>.
+ */
 
+#ifndef _LOCKING_PROTO_H_
+#define _LOCKING_PROTO_H_
+
 /* The following definitions come from locking/brlock.c  */
 
 bool brl_same_context(const struct lock_context *ctx1,
@@ -199,3 +223,5 @@
 				const struct lock_context *lock_ctx,
 				const struct lock_struct *plocks,
 				int num_locks);
+
+#endif /* _LOCKING_PROTO_H_ */

Modified: branches/samba/experimental/source3/m4/check_path.m4
===================================================================
--- branches/samba/experimental/source3/m4/check_path.m4	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/m4/check_path.m4	2011-07-28 16:06:15 UTC (rev 3863)
@@ -19,7 +19,7 @@
 lockdir="\${VARDIR}/locks"
 piddir="\${VARDIR}/locks"
 ncalrpcdir="\${VARDIR}/ncalrpc"
-nmbdsocketdir="${lockdir}/.nmbd"
+nmbdsocketdir="\${VARDIR}/nmbd"
 test "${mandir}" || mandir="\${prefix}/man"
 logfilebase="\${VARDIR}"
 privatedir="\${prefix}/private"
@@ -169,7 +169,7 @@
 #################################################
 # set nmbd socket directory location
 AC_ARG_WITH(nmbdsocketdir,
-[AS_HELP_STRING([--with-nmbdsocketdir=DIR], [Where to put the nmbd socket directory (${lockdir}/.nmbd)])],
+[AS_HELP_STRING([--with-nmbdsocketdir=DIR], [Where to put the nmbd socket directory ($ac_default_prefix/var/nmbd)])],
 [ case "$withval" in
   yes|no)
   #

Modified: branches/samba/experimental/source3/modules/vfs_acl_common.c
===================================================================
--- branches/samba/experimental/source3/modules/vfs_acl_common.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/modules/vfs_acl_common.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -448,10 +448,14 @@
 	struct security_descriptor *psd = NULL;
 	struct dom_sid *owner_sid = NULL;
 	struct dom_sid *group_sid = NULL;
+	uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
 	bool inherit_owner = lp_inherit_owner(SNUM(handle->conn));
+	bool inheritable_components = sd_has_inheritable_components(parent_desc,
+					is_directory);
 	size_t size;
 
-	if (!sd_has_inheritable_components(parent_desc, is_directory)) {
+	if (!inheritable_components && !inherit_owner) {
+		/* Nothing to inherit and not setting owner. */
 		return NT_STATUS_OK;
 	}
 
@@ -487,6 +491,17 @@
 		return status;
 	}
 
+	/* If inheritable_components == false,
+	   se_create_child_secdesc()
+	   creates a security desriptor with a NULL dacl
+	   entry, but with SEC_DESC_DACL_PRESENT. We need
+	   to remove that flag. */
+
+	if (!inheritable_components) {
+		security_info_sent &= ~SECINFO_DACL;
+		psd->type &= ~SEC_DESC_DACL_PRESENT;
+	}
+
 	if (DEBUGLEVEL >= 10) {
 		DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
 			fsp_str_dbg(fsp) ));
@@ -498,9 +513,7 @@
 		become_root();
 	}
 	status = SMB_VFS_FSET_NT_ACL(fsp,
-				(SECINFO_OWNER |
-				 SECINFO_GROUP |
-				 SECINFO_DACL),
+				security_info_sent,
 				psd);
 	if (inherit_owner) {
 		unbecome_root();

Modified: branches/samba/experimental/source3/modules/vfs_afsacl.c
===================================================================
--- branches/samba/experimental/source3/modules/vfs_afsacl.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/modules/vfs_afsacl.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -20,6 +20,10 @@
 #include "includes.h"
 #include "system/filesys.h"
 #include "smbd/smbd.h"
+#include "../librpc/gen_ndr/lsa.h"
+#include "../libcli/security/security.h"
+#include "../libcli/security/dom_sid.h"
+#include "passdb.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS

Modified: branches/samba/experimental/source3/modules/vfs_commit.c
===================================================================
--- branches/samba/experimental/source3/modules/vfs_commit.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/modules/vfs_commit.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -17,6 +17,7 @@
  */
 
 #include "includes.h"
+#include "system/filesys.h"
 #include "smbd/smbd.h"
 
 /* Commit data module.

Modified: branches/samba/experimental/source3/modules/vfs_time_audit.c
===================================================================
--- branches/samba/experimental/source3/modules/vfs_time_audit.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/modules/vfs_time_audit.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -564,7 +564,7 @@
 				      files_struct *fsp,
 				      SMB_OFF_T offset, int whence)
 {
-	ssize_t result;
+	SMB_OFF_T result;
 	struct timespec ts1,ts2;
 	double timediff;
 
@@ -721,7 +721,7 @@
 					      files_struct *fsp,
 					      const SMB_STRUCT_STAT *sbuf)
 {
-	int result;
+	uint64_t result;
 	struct timespec ts1,ts2;
 	double timediff;
 
@@ -2216,7 +2216,7 @@
 					 struct files_struct *fsp,
 					 SMB_STRUCT_AIOCB *aiocb)
 {
-	int result;
+	ssize_t result;
 	struct timespec ts1,ts2;
 	double timediff;
 

Modified: branches/samba/experimental/source3/nmbd/nmbd.h
===================================================================
--- branches/samba/experimental/source3/nmbd/nmbd.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/nmbd/nmbd.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,26 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  NBT netbios routines and daemon - version 2
+ *
+ *  Copyright (C) Guenther Deschner 2011
+ *
+ *  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/>.
+ */
+
+#ifndef _NMBD_NMBD_H_
+#define _NMBD_NMBD_H_
+
 #ifndef HAVE_PIPE
 #define SYNC_DNS 1
 #endif
@@ -4,3 +27,5 @@
 
 #include "libsmb/nmblib.h"
 #include "nmbd/nmbd_proto.h"
+
+#endif /* _NMBD_NMBD_H_ */

Modified: branches/samba/experimental/source3/nmbd/nmbd_proto.h
===================================================================
--- branches/samba/experimental/source3/nmbd/nmbd_proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/nmbd/nmbd_proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,28 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  NBT netbios routines and daemon - version 2
+ *
+ *  Copyright (C) Andrew Tridgell			1994-1998
+ *  Copyright (C) Jeremy Allison			1994-2005
+ *  Copyright (C) Luke Kenneth Casson Leighton		1994-1998
+ *  Copyright (C) John H Terpstra			1995-1998
+ *  Copyright (C) Christopher R. Hertel			1998
+ *  Copyright (C) Jim McDonough <jmcd at us.ibm.com>	2002
+ *  Copyright (C) Jelmer Vernooij			2002,2003
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
 /* The following definitions come from nmbd/asyncdns.c  */
 

Modified: branches/samba/experimental/source3/nmbd/nmbd_subnetdb.c
===================================================================
--- branches/samba/experimental/source3/nmbd/nmbd_subnetdb.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/nmbd/nmbd_subnetdb.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -56,13 +56,21 @@
 
 void close_subnet(struct subnet_record *subrec)
 {
+	if (subrec->nmb_sock != -1) {
+		close(subrec->nmb_sock);
+		subrec->nmb_sock = -1;
+	}
+	if (subrec->nmb_bcast != -1) {
+		close(subrec->nmb_bcast);
+		subrec->nmb_bcast = -1;
+	}
 	if (subrec->dgram_sock != -1) {
 		close(subrec->dgram_sock);
 		subrec->dgram_sock = -1;
 	}
-	if (subrec->nmb_sock != -1) {
-		close(subrec->nmb_sock);
-		subrec->nmb_sock = -1;
+	if (subrec->dgram_bcast != -1) {
+		close(subrec->dgram_bcast);
+		subrec->dgram_bcast = -1;
 	}
 
 	DLIST_REMOVE(subnetlist, subrec);

Modified: branches/samba/experimental/source3/param/loadparm.c
===================================================================
--- branches/samba/experimental/source3/param/loadparm.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/param/loadparm.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -4146,7 +4146,7 @@
 		.ptr		= &extra_time_offset,
 		.special	= NULL,
 		.enum_list	= NULL,
-		.flags		= FLAG_ADVANCED,
+		.flags		= FLAG_ADVANCED | FLAG_DEPRECATED,
 	},
 	{
 		.label		= "NIS homedir",
@@ -7540,9 +7540,9 @@
 	if (len == 4 || len == 5) {
 		/* Don't use StrCaseCmp here as we don't want to
 		   initialize iconv. */
-		if ((toupper_ascii(pszParmValue[0]) == 'U') &&
-		    (toupper_ascii(pszParmValue[1]) == 'T') &&
-		    (toupper_ascii(pszParmValue[2]) == 'F')) {
+		if ((toupper_m(pszParmValue[0]) == 'U') &&
+		    (toupper_m(pszParmValue[1]) == 'T') &&
+		    (toupper_m(pszParmValue[2]) == 'F')) {
 			if (len == 4) {
 				if (pszParmValue[3] == '8') {
 					is_utf8 = true;

Modified: branches/samba/experimental/source3/passdb/machine_sid.h
===================================================================
--- branches/samba/experimental/source3/passdb/machine_sid.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/passdb/machine_sid.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,24 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  Password and authentication handling
+ *  Copyright (C) Jeremy Allison 		1996-2002
+ *  Copyright (C) Andrew Tridgell		2002
+ *  Copyright (C) Gerald (Jerry) Carter		2000
+ *  Copyright (C) Stefan (metze) Metzmacher	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/>.
+ */
 
 /* The following definitions come from passdb/machine_sid.c  */
 

Modified: branches/samba/experimental/source3/passdb/passdb.c
===================================================================
--- branches/samba/experimental/source3/passdb/passdb.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/passdb/passdb.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -407,8 +407,8 @@
 		return false;
 
 	for (i = 0; i < 32; i += 2) {
-		hinybble = toupper_ascii(p[i]);
-		lonybble = toupper_ascii(p[i + 1]);
+		hinybble = toupper_m(p[i]);
+		lonybble = toupper_m(p[i + 1]);
 
 		p1 = strchr(hexchars, hinybble);
 		p2 = strchr(hexchars, lonybble);
@@ -457,8 +457,8 @@
 	}
 
 	for (i = 0; i < 42; i += 2) {
-		hinybble = toupper_ascii(p[i]);
-		lonybble = toupper_ascii(p[i + 1]);
+		hinybble = toupper_m(p[i]);
+		lonybble = toupper_m(p[i + 1]);
 
 		p1 = strchr(hexchars, hinybble);
 		p2 = strchr(hexchars, lonybble);

Modified: branches/samba/experimental/source3/passdb/proto.h
===================================================================
--- branches/samba/experimental/source3/passdb/proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/passdb/proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,4 +1,42 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  passdb - password and authentication handling
+ *
+ *  Copyright (C) Andrew Tridgell		1992-1998
+ *  Copyright (C) Jeremy Allison 		1995-2009
+ *  Copyright (C) Luke Kenneth Casson Leighton	1996-1998
+ *  Copyright (C) Jean François Micouleau	1998-2001
+ *  Copyright (C) Gerald (Jerry) Carter		2000-2006
+ *  Copyright (C) Simo Sorce			2000-2003,2006
+ *  Copyright (C) Andrew Bartlett		2001-2002
+ *  Copyright (C) Shahms King			2001
+ *  Copyright (C) Jelmer Vernooij		2002
+ *  Copyright (C) Rafal Szczesniak		2002
+ *  Copyright (C) Stefan (metze) Metzmacher	2002-2003
+ *  Copyright (C) Guenther Deschner		2004-2005
+ *  Copyright (C) Jim McDonough (jmcd at us.ibm.com) 2004-2005
+ *  Copyright (C) Vince Brimhall		2004-2005
+ *  Copyright (C) Volker Lendecke 		2006
+ *  Copyright (C) Michael Adam			2007
+ *  Copyright (C) Dan Sledz			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/>.
+ */
 
+#ifndef _PASSDB_PROTO_H_
+#define _PASSDB_PROTO_H_
+
 /* The following definitions come from passdb/account_pol.c  */
 
 void account_policy_names_list(const char ***names, int *num_names);
@@ -300,3 +338,5 @@
 
 NTSTATUS create_builtin_users(const struct dom_sid *sid);
 NTSTATUS create_builtin_administrators(const struct dom_sid *sid);
+
+#endif /* _PASSDB_PROTO_H_ */

Modified: branches/samba/experimental/source3/printing/load.h
===================================================================
--- branches/samba/experimental/source3/printing/load.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/printing/load.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+   Unix SMB/CIFS implementation.
+   load printer lists
+   Copyright (C) Andrew Tridgell 1992-2000
+
+   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/>.
+*/
+
+#ifndef _PRINTING_LOAD_H_
+#define _PRINTING_LOAD_H_
+
 /* The following definitions come from printing/load.c  */
 
 void load_printers(struct tevent_context *ev,
@@ -2 +24,3 @@
 		   struct messaging_context *msg_ctx);
+
+#endif /* _PRINTING_LOAD_H_ */

Modified: branches/samba/experimental/source3/printing/nt_printing.c
===================================================================
--- branches/samba/experimental/source3/printing/nt_printing.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/printing/nt_printing.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -32,6 +32,7 @@
 #include "auth.h"
 #include "messages.h"
 #include "rpc_server/spoolss/srv_spoolss_nt.h"
+#include "rpc_client/cli_winreg_spoolss.h"
 
 /* Map generic permissions to printer object specific permissions */
 
@@ -1168,410 +1169,6 @@
 }
 
 /****************************************************************************
- Create and allocate a default devicemode.
-****************************************************************************/
-
-WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
-				      const char *devicename,
-				      struct spoolss_DeviceMode **devmode)
-{
-	struct spoolss_DeviceMode *dm;
-	char *dname;
-
-	dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
-	if (dm == NULL) {
-		return WERR_NOMEM;
-	}
-
-	dname = talloc_asprintf(dm, "%s", devicename);
-	if (dname == NULL) {
-		return WERR_NOMEM;
-	}
-	if (strlen(dname) > MAXDEVICENAME) {
-		dname[MAXDEVICENAME] = '\0';
-	}
-	dm->devicename = dname;
-
-	dm->formname = talloc_strdup(dm, "Letter");
-	if (dm->formname == NULL) {
-		return WERR_NOMEM;
-	}
-
-	dm->specversion          = DMSPEC_NT4_AND_ABOVE;
-	dm->driverversion        = 0x0400;
-	dm->size                 = 0x00DC;
-	dm->__driverextra_length = 0;
-	dm->fields               = DEVMODE_FORMNAME |
-				   DEVMODE_TTOPTION |
-				   DEVMODE_PRINTQUALITY |
-				   DEVMODE_DEFAULTSOURCE |
-				   DEVMODE_COPIES |
-				   DEVMODE_SCALE |
-				   DEVMODE_PAPERSIZE |
-				   DEVMODE_ORIENTATION;
-	dm->orientation          = DMORIENT_PORTRAIT;
-	dm->papersize            = DMPAPER_LETTER;
-	dm->paperlength          = 0;
-	dm->paperwidth           = 0;
-	dm->scale                = 0x64;
-	dm->copies               = 1;
-	dm->defaultsource        = DMBIN_FORMSOURCE;
-	dm->printquality         = DMRES_HIGH;           /* 0x0258 */
-	dm->color                = DMRES_MONOCHROME;
-	dm->duplex               = DMDUP_SIMPLEX;
-	dm->yresolution          = 0;
-	dm->ttoption             = DMTT_SUBDEV;
-	dm->collate              = DMCOLLATE_FALSE;
-	dm->icmmethod            = 0;
-	dm->icmintent            = 0;
-	dm->mediatype            = 0;
-	dm->dithertype           = 0;
-
-	dm->logpixels            = 0;
-	dm->bitsperpel           = 0;
-	dm->pelswidth            = 0;
-	dm->pelsheight           = 0;
-	dm->displayflags         = 0;
-	dm->displayfrequency     = 0;
-	dm->reserved1            = 0;
-	dm->reserved2            = 0;
-	dm->panningwidth         = 0;
-	dm->panningheight        = 0;
-
-	dm->driverextra_data.data = NULL;
-	dm->driverextra_data.length = 0;
-
-        *devmode = dm;
-	return WERR_OK;
-}
-
-WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
-				      struct spoolss_security_descriptor **secdesc)
-{
-	struct security_ace ace[7];	/* max number of ace entries */
-	int i = 0;
-	uint32_t sa;
-	struct security_acl *psa = NULL;
-	struct security_descriptor *psd = NULL;
-	struct dom_sid adm_sid;
-	size_t sd_size;
-
-	/* Create an ACE where Everyone is allowed to print */
-
-	sa = PRINTER_ACE_PRINT;
-	init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
-		     sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
-	/* Add the domain admins group if we are a DC */
-
-	if ( IS_DC ) {
-		struct dom_sid domadmins_sid;
-
-		sid_compose(&domadmins_sid, get_global_sam_sid(),
-			    DOMAIN_RID_ADMINS);
-
-		sa = PRINTER_ACE_FULL_CONTROL;
-		init_sec_ace(&ace[i++], &domadmins_sid,
-			SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
-			SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
-		init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-			sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-	}
-	else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
-		sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
-
-		sa = PRINTER_ACE_FULL_CONTROL;
-		init_sec_ace(&ace[i++], &adm_sid,
-			SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
-			SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
-		init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-			sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-	}
-
-	/* add BUILTIN\Administrators as FULL CONTROL */
-
-	sa = PRINTER_ACE_FULL_CONTROL;
-	init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
-		SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
-		SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
-	init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
-		SEC_ACE_TYPE_ACCESS_ALLOWED,
-		sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
-	/* add BUILTIN\Print Operators as FULL CONTROL */
-
-	sa = PRINTER_ACE_FULL_CONTROL;
-	init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
-		SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
-		SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
-	init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
-		SEC_ACE_TYPE_ACCESS_ALLOWED,
-		sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
-	/* Make the security descriptor owned by the BUILTIN\Administrators */
-
-	/* The ACL revision number in rpc_secdesc.h differs from the one
-	   created by NT when setting ACE entries in printer
-	   descriptors.  NT4 complains about the property being edited by a
-	   NT5 machine. */
-
-	if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
-		psd = make_sec_desc(mem_ctx,
-				    SD_REVISION,
-				    SEC_DESC_SELF_RELATIVE,
-				    &global_sid_Builtin_Administrators,
-				    &global_sid_Builtin_Administrators,
-				    NULL,
-				    psa,
-				    &sd_size);
-	}
-
-	if (psd == NULL) {
-		DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
-		return WERR_NOMEM;
-	}
-
-	DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
-		 (unsigned int)sd_size));
-
-	*secdesc = psd;
-
-	return WERR_OK;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-static char *win_driver;
-static char *os2_driver;
-
-static const char *get_win_driver(void)
-{
-	if (win_driver == NULL) {
-		return "";
-	}
-	return win_driver;
-}
-
-static const char *get_os2_driver(void)
-{
-	if (os2_driver == NULL) {
-		return "";
-	}
-	return os2_driver;
-}
-
-static bool set_driver_mapping(const char *from, const char *to)
-{
-	SAFE_FREE(win_driver);
-	SAFE_FREE(os2_driver);
-
-	win_driver = SMB_STRDUP(from);
-	os2_driver = SMB_STRDUP(to);
-
-	if (win_driver == NULL || os2_driver == NULL) {
-		SAFE_FREE(win_driver);
-		SAFE_FREE(os2_driver);
-		return false;
-	}
-	return true;
-}
-
-/**
- * @internal
- *
- * @brief Map a Windows driver to a OS/2 driver.
- *
- * @param[in]  mem_ctx  The memory context to use.
- *
- * @param[in,out] pdrivername The drivername of Windows to remap.
- *
- * @return              WERR_OK on success, a corresponding WERROR on failure.
- */
-WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername)
-{
-	const char *mapfile = lp_os2_driver_map();
-	char **lines = NULL;
-	const char *drivername;
-	int numlines = 0;
-	int i;
-
-	if (pdrivername == NULL || *pdrivername == NULL || *pdrivername[0] == '\0') {
-		return WERR_INVALID_PARAMETER;
-	}
-
-	drivername = *pdrivername;
-
-	if (mapfile[0] == '\0') {
-		return WERR_BADFILE;
-	}
-
-	if (strequal(drivername, get_win_driver())) {
-		DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
-			drivername, get_os2_driver()));
-		drivername = talloc_strdup(mem_ctx, get_os2_driver());
-		if (drivername == NULL) {
-			return WERR_NOMEM;
-		}
-		*pdrivername = drivername;
-		return WERR_OK;
-	}
-
-	lines = file_lines_load(mapfile, &numlines, 0, NULL);
-	if (numlines == 0 || lines == NULL) {
-		DEBUG(0,("No entries in OS/2 driver map %s\n", mapfile));
-		TALLOC_FREE(lines);
-		return WERR_EMPTY;
-	}
-
-	DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
-
-	for( i = 0; i < numlines; i++) {
-		char *nt_name = lines[i];
-		char *os2_name = strchr(nt_name, '=');
-
-		if (os2_name == NULL) {
-			continue;
-		}
-
-		*os2_name++ = '\0';
-
-		while (isspace(*nt_name)) {
-			nt_name++;
-		}
-
-		if (*nt_name == '\0' || strchr("#;", *nt_name)) {
-			continue;
-		}
-
-		{
-			int l = strlen(nt_name);
-			while (l && isspace(nt_name[l - 1])) {
-				nt_name[l - 1] = 0;
-				l--;
-			}
-		}
-
-		while (isspace(*os2_name)) {
-			os2_name++;
-		}
-
-		{
-			int l = strlen(os2_name);
-			while (l && isspace(os2_name[l-1])) {
-				os2_name[l-1] = 0;
-				l--;
-			}
-		}
-
-		if (strequal(nt_name, drivername)) {
-			DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,os2_name));
-			set_driver_mapping(drivername, os2_name);
-			drivername = talloc_strdup(mem_ctx, os2_name);
-			TALLOC_FREE(lines);
-			if (drivername == NULL) {
-				return WERR_NOMEM;
-			}
-			*pdrivername = drivername;
-			return WERR_OK;
-		}
-	}
-
-	TALLOC_FREE(lines);
-	return WERR_OK;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
-			      struct spoolss_DriverInfo8 *_info8)
-{
-	struct spoolss_DriverInfo8 info8;
-
-	ZERO_STRUCT(info8);
-
-	switch (r->level) {
-	case 3:
-		info8.version		= r->info.info3->version;
-		info8.driver_name	= r->info.info3->driver_name;
-		info8.architecture	= r->info.info3->architecture;
-		info8.driver_path	= r->info.info3->driver_path;
-		info8.data_file		= r->info.info3->data_file;
-		info8.config_file	= r->info.info3->config_file;
-		info8.help_file		= r->info.info3->help_file;
-		info8.monitor_name	= r->info.info3->monitor_name;
-		info8.default_datatype	= r->info.info3->default_datatype;
-		if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
-			info8.dependent_files	= r->info.info3->dependent_files->string;
-		}
-		break;
-	case 6:
-		info8.version		= r->info.info6->version;
-		info8.driver_name	= r->info.info6->driver_name;
-		info8.architecture	= r->info.info6->architecture;
-		info8.driver_path	= r->info.info6->driver_path;
-		info8.data_file		= r->info.info6->data_file;
-		info8.config_file	= r->info.info6->config_file;
-		info8.help_file		= r->info.info6->help_file;
-		info8.monitor_name	= r->info.info6->monitor_name;
-		info8.default_datatype	= r->info.info6->default_datatype;
-		if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
-			info8.dependent_files	= r->info.info6->dependent_files->string;
-		}
-		info8.driver_date	= r->info.info6->driver_date;
-		info8.driver_version	= r->info.info6->driver_version;
-		info8.manufacturer_name = r->info.info6->manufacturer_name;
-		info8.manufacturer_url	= r->info.info6->manufacturer_url;
-		info8.hardware_id	= r->info.info6->hardware_id;
-		info8.provider		= r->info.info6->provider;
-		break;
-	case 8:
-		info8.version		= r->info.info8->version;
-		info8.driver_name	= r->info.info8->driver_name;
-		info8.architecture	= r->info.info8->architecture;
-		info8.driver_path	= r->info.info8->driver_path;
-		info8.data_file		= r->info.info8->data_file;
-		info8.config_file	= r->info.info8->config_file;
-		info8.help_file		= r->info.info8->help_file;
-		info8.monitor_name	= r->info.info8->monitor_name;
-		info8.default_datatype	= r->info.info8->default_datatype;
-		if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
-			info8.dependent_files	= r->info.info8->dependent_files->string;
-		}
-		if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
-			info8.previous_names	= r->info.info8->previous_names->string;
-		}
-		info8.driver_date	= r->info.info8->driver_date;
-		info8.driver_version	= r->info.info8->driver_version;
-		info8.manufacturer_name = r->info.info8->manufacturer_name;
-		info8.manufacturer_url	= r->info.info8->manufacturer_url;
-		info8.hardware_id	= r->info.info8->hardware_id;
-		info8.provider		= r->info.info8->provider;
-		info8.print_processor	= r->info.info8->print_processor;
-		info8.vendor_setup	= r->info.info8->vendor_setup;
-		if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
-			info8.color_profiles = r->info.info8->color_profiles->string;
-		}
-		info8.inf_path		= r->info.info8->inf_path;
-		info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
-		if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
-			info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
-		}
-		info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
-		info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
-		break;
-	default:
-		return false;
-	}
-
-	*_info8 = info8;
-
-	return true;
-}
-
-
-/****************************************************************************
   Determine whether or not a particular driver is currently assigned
   to a printer
 ****************************************************************************/
@@ -1586,6 +1183,7 @@
 	bool in_use = False;
 	struct spoolss_PrinterInfo2 *pinfo2 = NULL;
 	WERROR result;
+	struct dcerpc_binding_handle *b = NULL;
 
 	if (!r) {
 		return false;
@@ -1600,7 +1198,17 @@
 			continue;
 		}
 
-		result = winreg_get_printer(mem_ctx, session_info, msg_ctx,
+		if (b == NULL) {
+			result = winreg_printer_binding_handle(mem_ctx,
+							       session_info,
+							       msg_ctx,
+							       &b);
+			if (!W_ERROR_IS_OK(result)) {
+				return false;
+			}
+		}
+
+		result = winreg_get_printer(mem_ctx, b,
 					    lp_servicename(snum),
 					    &pinfo2);
 		if (!W_ERROR_IS_OK(result)) {
@@ -1626,18 +1234,18 @@
 		   "Windows NT x86" version 2 or 3 left */
 
 		if (!strequal("Windows NT x86", r->architecture)) {
-			werr = winreg_get_driver(mem_ctx, session_info, msg_ctx,
+			werr = winreg_get_driver(mem_ctx, b,
 						 "Windows NT x86",
 						 r->driver_name,
 						 DRIVER_ANY_VERSION,
 						 &driver);
 		} else if (r->version == 2) {
-			werr = winreg_get_driver(mem_ctx, session_info, msg_ctx,
+			werr = winreg_get_driver(mem_ctx, b,
 						 "Windows NT x86",
 						 r->driver_name,
 						 3, &driver);
 		} else if (r->version == 3) {
-			werr = winreg_get_driver(mem_ctx, session_info, msg_ctx,
+			werr = winreg_get_driver(mem_ctx, b,
 						 "Windows NT x86",
 						 r->driver_name,
 						 2, &driver);
@@ -1816,6 +1424,7 @@
 	uint32_t num_drivers;
 	const char **drivers;
 	WERROR result;
+	struct dcerpc_binding_handle *b;
 
 	if ( !info )
 		return False;
@@ -1828,7 +1437,15 @@
 
 	/* get the list of drivers */
 
-	result = winreg_get_driver_list(mem_ctx, session_info, msg_ctx,
+	result = winreg_printer_binding_handle(mem_ctx,
+					       session_info,
+					       msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(result)) {
+		return false;
+	}
+
+	result = winreg_get_driver_list(mem_ctx, b,
 					info->architecture, version,
 					&num_drivers, &drivers);
 	if (!W_ERROR_IS_OK(result)) {
@@ -1845,7 +1462,7 @@
 
 		driver = NULL;
 
-		result = winreg_get_driver(mem_ctx, session_info, msg_ctx,
+		result = winreg_get_driver(mem_ctx, b,
 					   info->architecture, drivers[i],
 					   version, &driver);
 		if (!W_ERROR_IS_OK(result)) {
@@ -2141,7 +1758,7 @@
 		return False;
 	}
 
-	result = winreg_get_printer_secdesc(mem_ctx,
+	result = winreg_get_printer_secdesc_internal(mem_ctx,
 					    get_session_info_system(),
 					    msg_ctx,
 					    pname,
@@ -2217,7 +1834,7 @@
 	struct tm *t;
 	uint32 mins;
 
-	result = winreg_get_printer(NULL, session_info, msg_ctx,
+	result = winreg_get_printer_internal(NULL, session_info, msg_ctx,
 				    servicename, &pinfo2);
 	if (!W_ERROR_IS_OK(result)) {
 		return False;
@@ -2250,7 +1867,7 @@
 {
 	WERROR result;
 
-	result = winreg_delete_printer_key(mem_ctx, session_info, msg_ctx,
+	result = winreg_delete_printer_key_internal(mem_ctx, session_info, msg_ctx,
 					   printer, "");
 	if (!W_ERROR_IS_OK(result)) {
 		DEBUG(0, ("nt_printer_remove: failed to remove rpinter %s",

Modified: branches/samba/experimental/source3/printing/nt_printing_ads.c
===================================================================
--- branches/samba/experimental/source3/printing/nt_printing_ads.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/printing/nt_printing_ads.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -29,6 +29,7 @@
 #include "../libcli/registry/util_reg.h"
 #include "auth.h"
 #include "../librpc/ndr/libndr.h"
+#include "rpc_client/cli_winreg_spoolss.h"
 
 #ifdef HAVE_ADS
 /*****************************************************************
@@ -73,7 +74,7 @@
 		goto done;
 	}
 
-	result = winreg_set_printer_dataex(tmp_ctx, session_info, msg_ctx,
+	result = winreg_set_printer_dataex_internal(tmp_ctx, session_info, msg_ctx,
 					   printer,
 					   SPOOL_DSSPOOLER_KEY, "objectGUID",
 					   REG_SZ, blob.data, blob.length);
@@ -274,7 +275,7 @@
 
 	sinfo2->attributes = pinfo2->attributes;
 
-	win_rc = winreg_update_printer(mem_ctx, session_info, msg_ctx,
+	win_rc = winreg_update_printer_internal(mem_ctx, session_info, msg_ctx,
 					pinfo2->sharename, info2_mask,
 					sinfo2, NULL, NULL);
 	if (!W_ERROR_IS_OK(win_rc)) {
@@ -364,7 +365,7 @@
 			continue;
 		}
 
-		result = winreg_get_printer(tmp_ctx, session_info, msg_ctx,
+		result = winreg_get_printer_internal(tmp_ctx, session_info, msg_ctx,
 					    lp_servicename(snum),
 					    &pinfo2);
 		if (!W_ERROR_IS_OK(result)) {
@@ -398,8 +399,17 @@
 	uint32_t data_size;
 	WERROR result;
 	NTSTATUS status;
+	struct dcerpc_binding_handle *b;
 
-	result = winreg_get_printer(mem_ctx, session_info, msg_ctx,
+	result = winreg_printer_binding_handle(mem_ctx,
+					       session_info,
+					       msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(result)) {
+		return false;
+	}
+
+	result = winreg_get_printer(mem_ctx, b,
 				    printer, &pinfo2);
 	if (!W_ERROR_IS_OK(result)) {
 		return false;
@@ -416,7 +426,7 @@
 
 	/* fetching printer guids really ought to be a separate function. */
 
-	result = winreg_get_printer_dataex(mem_ctx, session_info, msg_ctx,
+	result = winreg_get_printer_dataex(mem_ctx, b,
 					   printer,
 					   SPOOL_DSSPOOLER_KEY, "objectGUID",
 					   &type, &data, &data_size);

Modified: branches/samba/experimental/source3/printing/nt_printing_migrate.c
===================================================================
--- branches/samba/experimental/source3/printing/nt_printing_migrate.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/printing/nt_printing_migrate.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -19,41 +19,27 @@
  */
 
 #include "includes.h"
-#include "system/filesys.h"
 #include "printing/nt_printing_migrate.h"
 
 #include "rpc_client/rpc_client.h"
 #include "librpc/gen_ndr/ndr_ntprinting.h"
 #include "librpc/gen_ndr/ndr_spoolss_c.h"
 #include "librpc/gen_ndr/ndr_security.h"
-#include "rpc_server/rpc_ncacn_np.h"
-#include "auth.h"
-#include "util_tdb.h"
+#include "rpc_client/cli_winreg_spoolss.h"
 
-#define FORMS_PREFIX "FORMS/"
-#define DRIVERS_PREFIX "DRIVERS/"
-#define PRINTERS_PREFIX "PRINTERS/"
-#define SECDESC_PREFIX "SECDESC/"
-
-static NTSTATUS migrate_form(TALLOC_CTX *mem_ctx,
-			 struct rpc_pipe_client *pipe_hnd,
-			 const char *key_name,
-			 unsigned char *data,
-			 size_t length)
+NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx,
+				   struct rpc_pipe_client *winreg_pipe,
+				   const char *key_name,
+				   unsigned char *data,
+				   size_t length)
 {
-	struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
-	struct spoolss_DevmodeContainer devmode_ctr;
-	struct policy_handle hnd;
+	struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
 	enum ndr_err_code ndr_err;
 	struct ntprinting_form r;
-	union spoolss_AddFormInfo f;
 	struct spoolss_AddFormInfo1 f1;
-	const char *srv_name_slash;
 	DATA_BLOB blob;
-	NTSTATUS status;
 	WERROR result;
 
-
 	blob = data_blob_const(data, length);
 
 	ZERO_STRUCT(r);
@@ -73,33 +59,6 @@
 
 	DEBUG(2, ("Migrating Form: %s\n", key_name));
 
-	srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
-	if (srv_name_slash == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	ZERO_STRUCT(devmode_ctr);
-
-	status = dcerpc_spoolss_OpenPrinter(b,
-					    mem_ctx,
-					    srv_name_slash,
-					    NULL,
-					    devmode_ctr,
-					    SEC_FLAG_MAXIMUM_ALLOWED,
-					    &hnd,
-					    &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(2, ("dcerpc_spoolss_OpenPrinter(%s) failed: %s\n",
-			  srv_name_slash, nt_errstr(status)));
-		return status;
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("OpenPrinter(%s) failed: %s\n",
-			  srv_name_slash, win_errstr(result)));
-		status = werror_to_ntstatus(result);
-		return status;
-	}
-
 	f1.form_name = key_name;
 	f1.flags = r.flag;
 
@@ -111,44 +70,32 @@
 	f1.area.bottom = r.bottom;
 	f1.area.left = r.left;
 
-	f.info1 = &f1;
-
-	status = dcerpc_spoolss_AddForm(b,
-					mem_ctx,
-					&hnd,
-					1,
-					f,
-					&result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(2, ("dcerpc_spoolss_AddForm(%s) refused -- %s.\n",
-			  f.info1->form_name, nt_errstr(status)));
-	} else if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("AddForm(%s) refused -- %s.\n",
-			  f.info1->form_name, win_errstr(result)));
-		status = werror_to_ntstatus(result);
+	result = winreg_printer_addform1(mem_ctx,
+					 b,
+					 &f1);
+	if (!W_ERROR_IS_OK(result)) {
+		return werror_to_ntstatus(result);
 	}
 
-	dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
-
-	return status;
+	return NT_STATUS_OK;
 }
 
-static NTSTATUS migrate_driver(TALLOC_CTX *mem_ctx,
-			       struct rpc_pipe_client *pipe_hnd,
-			       const char *key_name,
-			       unsigned char *data,
-			       size_t length)
+NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx,
+				     struct rpc_pipe_client *winreg_pipe,
+				     const char *key_name,
+				     unsigned char *data,
+				     size_t length)
 {
-	struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
-	const char *srv_name_slash;
+	struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
 	enum ndr_err_code ndr_err;
 	struct ntprinting_driver r;
 	struct spoolss_AddDriverInfoCtr d;
 	struct spoolss_AddDriverInfo3 d3;
 	struct spoolss_StringArray a;
 	DATA_BLOB blob;
-	NTSTATUS status;
 	WERROR result;
+	const char *driver_name;
+	uint32_t driver_version;
 
 	blob = data_blob_const(data, length);
 
@@ -164,11 +111,6 @@
 
 	DEBUG(2, ("Migrating Printer Driver: %s\n", key_name));
 
-	srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
-	if (srv_name_slash == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
 	ZERO_STRUCT(d3);
 	ZERO_STRUCT(a);
 
@@ -188,42 +130,36 @@
 	d.level = 3;
 	d.info.info3 = &d3;
 
-	status = dcerpc_spoolss_AddPrinterDriver(b,
-						 mem_ctx,
-						 srv_name_slash,
-						 &d,
-						 &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(2, ("dcerpc_spoolss_AddPrinterDriver(%s) refused -- %s.\n",
-			  d3.driver_name, nt_errstr(status)));
-	} else if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("AddPrinterDriver(%s) refused -- %s.\n",
-			  d3.driver_name, win_errstr(result)));
-		status = werror_to_ntstatus(result);
+	result = winreg_add_driver(mem_ctx,
+				   b,
+				   &d,
+				   &driver_name,
+				   &driver_version);
+	if (!W_ERROR_IS_OK(result)) {
+		return werror_to_ntstatus(result);
 	}
 
-	return status;
+	return NT_STATUS_OK;
 }
 
-static NTSTATUS migrate_printer(TALLOC_CTX *mem_ctx,
-				struct rpc_pipe_client *pipe_hnd,
-				const char *key_name,
-				unsigned char *data,
-				size_t length)
+NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx,
+				      struct rpc_pipe_client *winreg_pipe,
+				      const char *key_name,
+				      unsigned char *data,
+				      size_t length)
 {
-	struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
-	struct policy_handle hnd;
+	struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
 	enum ndr_err_code ndr_err;
 	struct ntprinting_printer r;
 	struct spoolss_SetPrinterInfo2 info2;
 	struct spoolss_DeviceMode dm;
-	struct spoolss_SetPrinterInfoCtr info_ctr;
 	struct spoolss_DevmodeContainer devmode_ctr;
-	struct sec_desc_buf secdesc_ctr;
 	DATA_BLOB blob;
 	NTSTATUS status;
 	WERROR result;
 	int j;
+	uint32_t info2_mask = (SPOOLSS_PRINTER_INFO_ALL)
+				& ~SPOOLSS_PRINTER_INFO_SECDESC;
 
 	if (strequal(key_name, "printers")) {
 		return NT_STATUS_OK;
@@ -245,29 +181,8 @@
 
 	ZERO_STRUCT(devmode_ctr);
 
-	status = dcerpc_spoolss_OpenPrinter(b,
-					    mem_ctx,
-					    key_name,
-					    NULL,
-					    devmode_ctr,
-					    SEC_FLAG_MAXIMUM_ALLOWED,
-					    &hnd,
-					    &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(2, ("dcerpc_spoolss_OpenPrinter(%s) failed: %s\n",
-			  key_name, nt_errstr(status)));
-		return status;
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("OpenPrinter(%s) failed: %s\n",
-			  key_name, win_errstr(result)));
-		status = werror_to_ntstatus(result);
-		return status;
-	}
-
 	/* Create printer info level 2 */
 	ZERO_STRUCT(info2);
-	ZERO_STRUCT(secdesc_ctr);
 
 	info2.attributes = r.info.attributes;
 	info2.averageppm = r.info.averageppm;
@@ -289,7 +204,9 @@
 	info2.untiltime = r.info.untiltime;
 
 	/* Create Device Mode */
-	if (r.devmode != NULL) {
+	if (r.devmode == NULL) {
+		info2_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
+	} else {
 		ZERO_STRUCT(dm);
 
 		dm.bitsperpel              = r.devmode->bitsperpel;
@@ -318,6 +235,7 @@
 		dm.pelsheight              = r.devmode->pelsheight;
 		dm.pelswidth               = r.devmode->pelswidth;
 		dm.printquality            = r.devmode->printquality;
+		dm.size                    = r.devmode->size;
 		dm.scale                   = r.devmode->scale;
 		dm.specversion             = r.devmode->specversion;
 		dm.ttoption                = r.devmode->ttoption;
@@ -334,22 +252,12 @@
 		info2.devmode_ptr = 1;
 	}
 
-	info_ctr.info.info2 = &info2;
-	info_ctr.level = 2;
-
-	status = dcerpc_spoolss_SetPrinter(b,
-					   mem_ctx,
-					   &hnd,
-					   &info_ctr,
-					   &devmode_ctr,
-					   &secdesc_ctr,
-					   0, /* command */
-					   &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(2, ("dcerpc_spoolss_SetPrinter(%s) level 2 refused -- %s.\n",
-			  key_name, nt_errstr(status)));
-		goto done;
-	}
+	result = winreg_update_printer(mem_ctx, b,
+				       key_name,
+				       info2_mask,
+				       &info2,
+				       &dm,
+				       NULL);
 	if (!W_ERROR_IS_OK(result)) {
 		DEBUG(2, ("SetPrinter(%s) level 2 refused -- %s.\n",
 			  key_name, win_errstr(result)));
@@ -375,23 +283,13 @@
 			valuename++;
 		}
 
-		status = dcerpc_spoolss_SetPrinterDataEx(b,
-							 mem_ctx,
-							 &hnd,
-							 keyname,
-							 valuename,
-							 r.printer_data[j].type,
-							 r.printer_data[j].data.data,
-							 r.printer_data[j].data.length,
-							 &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(2, ("dcerpc_spoolss_SetPrinterDataEx: "
-				  "printer [%s], keyname [%s], "
-				  "valuename [%s] refused -- %s.\n",
-				  key_name, keyname, valuename,
-				  nt_errstr(status)));
-			break;
-		}
+		result = winreg_set_printer_dataex(mem_ctx, b,
+						   key_name,
+						   keyname,
+						   valuename,
+						   r.printer_data[j].type,
+						   r.printer_data[j].data.data,
+						   r.printer_data[j].data.length);
 		if (!W_ERROR_IS_OK(result)) {
 			DEBUG(2, ("SetPrinterDataEx: printer [%s], keyname [%s], "
 				  "valuename [%s] refused -- %s.\n",
@@ -402,27 +300,22 @@
 		}
 	}
 
+	status = NT_STATUS_OK;
  done:
-	dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
 
 	return status;
 }
 
-static NTSTATUS migrate_secdesc(TALLOC_CTX *mem_ctx,
-				struct rpc_pipe_client *pipe_hnd,
-				const char *key_name,
-				unsigned char *data,
-				size_t length)
+NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx,
+				      struct rpc_pipe_client *winreg_pipe,
+				      const char *key_name,
+				      unsigned char *data,
+				      size_t length)
 {
-	struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
-	struct policy_handle hnd;
+	struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
 	enum ndr_err_code ndr_err;
 	struct sec_desc_buf secdesc_ctr;
-	struct spoolss_SetPrinterInfo3 info3;
-	struct spoolss_SetPrinterInfoCtr info_ctr;
-	struct spoolss_DevmodeContainer devmode_ctr;
 	DATA_BLOB blob;
-	NTSTATUS status;
 	WERROR result;
 
 	if (strequal(key_name, "printers")) {
@@ -443,257 +336,12 @@
 
 	DEBUG(2, ("Migrating Security Descriptor: %s\n", key_name));
 
-	ZERO_STRUCT(devmode_ctr);
-
-	status = dcerpc_spoolss_OpenPrinter(b,
-					    mem_ctx,
+	result = winreg_set_printer_secdesc(mem_ctx, b,
 					    key_name,
-					    NULL,
-					    devmode_ctr,
-					    SEC_FLAG_MAXIMUM_ALLOWED,
-					    &hnd,
-					    &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(2, ("dcerpc_spoolss_OpenPrinter(%s) failed: %s\n",
-			  key_name, nt_errstr(status)));
-		return status;
-	}
-	if (W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME, result)) {
-		DEBUG(3, ("Ignoring missing printer %s\n", key_name));
-		return NT_STATUS_OK;
-	}
+					    secdesc_ctr.sd);
 	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("OpenPrinter(%s) failed: %s\n",
-			  key_name, win_errstr(result)));
-		status = werror_to_ntstatus(result);
-		return status;
+		return werror_to_ntstatus(result);
 	}
 
-	ZERO_STRUCT(devmode_ctr);
-
-	info3.sec_desc_ptr = 1;
-
-	info_ctr.info.info3 = &info3;
-	info_ctr.level = 3;
-
-	status = dcerpc_spoolss_SetPrinter(b,
-					   mem_ctx,
-					   &hnd,
-					   &info_ctr,
-					   &devmode_ctr,
-					   &secdesc_ctr,
-					   0, /* command */
-					   &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(2, ("dcerpc_spoolss_SetPrinter(%s) level 3 refused -- %s.\n",
-			  key_name, nt_errstr(status)));
-	} else if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("SetPrinter(%s) level 3 refused -- %s.\n",
-			  key_name, win_errstr(result)));
-		status = werror_to_ntstatus(result);
-	}
-
-	dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
-
-	return status;
-}
-
-static int rename_file_with_suffix(TALLOC_CTX *mem_ctx,
-				   const char *path,
-				   const char *suffix)
-{
-	int rc = -1;
-	char *dst_path;
-
-	dst_path = talloc_asprintf(mem_ctx, "%s%s", path, suffix);
-	if (dst_path == NULL) {
-		DEBUG(3, ("error out of memory\n"));
-		return rc;
-	}
-
-	rc = (rename(path, dst_path) != 0);
-
-	if (rc == 0) {
-		DEBUG(5, ("moved '%s' to '%s'\n", path, dst_path));
-	} else if (errno == ENOENT) {
-		DEBUG(3, ("file '%s' does not exist - so not moved\n", path));
-		rc = 0;
-	} else {
-		DEBUG(3, ("error renaming %s to %s: %s\n", path, dst_path,
-			  strerror(errno)));
-	}
-
-	TALLOC_FREE(dst_path);
-	return rc;
-}
-
-static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx,
-				 const char *tdb_path,
-				 struct rpc_pipe_client *pipe_hnd)
-{
-	const char *backup_suffix = ".bak";
-	TDB_DATA kbuf, newkey, dbuf;
-	TDB_CONTEXT *tdb;
-	NTSTATUS status;
-	int rc;
-
-	tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDONLY, 0600);
-	if (tdb == NULL && errno == ENOENT) {
-		/* if we have no printers database then migration is
-		   considered successful */
-		DEBUG(4, ("No printers database to migrate in %s\n", tdb_path));
-		return NT_STATUS_OK;
-	}
-	if (tdb == NULL) {
-		DEBUG(2, ("Failed to open tdb file: %s\n", tdb_path));
-		return NT_STATUS_NO_SUCH_FILE;
-	}
-
-	for (kbuf = tdb_firstkey(tdb);
-	     kbuf.dptr;
-	     newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
-	{
-		dbuf = tdb_fetch(tdb, kbuf);
-		if (!dbuf.dptr) {
-			continue;
-		}
-
-		if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
-			status = migrate_form(mem_ctx,
-					      pipe_hnd,
-					      (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
-					      dbuf.dptr,
-					      dbuf.dsize);
-			SAFE_FREE(dbuf.dptr);
-			if (!NT_STATUS_IS_OK(status)) {
-				tdb_close(tdb);
-				return status;
-			}
-			continue;
-		}
-
-		if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
-			status = migrate_driver(mem_ctx,
-						pipe_hnd,
-						(const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
-						dbuf.dptr,
-						dbuf.dsize);
-			SAFE_FREE(dbuf.dptr);
-			if (!NT_STATUS_IS_OK(status)) {
-				tdb_close(tdb);
-				return status;
-			}
-			continue;
-		}
-
-		if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
-			status = migrate_printer(mem_ctx,
-						 pipe_hnd,
-						 (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
-						 dbuf.dptr,
-						 dbuf.dsize);
-			SAFE_FREE(dbuf.dptr);
-			if (!NT_STATUS_IS_OK(status)) {
-				tdb_close(tdb);
-				return status;
-			}
-			continue;
-		}
-
-		if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
-			status = migrate_secdesc(mem_ctx,
-						 pipe_hnd,
-						 (const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
-						 dbuf.dptr,
-						 dbuf.dsize);
-			SAFE_FREE(dbuf.dptr);
-			if (!NT_STATUS_IS_OK(status)) {
-				tdb_close(tdb);
-				return status;
-			}
-			continue;
-		}
-	}
-
-	tdb_close(tdb);
-
-	rc = rename_file_with_suffix(mem_ctx, tdb_path, backup_suffix);
-	if (rc != 0) {
-		DEBUG(0, ("Error moving tdb to '%s%s'\n",
-			  tdb_path, backup_suffix));
-	}
-
 	return NT_STATUS_OK;
 }
-
-bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx)
-{
-	const char *drivers_path = state_path("ntdrivers.tdb");
-	const char *printers_path = state_path("ntprinters.tdb");
-	const char *forms_path = state_path("ntforms.tdb");
-	bool drivers_exists = file_exist(drivers_path);
-	bool printers_exists = file_exist(printers_path);
-	bool forms_exists = file_exist(forms_path);
-	struct auth_serversupplied_info *session_info;
-	struct rpc_pipe_client *spoolss_pipe = NULL;
-	TALLOC_CTX *tmp_ctx = talloc_stackframe();
-	NTSTATUS status;
-
-	if (!drivers_exists && !printers_exists && !forms_exists) {
-		return true;
-	}
-
-	status = make_session_info_system(tmp_ctx, &session_info);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("Couldn't create session_info: %s\n",
-			  nt_errstr(status)));
-		talloc_free(tmp_ctx);
-		return false;
-	}
-
-	status = rpc_pipe_open_interface(tmp_ctx,
-					&ndr_table_spoolss.syntax_id,
-					session_info,
-					NULL,
-					msg_ctx,
-					&spoolss_pipe);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("Couldn't open internal spoolss pipe: %s\n",
-			  nt_errstr(status)));
-		talloc_free(tmp_ctx);
-		return false;
-	}
-
-	if (drivers_exists) {
-		status = migrate_internal(tmp_ctx, drivers_path, spoolss_pipe);
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0, ("Couldn't migrate drivers tdb file: %s\n",
-			  nt_errstr(status)));
-			talloc_free(tmp_ctx);
-			return false;
-		}
-	}
-
-	if (printers_exists) {
-		status = migrate_internal(tmp_ctx, printers_path, spoolss_pipe);
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0, ("Couldn't migrate printers tdb file: %s\n",
-				  nt_errstr(status)));
-			talloc_free(tmp_ctx);
-			return false;
-		}
-	}
-
-	if (forms_exists) {
-		status = migrate_internal(tmp_ctx, forms_path, spoolss_pipe);
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0, ("Couldn't migrate forms tdb file: %s\n",
-				  nt_errstr(status)));
-			talloc_free(tmp_ctx);
-			return false;
-		}
-	}
-
-	talloc_free(tmp_ctx);
-	return true;
-}

Modified: branches/samba/experimental/source3/printing/nt_printing_migrate.h
===================================================================
--- branches/samba/experimental/source3/printing/nt_printing_migrate.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/printing/nt_printing_migrate.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -21,6 +21,25 @@
 #ifndef _NT_PRINTING_MIGRATE_H_
 #define _NT_PRINTING_MIGRATE_H_
 
-bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx);
+NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx,
+				   struct rpc_pipe_client *winreg_pipe,
+				   const char *key_name,
+				   unsigned char *data,
+				   size_t length);
+NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx,
+				     struct rpc_pipe_client *winreg_pipe,
+				     const char *key_name,
+				     unsigned char *data,
+				     size_t length);
+NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx,
+				      struct rpc_pipe_client *winreg_pipe,
+				      const char *key_name,
+				      unsigned char *data,
+				      size_t length);
+NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx,
+				      struct rpc_pipe_client *winreg_pipe,
+				      const char *key_name,
+				      unsigned char *data,
+				      size_t length);
 
 #endif /* _NT_PRINTING_MIGRATE_H_ */

Copied: branches/samba/experimental/source3/printing/nt_printing_migrate_internal.c (from rev 3862, tags/samba/upstream_3.6.0~rc3/source3/printing/nt_printing_migrate_internal.c)
===================================================================
--- branches/samba/experimental/source3/printing/nt_printing_migrate_internal.c	                        (rev 0)
+++ branches/samba/experimental/source3/printing/nt_printing_migrate_internal.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -0,0 +1,255 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *
+ *  Copyright (c) Andreas Schneider            2010.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "system/filesys.h"
+#include "printing/nt_printing_migrate.h"
+#include "printing/nt_printing_migrate_internal.h"
+
+#include "rpc_client/rpc_client.h"
+#include "librpc/gen_ndr/ndr_spoolss_c.h"
+#include "librpc/gen_ndr/ndr_winreg.h"
+#include "rpc_server/rpc_ncacn_np.h"
+#include "auth.h"
+#include "util_tdb.h"
+
+#define FORMS_PREFIX "FORMS/"
+#define DRIVERS_PREFIX "DRIVERS/"
+#define PRINTERS_PREFIX "PRINTERS/"
+#define SECDESC_PREFIX "SECDESC/"
+
+static int rename_file_with_suffix(TALLOC_CTX *mem_ctx,
+				   const char *path,
+				   const char *suffix)
+{
+	int rc = -1;
+	char *dst_path;
+
+	dst_path = talloc_asprintf(mem_ctx, "%s%s", path, suffix);
+	if (dst_path == NULL) {
+		DEBUG(3, ("error out of memory\n"));
+		return rc;
+	}
+
+	rc = (rename(path, dst_path) != 0);
+
+	if (rc == 0) {
+		DEBUG(5, ("moved '%s' to '%s'\n", path, dst_path));
+	} else if (errno == ENOENT) {
+		DEBUG(3, ("file '%s' does not exist - so not moved\n", path));
+		rc = 0;
+	} else {
+		DEBUG(3, ("error renaming %s to %s: %s\n", path, dst_path,
+			  strerror(errno)));
+	}
+
+	TALLOC_FREE(dst_path);
+	return rc;
+}
+
+static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx,
+				 const char *tdb_path,
+				 struct rpc_pipe_client *winreg_pipe)
+{
+	const char *backup_suffix = ".bak";
+	TDB_DATA kbuf, newkey, dbuf;
+	TDB_CONTEXT *tdb;
+	NTSTATUS status;
+	int rc;
+
+	tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDONLY, 0600);
+	if (tdb == NULL && errno == ENOENT) {
+		/* if we have no printers database then migration is
+		   considered successful */
+		DEBUG(4, ("No printers database to migrate in %s\n", tdb_path));
+		return NT_STATUS_OK;
+	}
+	if (tdb == NULL) {
+		DEBUG(2, ("Failed to open tdb file: %s\n", tdb_path));
+		return NT_STATUS_NO_SUCH_FILE;
+	}
+
+	for (kbuf = tdb_firstkey(tdb);
+	     kbuf.dptr;
+	     newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
+	{
+		dbuf = tdb_fetch(tdb, kbuf);
+		if (!dbuf.dptr) {
+			continue;
+		}
+
+		if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
+			status = printing_tdb_migrate_form(mem_ctx,
+					      winreg_pipe,
+					      (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
+					      dbuf.dptr,
+					      dbuf.dsize);
+			SAFE_FREE(dbuf.dptr);
+			if (!NT_STATUS_IS_OK(status)) {
+				tdb_close(tdb);
+				return status;
+			}
+			continue;
+		}
+
+		if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
+			status = printing_tdb_migrate_driver(mem_ctx,
+						winreg_pipe,
+						(const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
+						dbuf.dptr,
+						dbuf.dsize);
+			SAFE_FREE(dbuf.dptr);
+			if (!NT_STATUS_IS_OK(status)) {
+				tdb_close(tdb);
+				return status;
+			}
+			continue;
+		}
+
+		if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
+			const char *printer_name = (const char *)(kbuf.dptr
+						    + strlen(PRINTERS_PREFIX));
+			status = printing_tdb_migrate_printer(mem_ctx,
+						 winreg_pipe,
+						 printer_name,
+						 dbuf.dptr,
+						 dbuf.dsize);
+			SAFE_FREE(dbuf.dptr);
+			if (!NT_STATUS_IS_OK(status)) {
+				tdb_close(tdb);
+				return status;
+			}
+			continue;
+		}
+		SAFE_FREE(dbuf.dptr);
+	}
+
+	for (kbuf = tdb_firstkey(tdb);
+	     kbuf.dptr;
+	     newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
+	{
+		dbuf = tdb_fetch(tdb, kbuf);
+		if (!dbuf.dptr) {
+			continue;
+		}
+
+		if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
+			const char *secdesc_name = (const char *)(kbuf.dptr
+						    + strlen(SECDESC_PREFIX));
+			status = printing_tdb_migrate_secdesc(mem_ctx,
+						 winreg_pipe,
+						 secdesc_name,
+						 dbuf.dptr,
+						 dbuf.dsize);
+			SAFE_FREE(dbuf.dptr);
+			if (NT_STATUS_EQUAL(status, werror_to_ntstatus(WERR_BADFILE))) {
+				DEBUG(2, ("Skipping secdesc migration for non-existent "
+						"printer: %s\n", secdesc_name));
+			} else if (!NT_STATUS_IS_OK(status)) {
+				tdb_close(tdb);
+				return status;
+			}
+			continue;
+		}
+		SAFE_FREE(dbuf.dptr);
+	}
+
+	tdb_close(tdb);
+
+	rc = rename_file_with_suffix(mem_ctx, tdb_path, backup_suffix);
+	if (rc != 0) {
+		DEBUG(0, ("Error moving tdb to '%s%s'\n",
+			  tdb_path, backup_suffix));
+	}
+
+	return NT_STATUS_OK;
+}
+
+bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx)
+{
+	const char *drivers_path = state_path("ntdrivers.tdb");
+	const char *printers_path = state_path("ntprinters.tdb");
+	const char *forms_path = state_path("ntforms.tdb");
+	bool drivers_exists = file_exist(drivers_path);
+	bool printers_exists = file_exist(printers_path);
+	bool forms_exists = file_exist(forms_path);
+	struct auth_serversupplied_info *session_info;
+	struct rpc_pipe_client *winreg_pipe = NULL;
+	TALLOC_CTX *tmp_ctx = talloc_stackframe();
+	NTSTATUS status;
+
+	if (!drivers_exists && !printers_exists && !forms_exists) {
+		return true;
+	}
+
+	status = make_session_info_system(tmp_ctx, &session_info);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("Couldn't create session_info: %s\n",
+			  nt_errstr(status)));
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	status = rpc_pipe_open_interface(tmp_ctx,
+					&ndr_table_winreg.syntax_id,
+					session_info,
+					NULL,
+					msg_ctx,
+					&winreg_pipe);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("Couldn't open internal winreg pipe: %s\n",
+			  nt_errstr(status)));
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	if (drivers_exists) {
+		status = migrate_internal(tmp_ctx, drivers_path, winreg_pipe);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0, ("Couldn't migrate drivers tdb file: %s\n",
+			  nt_errstr(status)));
+			talloc_free(tmp_ctx);
+			return false;
+		}
+	}
+
+	if (printers_exists) {
+		status = migrate_internal(tmp_ctx, printers_path, winreg_pipe);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0, ("Couldn't migrate printers tdb file: %s\n",
+				  nt_errstr(status)));
+			talloc_free(tmp_ctx);
+			return false;
+		}
+	}
+
+	if (forms_exists) {
+		status = migrate_internal(tmp_ctx, forms_path, winreg_pipe);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0, ("Couldn't migrate forms tdb file: %s\n",
+				  nt_errstr(status)));
+			talloc_free(tmp_ctx);
+			return false;
+		}
+	}
+
+	talloc_free(tmp_ctx);
+	return true;
+}

Copied: branches/samba/experimental/source3/printing/nt_printing_migrate_internal.h (from rev 3862, tags/samba/upstream_3.6.0~rc3/source3/printing/nt_printing_migrate_internal.h)
===================================================================
--- branches/samba/experimental/source3/printing/nt_printing_migrate_internal.h	                        (rev 0)
+++ branches/samba/experimental/source3/printing/nt_printing_migrate_internal.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -0,0 +1,26 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *
+ *  Copyright (c) Andreas Schneider            2010.
+ *
+ *  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/>.
+ */
+
+#ifndef _NT_PRINTING_MIGRATE_INTERNAL_H_
+#define _NT_PRINTING_MIGRATE_INTERNAL_H_
+
+bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx);
+
+#endif /* _NT_PRINTING_MIGRATE_INTERNAL_H_ */

Copied: branches/samba/experimental/source3/printing/nt_printing_os2.c (from rev 3862, tags/samba/upstream_3.6.0~rc3/source3/printing/nt_printing_os2.c)
===================================================================
--- branches/samba/experimental/source3/printing/nt_printing_os2.c	                        (rev 0)
+++ branches/samba/experimental/source3/printing/nt_printing_os2.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -0,0 +1,165 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Andrew Tridgell              1992-2000,
+ *  Copyright (C) Jean François Micouleau      1998-2000.
+ *  Copyright (C) Gerald Carter                2002-2005.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "printing/nt_printing_os2.h"
+
+/****************************************************************************
+ ***************************************************************************/
+
+static char *win_driver;
+static char *os2_driver;
+
+static const char *get_win_driver(void)
+{
+	if (win_driver == NULL) {
+		return "";
+	}
+	return win_driver;
+}
+
+static const char *get_os2_driver(void)
+{
+	if (os2_driver == NULL) {
+		return "";
+	}
+	return os2_driver;
+}
+
+static bool set_driver_mapping(const char *from, const char *to)
+{
+	SAFE_FREE(win_driver);
+	SAFE_FREE(os2_driver);
+
+	win_driver = SMB_STRDUP(from);
+	os2_driver = SMB_STRDUP(to);
+
+	if (win_driver == NULL || os2_driver == NULL) {
+		SAFE_FREE(win_driver);
+		SAFE_FREE(os2_driver);
+		return false;
+	}
+	return true;
+}
+
+/**
+ * @internal
+ *
+ * @brief Map a Windows driver to a OS/2 driver.
+ *
+ * @param[in]  mem_ctx  The memory context to use.
+ *
+ * @param[in,out] pdrivername The drivername of Windows to remap.
+ *
+ * @return              WERR_OK on success, a corresponding WERROR on failure.
+ */
+WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername)
+{
+	const char *mapfile = lp_os2_driver_map();
+	char **lines = NULL;
+	const char *drivername;
+	int numlines = 0;
+	int i;
+
+	if (pdrivername == NULL || *pdrivername == NULL || *pdrivername[0] == '\0') {
+		return WERR_INVALID_PARAMETER;
+	}
+
+	drivername = *pdrivername;
+
+	if (mapfile[0] == '\0') {
+		return WERR_BADFILE;
+	}
+
+	if (strequal(drivername, get_win_driver())) {
+		DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
+			drivername, get_os2_driver()));
+		drivername = talloc_strdup(mem_ctx, get_os2_driver());
+		if (drivername == NULL) {
+			return WERR_NOMEM;
+		}
+		*pdrivername = drivername;
+		return WERR_OK;
+	}
+
+	lines = file_lines_load(mapfile, &numlines, 0, NULL);
+	if (numlines == 0 || lines == NULL) {
+		DEBUG(0,("No entries in OS/2 driver map %s\n", mapfile));
+		TALLOC_FREE(lines);
+		return WERR_EMPTY;
+	}
+
+	DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
+
+	for( i = 0; i < numlines; i++) {
+		char *nt_name = lines[i];
+		char *os2_name = strchr(nt_name, '=');
+
+		if (os2_name == NULL) {
+			continue;
+		}
+
+		*os2_name++ = '\0';
+
+		while (isspace(*nt_name)) {
+			nt_name++;
+		}
+
+		if (*nt_name == '\0' || strchr("#;", *nt_name)) {
+			continue;
+		}
+
+		{
+			int l = strlen(nt_name);
+			while (l && isspace(nt_name[l - 1])) {
+				nt_name[l - 1] = 0;
+				l--;
+			}
+		}
+
+		while (isspace(*os2_name)) {
+			os2_name++;
+		}
+
+		{
+			int l = strlen(os2_name);
+			while (l && isspace(os2_name[l-1])) {
+				os2_name[l-1] = 0;
+				l--;
+			}
+		}
+
+		if (strequal(nt_name, drivername)) {
+			DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,os2_name));
+			set_driver_mapping(drivername, os2_name);
+			drivername = talloc_strdup(mem_ctx, os2_name);
+			TALLOC_FREE(lines);
+			if (drivername == NULL) {
+				return WERR_NOMEM;
+			}
+			*pdrivername = drivername;
+			return WERR_OK;
+		}
+	}
+
+	TALLOC_FREE(lines);
+	return WERR_OK;
+}

Copied: branches/samba/experimental/source3/printing/nt_printing_os2.h (from rev 3862, tags/samba/upstream_3.6.0~rc3/source3/printing/nt_printing_os2.h)
===================================================================
--- branches/samba/experimental/source3/printing/nt_printing_os2.h	                        (rev 0)
+++ branches/samba/experimental/source3/printing/nt_printing_os2.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -0,0 +1,22 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Andrew Tridgell              1992-2000,
+ *  Copyright (C) Jean François Micouleau      1998-2000.
+ *  Copyright (C) Gerald Carter                2002-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/>.
+ */
+
+WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername);

Modified: branches/samba/experimental/source3/printing/pcap.h
===================================================================
--- branches/samba/experimental/source3/printing/pcap.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/printing/pcap.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -2,6 +2,16 @@
    Unix SMB/CIFS implementation.
    printcap headers
 
+   Copyright (C) Karl Auer 1993-1998
+
+   Re-working by Martin Kiff, 1994
+
+   Re-written again by Andrew Tridgell
+
+   Modified for SVID support by Norm Jacobs, 1997
+
+   Modified for CUPS support by Michael Sweet, 1999
+
    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
@@ -16,6 +26,9 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#ifndef _PRINTING_PCAP_H_
+#define _PRINTING_PCAP_H_
+
 struct pcap_cache;
 
 /* The following definitions come from printing/pcap.c  */
@@ -55,3 +68,5 @@
 
 /* The following definitions come from printing/print_standard.c  */
 bool std_pcap_cache_reload(const char *pcap_name);
+
+#endif /* _PRINTING_PCAP_H_ */

Modified: branches/samba/experimental/source3/printing/spoolssd.c
===================================================================
--- branches/samba/experimental/source3/printing/spoolssd.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/printing/spoolssd.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -22,7 +22,7 @@
 
 #include "messages.h"
 #include "include/printing.h"
-#include "printing/nt_printing_migrate.h"
+#include "printing/nt_printing_migrate_internal.h"
 #include "ntdomain.h"
 #include "librpc/gen_ndr/srv_winreg.h"
 #include "librpc/gen_ndr/srv_spoolss.h"

Modified: branches/samba/experimental/source3/registry/reg_parse_internal.c
===================================================================
--- branches/samba/experimental/source3/registry/reg_parse_internal.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/registry/reg_parse_internal.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,5 +1,10 @@
-/* * Samba Unix/Linux SMB client library
+/*
+ * Unix SMB/CIFS implementation.
  *
+ * Registry helper routines
+ *
+ * Copyright (C) Gregor Beck 2010
+ *
  * 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

Modified: branches/samba/experimental/source3/registry/reg_parse_internal.h
===================================================================
--- branches/samba/experimental/source3/registry/reg_parse_internal.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/registry/reg_parse_internal.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,5 +1,10 @@
-/* Samba Unix/Linux SMB client library
+/*
+ * Unix SMB/CIFS implementation.
  *
+ * Registry helper routines
+ *
+ * Copyright (C) Gregor Beck 2010
+ *
  * 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

Modified: branches/samba/experimental/source3/rpc_client/cli_netlogon.h
===================================================================
--- branches/samba/experimental/source3/rpc_client/cli_netlogon.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_client/cli_netlogon.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,28 @@
+/*
+   Unix SMB/CIFS implementation.
+   NT Domain Authentication SMB / MSRPC client
+   Copyright (C) Andrew Tridgell 1992-2000
+   Copyright (C) Jeremy Allison                    1998.
+   Largely re-written by Jeremy Allison (C)	   2005.
+   Copyright (C) Guenther Deschner                 2008.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 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/>.
+*/
+
+#ifndef _RPC_CLIENT_CLI_NETLOGON_H_
+#define _RPC_CLIENT_CLI_NETLOGON_H_
+
 /* The following definitions come from rpc_client/cli_netlogon.c  */
 
 NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli,
@@ -49,3 +74,4 @@
 					    const unsigned char new_trust_passwd_hash[16],
 					    enum netr_SchannelType sec_channel_type);
 
+#endif /* _RPC_CLIENT_CLI_NETLOGON_H_ */

Modified: branches/samba/experimental/source3/rpc_client/cli_spoolss.h
===================================================================
--- branches/samba/experimental/source3/rpc_client/cli_spoolss.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_client/cli_spoolss.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,30 @@
+/*
+   Unix SMB/CIFS implementation.
+   RPC pipe client
+
+   Copyright (C) Gerald Carter                2001-2005,
+   Copyright (C) Tim Potter                   2000-2002,
+   Copyright (C) Andrew Tridgell              1994-2000,
+   Copyright (C) Jean-Francois Micouleau      1999-2000.
+   Copyright (C) Jeremy Allison                         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/>.
+*/
+
+#ifndef _RPC_CLIENT_CLI_SPOOLSS_H_
+#define _RPC_CLIENT_CLI_SPOOLSS_H_
+
 /* The following definitions come from rpc_client/cli_spoolss.c  */
 
 WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli,
@@ -122,3 +149,5 @@
 					uint32_t offered,
 					uint32_t *count,
 					struct spoolss_PrinterEnumValues **info);
+
+#endif /* _RPC_CLIENT_CLI_SPOOLSS_H_ */

Modified: branches/samba/experimental/source3/rpc_client/cli_winreg.c
===================================================================
--- branches/samba/experimental/source3/rpc_client/cli_winreg.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_client/cli_winreg.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -33,7 +33,7 @@
 				   WERROR *pwerr)
 {
 	struct winreg_String wvalue;
-	enum winreg_Type type;
+	enum winreg_Type type = REG_NONE;
 	uint32_t value_len = 0;
 	uint32_t data_size = 0;
 	WERROR result = WERR_OK;
@@ -69,7 +69,7 @@
 		return status;
 	}
 
-	blob = data_blob_talloc(mem_ctx, NULL, data_size);
+	blob = data_blob_talloc_zero(mem_ctx, data_size);
 	if (blob.data == NULL) {
 		*pwerr = WERR_NOMEM;
 		return status;
@@ -108,13 +108,14 @@
 				    WERROR *pwerr)
 {
 	struct winreg_String wvalue;
-	enum winreg_Type type;
+	enum winreg_Type type = REG_NONE;
 	WERROR result = WERR_OK;
 	uint32_t value_len = 0;
 	uint32_t data_size = 0;
 	NTSTATUS status;
 	DATA_BLOB blob;
 
+	ZERO_STRUCT(wvalue);
 	wvalue.name = value;
 
 	status = dcerpc_winreg_QueryValue(h,
@@ -139,7 +140,7 @@
 		return status;
 	}
 
-	blob = data_blob_talloc(mem_ctx, NULL, data_size);
+	blob = data_blob_talloc_zero(mem_ctx, data_size);
 	if (blob.data == NULL) {
 		*pwerr = WERR_NOMEM;
 		return status;
@@ -179,7 +180,7 @@
 				      WERROR *pwerr)
 {
 	struct winreg_String wvalue;
-	enum winreg_Type type;
+	enum winreg_Type type = REG_NONE;
 	WERROR result = WERR_OK;
 	uint32_t value_len = 0;
 	uint32_t data_size = 0;
@@ -210,7 +211,7 @@
 		return status;
 	}
 
-	blob = data_blob_talloc(mem_ctx, NULL, data_size);
+	blob = data_blob_talloc_zero(mem_ctx, data_size);
 	if (blob.data == NULL) {
 		*pwerr = WERR_NOMEM;
 		return status;
@@ -254,7 +255,7 @@
 				      WERROR *pwerr)
 {
 	struct winreg_String wvalue;
-	enum winreg_Type type;
+	enum winreg_Type type = REG_NONE;
 	WERROR result = WERR_OK;
 	uint32_t value_len = 0;
 	uint32_t data_size = 0;
@@ -285,7 +286,7 @@
 		return status;
 	}
 
-	blob = data_blob_talloc(mem_ctx, NULL, data_size);
+	blob = data_blob_talloc_zero(mem_ctx, data_size);
 	if (blob.data == NULL) {
 		*pwerr = WERR_NOMEM;
 		return status;
@@ -380,13 +381,14 @@
 				 uint32_t data,
 				 WERROR *pwerr)
 {
-	struct winreg_String wvalue = { 0, };
+	struct winreg_String wvalue;
 	DATA_BLOB blob;
 	WERROR result = WERR_OK;
 	NTSTATUS status;
 
+	ZERO_STRUCT(wvalue);
 	wvalue.name = value;
-	blob = data_blob_talloc(mem_ctx, NULL, 4);
+	blob = data_blob_talloc_zero(mem_ctx, 4);
 	SIVAL(blob.data, 0, data);
 
 	status = dcerpc_winreg_SetValue(h,

Copied: branches/samba/experimental/source3/rpc_client/cli_winreg_spoolss.c (from rev 3862, tags/samba/upstream_3.6.0~rc3/source3/rpc_client/cli_winreg_spoolss.c)
===================================================================
--- branches/samba/experimental/source3/rpc_client/cli_winreg_spoolss.c	                        (rev 0)
+++ branches/samba/experimental/source3/rpc_client/cli_winreg_spoolss.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -0,0 +1,4093 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *
+ *  SPOOLSS RPC Pipe server / winreg client routines
+ *
+ *  Copyright (c) 2010      Andreas Schneider <asn at 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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "nt_printing.h"
+#include "../librpc/gen_ndr/ndr_spoolss.h"
+#include "../librpc/gen_ndr/ndr_winreg_c.h"
+#include "../librpc/gen_ndr/ndr_security.h"
+#include "secrets.h"
+#include "../libcli/security/security.h"
+#include "rpc_client/cli_winreg.h"
+#include "../libcli/registry/util_reg.h"
+#include "rpc_client/cli_winreg_spoolss.h"
+#include "printing/nt_printing_os2.h"
+#include "rpc_client/init_spoolss.h"
+
+#define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
+#define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
+#define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
+#define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
+
+#define EMPTY_STRING ""
+
+#define FILL_STRING(mem_ctx, in, out) \
+	do { \
+		if (in && strlen(in)) { \
+			out = talloc_strdup(mem_ctx, in); \
+		} else { \
+			out = talloc_strdup(mem_ctx, ""); \
+		} \
+		W_ERROR_HAVE_NO_MEMORY(out); \
+	} while (0);
+
+#define CHECK_ERROR(result) \
+	if (W_ERROR_IS_OK(result)) continue; \
+	if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \
+	if (!W_ERROR_IS_OK(result)) break
+
+/*        FLAGS,                NAME,                              with,   height,   left, top, right, bottom */
+static const struct spoolss_FormInfo1 builtin_forms1[] = {
+	{ SPOOLSS_FORM_BUILTIN, "10x11",                          {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
+	{ SPOOLSS_FORM_BUILTIN, "10x14",                          {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
+	{ SPOOLSS_FORM_BUILTIN, "11x17",                          {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
+	{ SPOOLSS_FORM_BUILTIN, "12x11",                          {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
+	{ SPOOLSS_FORM_BUILTIN, "15x11",                          {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
+	{ SPOOLSS_FORM_BUILTIN, "6 3/4 Envelope",                 {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
+	{ SPOOLSS_FORM_BUILTIN, "9x11",                           {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
+	{ SPOOLSS_FORM_BUILTIN, "A0",                             {0xcd528,0x122488},{0x0,0x0,0xcd528,0x122488} },
+	{ SPOOLSS_FORM_BUILTIN, "A1",                             {0x91050,0xcd528}, {0x0,0x0,0x91050,0xcd528} },
+	{ SPOOLSS_FORM_BUILTIN, "A2",                             {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
+	{ SPOOLSS_FORM_BUILTIN, "A3 Extra Transverse",            {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
+	{ SPOOLSS_FORM_BUILTIN, "A3 Extra",                       {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
+	{ SPOOLSS_FORM_BUILTIN, "A3 Rotated",                     {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
+	{ SPOOLSS_FORM_BUILTIN, "A3 Transverse",                  {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
+	{ SPOOLSS_FORM_BUILTIN, "A3",                             {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
+	{ SPOOLSS_FORM_BUILTIN, "A4 Extra",                       {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
+	{ SPOOLSS_FORM_BUILTIN, "A4 Plus",                        {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
+	{ SPOOLSS_FORM_BUILTIN, "A4 Rotated",                     {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
+	{ SPOOLSS_FORM_BUILTIN, "A4 Small",                       {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+	{ SPOOLSS_FORM_BUILTIN, "A4 Transverse",                  {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+	{ SPOOLSS_FORM_BUILTIN, "A4",                             {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+	{ SPOOLSS_FORM_BUILTIN, "A5 Extra",                       {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
+	{ SPOOLSS_FORM_BUILTIN, "A5 Rotated",                     {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
+	{ SPOOLSS_FORM_BUILTIN, "A5 Transverse",                  {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
+	{ SPOOLSS_FORM_BUILTIN, "A5",                             {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
+	{ SPOOLSS_FORM_BUILTIN, "A6 Rotated",                     {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
+	{ SPOOLSS_FORM_BUILTIN, "A6",                             {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
+	{ SPOOLSS_FORM_BUILTIN, "B4 (ISO)",                       {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
+	{ SPOOLSS_FORM_BUILTIN, "B4 (JIS) Rotated",               {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
+	{ SPOOLSS_FORM_BUILTIN, "B4 (JIS)",                       {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} },
+	{ SPOOLSS_FORM_BUILTIN, "B5 (ISO) Extra",                 {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
+	{ SPOOLSS_FORM_BUILTIN, "B5 (JIS) Rotated",               {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
+	{ SPOOLSS_FORM_BUILTIN, "B5 (JIS) Transverse",            {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
+	{ SPOOLSS_FORM_BUILTIN, "B5 (JIS)",                       {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
+	{ SPOOLSS_FORM_BUILTIN, "B6 (JIS) Rotated",               {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
+	{ SPOOLSS_FORM_BUILTIN, "B6 (JIS)",                       {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
+	{ SPOOLSS_FORM_BUILTIN, "C size sheet",                   {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
+	{ SPOOLSS_FORM_BUILTIN, "D size sheet",                   {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
+	{ SPOOLSS_FORM_BUILTIN, "Double Japan Postcard Rotated",  {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
+	{ SPOOLSS_FORM_BUILTIN, "E size sheet",                   {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope #10",                   {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope #11",                   {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope #12",                   {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope #14",                   {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope #9",                    {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope B4",                    {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope B5",                    {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope B6",                    {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope C3",                    {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope C4",                    {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope C5",                    {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope C6",                    {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope C65",                   {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope DL",                    {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope Invite",                {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope Monarch",               {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} },
+	{ SPOOLSS_FORM_BUILTIN, "Envelope",                       {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
+	{ SPOOLSS_FORM_BUILTIN, "Executive",                      {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
+	{ SPOOLSS_FORM_BUILTIN, "Folio",                          {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
+	{ SPOOLSS_FORM_BUILTIN, "German Legal Fanfold",           {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
+	{ SPOOLSS_FORM_BUILTIN, "German Std Fanfold",             {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
+	{ SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
+	{ SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
+	{ SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
+	{ SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
+	{ SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4 Rotated",  {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
+	{ SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4",          {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
+	{ SPOOLSS_FORM_BUILTIN, "Japanese Double Postcard",       {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
+	{ SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #3",      {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
+	{ SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #4",      {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
+	{ SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #2",      {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
+	{ SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #3",      {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
+	{ SPOOLSS_FORM_BUILTIN, "Japanese Postcard Rotated",      {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
+	{ SPOOLSS_FORM_BUILTIN, "Japanese Postcard",              {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} },
+	{ SPOOLSS_FORM_BUILTIN, "Ledger",                         {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
+	{ SPOOLSS_FORM_BUILTIN, "Legal Extra",                    {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} },
+	{ SPOOLSS_FORM_BUILTIN, "Legal",                          {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
+	{ SPOOLSS_FORM_BUILTIN, "Letter Extra Transverse",        {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
+	{ SPOOLSS_FORM_BUILTIN, "Letter Extra",                   {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
+	{ SPOOLSS_FORM_BUILTIN, "Letter Plus",                    {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} },
+	{ SPOOLSS_FORM_BUILTIN, "Letter Rotated",                 {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} },
+	{ SPOOLSS_FORM_BUILTIN, "Letter Small",                   {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
+	{ SPOOLSS_FORM_BUILTIN, "Letter Transverse",              {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
+	{ SPOOLSS_FORM_BUILTIN, "Letter",                         {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
+	{ SPOOLSS_FORM_BUILTIN, "Note",                           {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC 16K Rotated",                {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC 16K",                        {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC 32K Rotated",                {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC 32K",                        {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC 32K(Big) Rotated",           {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC 32K(Big)",                   {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #1 Rotated",        {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #1",                {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #10 Rotated",       {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #10",               {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #2 Rotated",        {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #2",                {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #3 Rotated",        {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #3",                {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #4 Rotated",        {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #4",                {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #5 Rotated",        {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #5",                {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #6 Rotated",        {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #6",                {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #7 Rotated",        {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #7",                {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #8 Rotated",        {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #8",                {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #9 Rotated",        {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} },
+	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #9",                {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
+	{ SPOOLSS_FORM_BUILTIN, "Quarto",                         {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
+	{ SPOOLSS_FORM_BUILTIN, "Reserved48",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
+	{ SPOOLSS_FORM_BUILTIN, "Reserved49",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
+	{ SPOOLSS_FORM_BUILTIN, "Statement",                      {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
+	{ SPOOLSS_FORM_BUILTIN, "Super A",                        {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
+	{ SPOOLSS_FORM_BUILTIN, "Super B",                        {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
+	{ SPOOLSS_FORM_BUILTIN, "Tabloid Extra",                  {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
+	{ SPOOLSS_FORM_BUILTIN, "Tabloid",                        {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
+	{ SPOOLSS_FORM_BUILTIN, "US Std Fanfold",                 {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} }
+};
+
+/********************************************************************
+ static helper functions
+********************************************************************/
+
+/****************************************************************************
+ Update the changeid time.
+****************************************************************************/
+/**
+ * @internal
+ *
+ * @brief Update the ChangeID time of a printer.
+ *
+ * This is SO NASTY as some drivers need this to change, others need it
+ * static. This value will change every second, and I must hope that this
+ * is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
+ * UTAH ! JRA.
+ *
+ * @return              The ChangeID.
+ */
+static uint32_t winreg_printer_rev_changeid(void)
+{
+	struct timeval tv;
+
+	get_process_uptime(&tv);
+
+#if 1	/* JERRY */
+	/* Return changeid as msec since spooler restart */
+	return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+#else
+	/*
+	 * This setting seems to work well but is too untested
+	 * to replace the above calculation.  Left in for experimentation
+	 * of the reader            --jerry (Tue Mar 12 09:15:05 CST 2002)
+	 */
+	return tv.tv_sec * 10 + tv.tv_usec / 100000;
+#endif
+}
+
+static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx,
+			      struct dcerpc_binding_handle *binding_handle,
+			      const char *path,
+			      const char *key,
+			      bool create_key,
+			      uint32_t access_mask,
+			      struct policy_handle *hive_handle,
+			      struct policy_handle *key_handle)
+{
+	struct winreg_String wkey, wkeyclass;
+	char *keyname;
+	NTSTATUS status;
+	WERROR result = WERR_OK;
+
+	status = dcerpc_winreg_OpenHKLM(binding_handle,
+					mem_ctx,
+					NULL,
+					access_mask,
+					hive_handle,
+					&result);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
+			  nt_errstr(status)));
+		return ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
+			  win_errstr(result)));
+		return result;
+	}
+
+	if (key && *key) {
+		keyname = talloc_asprintf(mem_ctx, "%s\\%s", path, key);
+	} else {
+		keyname = talloc_strdup(mem_ctx, path);
+	}
+	if (keyname == NULL) {
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(wkey);
+	wkey.name = keyname;
+
+	if (create_key) {
+		enum winreg_CreateAction action = REG_ACTION_NONE;
+
+		ZERO_STRUCT(wkeyclass);
+		wkeyclass.name = "";
+
+		status = dcerpc_winreg_CreateKey(binding_handle,
+						 mem_ctx,
+						 hive_handle,
+						 wkey,
+						 wkeyclass,
+						 0,
+						 access_mask,
+						 NULL,
+						 key_handle,
+						 &action,
+						 &result);
+		switch (action) {
+			case REG_ACTION_NONE:
+				DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n"));
+				break;
+			case REG_CREATED_NEW_KEY:
+				DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname));
+				break;
+			case REG_OPENED_EXISTING_KEY:
+				DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname));
+				break;
+		}
+	} else {
+		status = dcerpc_winreg_OpenKey(binding_handle,
+					       mem_ctx,
+					       hive_handle,
+					       wkey,
+					       0,
+					       access_mask,
+					       key_handle,
+					       &result);
+	}
+	if (!NT_STATUS_IS_OK(status)) {
+		return ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		return result;
+	}
+
+	return WERR_OK;
+}
+
+/**
+ * @brief Create the registry keyname for the given printer.
+ *
+ * @param[in]  mem_ctx  The memory context to use.
+ *
+ * @param[in]  printer  The name of the printer to get the registry key.
+ *
+ * @return     The registry key or NULL on error.
+ */
+static char *winreg_printer_data_keyname(TALLOC_CTX *mem_ctx, const char *printer) {
+	return talloc_asprintf(mem_ctx, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY, printer);
+}
+
+/**
+ * @internal
+ *
+ * @brief Enumerate values of an opened key handle and retrieve the data.
+ *
+ * @param[in]  mem_ctx  The memory context to use.
+ *
+ * @param[in]  winreg_handle The binding handle for the rpc connection.
+ *
+ * @param[in]  key_hnd  The opened key handle.
+ *
+ * @param[out] pnum_values A pointer to store he number of values found.
+ *
+ * @param[out] pnum_values A pointer to store the number of values we found.
+ *
+ * @return                   WERR_OK on success, the corresponding DOS error
+ *                           code if something gone wrong.
+ */
+static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
+					struct dcerpc_binding_handle *winreg_handle,
+					struct policy_handle *key_hnd,
+					uint32_t *pnum_values,
+					struct spoolss_PrinterEnumValues **penum_values)
+{
+	TALLOC_CTX *tmp_ctx;
+	uint32_t num_subkeys, max_subkeylen, max_classlen;
+	uint32_t num_values, max_valnamelen, max_valbufsize;
+	uint32_t secdescsize;
+	uint32_t i;
+	NTTIME last_changed_time;
+	struct winreg_String classname;
+
+	struct spoolss_PrinterEnumValues *enum_values;
+
+	WERROR result = WERR_OK;
+	NTSTATUS status;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(classname);
+
+	status = dcerpc_winreg_QueryInfoKey(winreg_handle,
+					    tmp_ctx,
+					    key_hnd,
+					    &classname,
+					    &num_subkeys,
+					    &max_subkeylen,
+					    &max_classlen,
+					    &num_values,
+					    &max_valnamelen,
+					    &max_valbufsize,
+					    &secdescsize,
+					    &last_changed_time,
+					    &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
+			  nt_errstr(status)));
+		result = ntstatus_to_werror(status);
+		goto error;
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
+			  win_errstr(result)));
+		goto error;
+	}
+
+	if (num_values == 0) {
+		*pnum_values = 0;
+		TALLOC_FREE(tmp_ctx);
+		return WERR_OK;
+	}
+
+	enum_values = talloc_array(tmp_ctx, struct spoolss_PrinterEnumValues, num_values);
+	if (enum_values == NULL) {
+		result = WERR_NOMEM;
+		goto error;
+	}
+
+	for (i = 0; i < num_values; i++) {
+		struct spoolss_PrinterEnumValues val;
+		struct winreg_ValNameBuf name_buf;
+		enum winreg_Type type = REG_NONE;
+		uint8_t *data;
+		uint32_t data_size;
+		uint32_t length;
+		char n = '\0';
+
+		name_buf.name = &n;
+		name_buf.size = max_valnamelen + 2;
+		name_buf.length = 0;
+
+		data_size = max_valbufsize;
+		data = NULL;
+		if (data_size) {
+			data = (uint8_t *) talloc_zero_size(tmp_ctx, data_size);
+		}
+		length = 0;
+
+		status = dcerpc_winreg_EnumValue(winreg_handle,
+						 tmp_ctx,
+						 key_hnd,
+						 i,
+						 &name_buf,
+						 &type,
+						 data,
+						 data_size ? &data_size : NULL,
+						 &length,
+						 &result);
+		if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
+			result = WERR_OK;
+			status = NT_STATUS_OK;
+			break;
+		}
+
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
+				  nt_errstr(status)));
+			result = ntstatus_to_werror(status);
+			goto error;
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
+				  win_errstr(result)));
+			goto error;
+		}
+
+		if (name_buf.name == NULL) {
+			result = WERR_INVALID_PARAMETER;
+			goto error;
+		}
+
+		val.value_name = talloc_strdup(enum_values, name_buf.name);
+		if (val.value_name == NULL) {
+			result = WERR_NOMEM;
+			goto error;
+		}
+		val.value_name_len = strlen_m_term(val.value_name) * 2;
+
+		val.type = type;
+		val.data_length = length;
+		val.data = NULL;
+		if (val.data_length) {
+			val.data = talloc(enum_values, DATA_BLOB);
+			if (val.data == NULL) {
+				result = WERR_NOMEM;
+				goto error;
+			}
+			*val.data = data_blob_talloc(val.data, data, val.data_length);
+		}
+
+		enum_values[i] = val;
+	}
+
+	*pnum_values = num_values;
+	if (penum_values) {
+		*penum_values = talloc_move(mem_ctx, &enum_values);
+	}
+
+	result = WERR_OK;
+
+ error:
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+/**
+ * @internal
+ *
+ * @brief A function to delete a key and its subkeys recurively.
+ *
+ * @param[in]  mem_ctx  The memory context to use.
+ *
+ * @param[in]  winreg_handle The binding handle for the rpc connection.
+ *
+ * @param[in]  hive_handle A opened hive handle to the key.
+ *
+ * @param[in]  access_mask The access mask to access the key.
+ *
+ * @param[in]  key      The key to delete
+ *
+ * @return              WERR_OK on success, the corresponding DOS error
+ *                      code if something gone wrong.
+ */
+static WERROR winreg_printer_delete_subkeys(TALLOC_CTX *mem_ctx,
+					    struct dcerpc_binding_handle *winreg_handle,
+					    struct policy_handle *hive_handle,
+					    uint32_t access_mask,
+					    const char *key)
+{
+	const char **subkeys = NULL;
+	uint32_t num_subkeys = 0;
+	struct policy_handle key_hnd;
+	struct winreg_String wkey = { 0, };
+	WERROR result = WERR_OK;
+	NTSTATUS status;
+	uint32_t i;
+
+	ZERO_STRUCT(key_hnd);
+	wkey.name = key;
+
+	DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key));
+	/* open the key */
+	status = dcerpc_winreg_OpenKey(winreg_handle,
+				       mem_ctx,
+				       hive_handle,
+				       wkey,
+				       0,
+				       access_mask,
+				       &key_hnd,
+				       &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
+			  wkey.name, nt_errstr(status)));
+		return ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
+			  wkey.name, win_errstr(result)));
+		return result;
+	}
+
+	status = dcerpc_winreg_enum_keys(mem_ctx,
+					 winreg_handle,
+					 &key_hnd,
+					 &num_subkeys,
+					 &subkeys,
+					 &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	for (i = 0; i < num_subkeys; i++) {
+		/* create key + subkey */
+		char *subkey = talloc_asprintf(mem_ctx, "%s\\%s", key, subkeys[i]);
+		if (subkey == NULL) {
+			goto done;
+		}
+
+		DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey));
+		result = winreg_printer_delete_subkeys(mem_ctx,
+						       winreg_handle,
+						       hive_handle,
+						       access_mask,
+						       subkey);
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (is_valid_policy_hnd(&key_hnd)) {
+		WERROR ignore;
+		dcerpc_winreg_CloseKey(winreg_handle, mem_ctx, &key_hnd, &ignore);
+	}
+
+	wkey.name = key;
+
+	status = dcerpc_winreg_DeleteKey(winreg_handle,
+					 mem_ctx,
+					 hive_handle,
+					 wkey,
+					 &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+
+done:
+	if (is_valid_policy_hnd(&key_hnd)) {
+		WERROR ignore;
+
+		dcerpc_winreg_CloseKey(winreg_handle, mem_ctx, &key_hnd, &ignore);
+	}
+
+	return result;
+}
+
+static WERROR winreg_printer_opendriver(TALLOC_CTX *mem_ctx,
+					struct dcerpc_binding_handle *winreg_handle,
+					const char *drivername,
+					const char *architecture,
+					uint32_t version,
+					uint32_t access_mask,
+					bool create,
+					struct policy_handle *hive_hnd,
+					struct policy_handle *key_hnd)
+{
+	WERROR result;
+	char *key_name;
+
+	key_name = talloc_asprintf(mem_ctx, "%s\\Environments\\%s\\Drivers\\Version-%u",
+				   TOP_LEVEL_CONTROL_KEY,
+				   architecture, version);
+	if (!key_name) {
+		return WERR_NOMEM;
+	}
+
+	result = winreg_printer_openkey(mem_ctx,
+					winreg_handle,
+					key_name,
+					drivername,
+					create,
+					access_mask,
+					hive_hnd,
+					key_hnd);
+	return result;
+}
+
+static WERROR winreg_enumval_to_dword(TALLOC_CTX *mem_ctx,
+				      struct spoolss_PrinterEnumValues *v,
+				      const char *valuename, uint32_t *dw)
+{
+	/* just return if it is not the one we are looking for */
+	if (strcmp(valuename, v->value_name) != 0) {
+		return WERR_NOT_FOUND;
+	}
+
+	if (v->type != REG_DWORD) {
+		return WERR_INVALID_DATATYPE;
+	}
+
+	if (v->data_length != 4) {
+		*dw = 0;
+		return WERR_OK;
+	}
+
+	*dw = IVAL(v->data->data, 0);
+	return WERR_OK;
+}
+
+static WERROR winreg_enumval_to_sz(TALLOC_CTX *mem_ctx,
+				   struct spoolss_PrinterEnumValues *v,
+				   const char *valuename, const char **_str)
+{
+	/* just return if it is not the one we are looking for */
+	if (strcmp(valuename, v->value_name) != 0) {
+		return WERR_NOT_FOUND;
+	}
+
+	if (v->type != REG_SZ) {
+		return WERR_INVALID_DATATYPE;
+	}
+
+	if (v->data_length == 0) {
+		*_str = talloc_strdup(mem_ctx, EMPTY_STRING);
+		if (*_str == NULL) {
+			return WERR_NOMEM;
+		}
+		return WERR_OK;
+	}
+
+	if (!pull_reg_sz(mem_ctx, v->data, _str)) {
+		return WERR_NOMEM;
+	}
+
+	return WERR_OK;
+}
+
+static WERROR winreg_enumval_to_multi_sz(TALLOC_CTX *mem_ctx,
+					 struct spoolss_PrinterEnumValues *v,
+					 const char *valuename,
+					 const char ***array)
+{
+	/* just return if it is not the one we are looking for */
+	if (strcmp(valuename, v->value_name) != 0) {
+		return WERR_NOT_FOUND;
+	}
+
+	if (v->type != REG_MULTI_SZ) {
+		return WERR_INVALID_DATATYPE;
+	}
+
+	if (v->data_length == 0) {
+		*array = talloc_array(mem_ctx, const char *, 1);
+		if (*array == NULL) {
+			return WERR_NOMEM;
+		}
+		*array[0] = NULL;
+		return WERR_OK;
+	}
+
+	if (!pull_reg_multi_sz(mem_ctx, v->data, array)) {
+		return WERR_NOMEM;
+	}
+
+	return WERR_OK;
+}
+
+static WERROR winreg_printer_write_date(TALLOC_CTX *mem_ctx,
+					struct dcerpc_binding_handle *winreg_handle,
+					struct policy_handle *key_handle,
+					const char *value,
+					NTTIME data)
+{
+	struct winreg_String wvalue = { 0, };
+	DATA_BLOB blob;
+	WERROR result = WERR_OK;
+	NTSTATUS status;
+	const char *str;
+	struct tm *tm;
+	time_t t;
+
+	if (data == 0) {
+		str = talloc_strdup(mem_ctx, "01/01/1601");
+	} else {
+		t = nt_time_to_unix(data);
+		tm = localtime(&t);
+		if (tm == NULL) {
+			return map_werror_from_unix(errno);
+		}
+		str = talloc_asprintf(mem_ctx, "%02d/%02d/%04d",
+				      tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
+	}
+	if (!str) {
+		return WERR_NOMEM;
+	}
+
+	wvalue.name = value;
+	if (!push_reg_sz(mem_ctx, &blob, str)) {
+		return WERR_NOMEM;
+	}
+	status = dcerpc_winreg_SetValue(winreg_handle,
+					mem_ctx,
+					key_handle,
+					wvalue,
+					REG_SZ,
+					blob.data,
+					blob.length,
+					&result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
+			wvalue.name, win_errstr(result)));
+	}
+
+	return result;
+}
+
+static WERROR winreg_printer_date_to_NTTIME(const char *str, NTTIME *data)
+{
+	struct tm tm;
+	time_t t;
+
+	if (strequal(str, "01/01/1601")) {
+		*data = 0;
+		return WERR_OK;
+	}
+
+	ZERO_STRUCT(tm);
+
+	if (sscanf(str, "%d/%d/%d",
+		   &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3) {
+		return WERR_INVALID_PARAMETER;
+	}
+	tm.tm_mon -= 1;
+	tm.tm_year -= 1900;
+	tm.tm_isdst = -1;
+
+	t = mktime(&tm);
+	unix_to_nt_time(data, t);
+
+	return WERR_OK;
+}
+
+static WERROR winreg_printer_write_ver(TALLOC_CTX *mem_ctx,
+				       struct dcerpc_binding_handle *winreg_handle,
+				       struct policy_handle *key_handle,
+				       const char *value,
+				       uint64_t data)
+{
+	struct winreg_String wvalue = { 0, };
+	DATA_BLOB blob;
+	WERROR result = WERR_OK;
+	NTSTATUS status;
+	char *str;
+
+	/* FIXME: check format is right,
+	 *	this needs to be something like: 6.1.7600.16385 */
+	str = talloc_asprintf(mem_ctx, "%u.%u.%u.%u",
+			      (unsigned)((data >> 48) & 0xFFFF),
+			      (unsigned)((data >> 32) & 0xFFFF),
+			      (unsigned)((data >> 16) & 0xFFFF),
+			      (unsigned)(data & 0xFFFF));
+	if (!str) {
+		return WERR_NOMEM;
+	}
+
+	wvalue.name = value;
+	if (!push_reg_sz(mem_ctx, &blob, str)) {
+		return WERR_NOMEM;
+	}
+	status = dcerpc_winreg_SetValue(winreg_handle,
+					mem_ctx,
+					key_handle,
+					wvalue,
+					REG_SZ,
+					blob.data,
+					blob.length,
+					&result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
+			wvalue.name, win_errstr(result)));
+	}
+
+	return result;
+}
+
+static WERROR winreg_printer_ver_to_dword(const char *str, uint64_t *data)
+{
+	unsigned int v1, v2, v3, v4;
+
+	if (sscanf(str, "%u.%u.%u.%u", &v1, &v2, &v3, &v4) != 4) {
+		return WERR_INVALID_PARAMETER;
+	}
+
+	*data = ((uint64_t)(v1 & 0xFFFF) << 48) +
+		((uint64_t)(v2 & 0xFFFF) << 32) +
+		((uint64_t)(v3 & 0xFFFF) << 16) +
+		(uint64_t)(v2 & 0xFFFF);
+
+	return WERR_OK;
+}
+
+/********************************************************************
+ Public winreg function for spoolss
+********************************************************************/
+
+WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
+			     struct dcerpc_binding_handle *winreg_handle,
+			     const char *sharename)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	struct spoolss_SetPrinterInfo2 *info2;
+	struct security_descriptor *secdesc;
+	struct winreg_String wkey, wkeyclass;
+	const char *path;
+	const char *subkeys[] = { SPOOL_DSDRIVER_KEY, SPOOL_DSSPOOLER_KEY, SPOOL_PRINTERDATA_KEY };
+	uint32_t i, count = ARRAY_SIZE(subkeys);
+	uint32_t info2_mask = 0;
+	WERROR result = WERR_OK;
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, sharename);
+	if (path == NULL) {
+		TALLOC_FREE(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					"",
+					false,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (W_ERROR_IS_OK(result)) {
+		DEBUG(2, ("winreg_create_printer: Skipping, %s already exists\n", path));
+		goto done;
+	} else if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+		DEBUG(2, ("winreg_create_printer: Creating default values in %s\n", path));
+	} else if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_create_printer: Could not open key %s: %s\n",
+			path, win_errstr(result)));
+		goto done;
+	}
+
+	/* Create the main key */
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					"",
+					true,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
+			path, win_errstr(result)));
+		goto done;
+	}
+
+	if (is_valid_policy_hnd(&key_hnd)) {
+		dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
+	}
+
+	/* Create subkeys */
+	for (i = 0; i < count; i++) {
+		NTSTATUS status;
+		enum winreg_CreateAction action = REG_ACTION_NONE;
+
+		ZERO_STRUCT(key_hnd);
+		ZERO_STRUCT(wkey);
+
+		wkey.name = talloc_asprintf(tmp_ctx, "%s\\%s", path, subkeys[i]);
+		if (wkey.name == NULL) {
+			result = WERR_NOMEM;
+			goto done;
+		}
+
+		ZERO_STRUCT(wkeyclass);
+		wkeyclass.name = "";
+
+		status = dcerpc_winreg_CreateKey(winreg_handle,
+						 tmp_ctx,
+						 &hive_hnd,
+						 wkey,
+						 wkeyclass,
+						 0,
+						 access_mask,
+						 NULL,
+						 &key_hnd,
+						 &action,
+						 &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
+				wkey.name, win_errstr(result)));
+			goto done;
+		}
+
+		if (strequal(subkeys[i], SPOOL_DSSPOOLER_KEY)) {
+			const char *dnssuffix;
+			const char *longname;
+			const char *uncname;
+
+			status = dcerpc_winreg_set_sz(tmp_ctx,
+						      winreg_handle,
+						      &key_hnd,
+						      SPOOL_REG_PRINTERNAME,
+						      sharename,
+						      &result);
+			if (!NT_STATUS_IS_OK(status)) {
+				result = ntstatus_to_werror(status);
+			}
+			if (!W_ERROR_IS_OK(result)) {
+				goto done;
+			}
+
+			status = dcerpc_winreg_set_sz(tmp_ctx,
+						      winreg_handle,
+						      &key_hnd,
+						      SPOOL_REG_SHORTSERVERNAME,
+						      global_myname(),
+						      &result);
+			if (!NT_STATUS_IS_OK(status)) {
+				result = ntstatus_to_werror(status);
+			}
+			if (!W_ERROR_IS_OK(result)) {
+				goto done;
+			}
+
+			/* We make the assumption that the netbios name
+			 * is the same as the DNS name since the former
+			 * will be what we used to join the domain
+			 */
+			dnssuffix = get_mydnsdomname(tmp_ctx);
+			if (dnssuffix != NULL && dnssuffix[0] != '\0') {
+				longname = talloc_asprintf(tmp_ctx, "%s.%s", global_myname(), dnssuffix);
+			} else {
+				longname = talloc_strdup(tmp_ctx, global_myname());
+			}
+			if (longname == NULL) {
+				result = WERR_NOMEM;
+				goto done;
+			}
+
+			status = dcerpc_winreg_set_sz(tmp_ctx,
+						      winreg_handle,
+						      &key_hnd,
+						      SPOOL_REG_SERVERNAME,
+						      longname,
+						      &result);
+			if (!NT_STATUS_IS_OK(status)) {
+				result = ntstatus_to_werror(status);
+			}
+			if (!W_ERROR_IS_OK(result)) {
+				goto done;
+			}
+
+			uncname = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
+						  longname, sharename);
+			if (uncname == NULL) {
+				result = WERR_NOMEM;
+				goto done;
+			}
+
+			status = dcerpc_winreg_set_sz(tmp_ctx,
+						      winreg_handle,
+						      &key_hnd,
+						      SPOOL_REG_UNCNAME,
+						      uncname,
+						      &result);
+			if (!NT_STATUS_IS_OK(status)) {
+				result = ntstatus_to_werror(status);
+			}
+			if (!W_ERROR_IS_OK(result)) {
+				goto done;
+			}
+
+			status = dcerpc_winreg_set_dword(tmp_ctx,
+							 winreg_handle,
+							 &key_hnd,
+							 SPOOL_REG_VERSIONNUMBER,
+							 4,
+							 &result);
+			if (!NT_STATUS_IS_OK(status)) {
+				result = ntstatus_to_werror(status);
+			}
+			if (!W_ERROR_IS_OK(result)) {
+				goto done;
+			}
+
+			status = dcerpc_winreg_set_dword(tmp_ctx,
+							 winreg_handle,
+							 &key_hnd,
+							 SPOOL_REG_PRINTSTARTTIME,
+							 0,
+							 &result);
+			if (!NT_STATUS_IS_OK(status)) {
+				result = ntstatus_to_werror(status);
+			}
+			if (!W_ERROR_IS_OK(result)) {
+				goto done;
+			}
+
+			status = dcerpc_winreg_set_dword(tmp_ctx,
+							 winreg_handle,
+							 &key_hnd,
+							 SPOOL_REG_PRINTENDTIME,
+							 0,
+							 &result);
+			if (!NT_STATUS_IS_OK(status)) {
+				result = ntstatus_to_werror(status);
+			}
+			if (!W_ERROR_IS_OK(result)) {
+				goto done;
+			}
+
+			status = dcerpc_winreg_set_dword(tmp_ctx,
+							 winreg_handle,
+							 &key_hnd,
+							 SPOOL_REG_PRIORITY,
+							 1,
+							 &result);
+			if (!NT_STATUS_IS_OK(status)) {
+				result = ntstatus_to_werror(status);
+			}
+			if (!W_ERROR_IS_OK(result)) {
+				goto done;
+			}
+
+			status = dcerpc_winreg_set_dword(tmp_ctx,
+							 winreg_handle,
+							 &key_hnd,
+							 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
+							 0,
+							 &result);
+			if (!NT_STATUS_IS_OK(status)) {
+				result = ntstatus_to_werror(status);
+			}
+			if (!W_ERROR_IS_OK(result)) {
+				goto done;
+			}
+		}
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
+		}
+	}
+	info2 = talloc_zero(tmp_ctx, struct spoolss_SetPrinterInfo2);
+	if (info2 == NULL) {
+		result = WERR_NOMEM;
+		goto done;
+	}
+
+	info2->printername = sharename;
+	if (info2->printername == NULL) {
+		result = WERR_NOMEM;
+		goto done;
+	}
+	info2_mask |= SPOOLSS_PRINTER_INFO_PRINTERNAME;
+
+	info2->sharename = sharename;
+	info2_mask |= SPOOLSS_PRINTER_INFO_SHARENAME;
+
+	info2->portname = SAMBA_PRINTER_PORT_NAME;
+	info2_mask |= SPOOLSS_PRINTER_INFO_PORTNAME;
+
+	info2->printprocessor = "winprint";
+	info2_mask |= SPOOLSS_PRINTER_INFO_PRINTPROCESSOR;
+
+	info2->datatype = "RAW";
+	info2_mask |= SPOOLSS_PRINTER_INFO_DATATYPE;
+
+	info2->comment = "";
+	info2_mask |= SPOOLSS_PRINTER_INFO_COMMENT;
+
+	info2->attributes = PRINTER_ATTRIBUTE_SAMBA;
+	info2_mask |= SPOOLSS_PRINTER_INFO_ATTRIBUTES;
+
+	info2->starttime = 0; /* Minutes since 12:00am GMT */
+	info2_mask |= SPOOLSS_PRINTER_INFO_STARTTIME;
+
+	info2->untiltime = 0; /* Minutes since 12:00am GMT */
+	info2_mask |= SPOOLSS_PRINTER_INFO_UNTILTIME;
+
+	info2->priority = 1;
+	info2_mask |= SPOOLSS_PRINTER_INFO_PRIORITY;
+
+	info2->defaultpriority = 1;
+	info2_mask |= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY;
+
+	result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+	info2_mask |= SPOOLSS_PRINTER_INFO_SECDESC;
+
+	/*
+	 * Don't write a default Device Mode to the registry! The Device Mode is
+	 * only written to disk with a SetPrinter level 2 or 8.
+	 */
+
+	result = winreg_update_printer(tmp_ctx,
+				       winreg_handle,
+				       sharename,
+				       info2_mask,
+				       info2,
+				       NULL,
+				       secdesc);
+
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	talloc_free(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
+			     struct dcerpc_binding_handle *winreg_handle,
+			     const char *sharename,
+			     uint32_t info2_mask,
+			     struct spoolss_SetPrinterInfo2 *info2,
+			     struct spoolss_DeviceMode *devmode,
+			     struct security_descriptor *secdesc)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	int snum = lp_servicenumber(sharename);
+	enum ndr_err_code ndr_err;
+	DATA_BLOB blob;
+	char *path;
+	WERROR result = WERR_OK;
+	NTSTATUS status;
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, sharename);
+	if (path == NULL) {
+		TALLOC_FREE(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					"",
+					true,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n",
+			path, win_errstr(result)));
+		goto done;
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_ATTRIBUTES) {
+		status = dcerpc_winreg_set_dword(tmp_ctx,
+						 winreg_handle,
+						 &key_hnd,
+						 "Attributes",
+						 info2->attributes,
+						 &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+#if 0
+	if (info2_mask & SPOOLSS_PRINTER_INFO_AVERAGEPPM) {
+		status = dcerpc_winreg_set_dword(tmp_ctx,
+						 winreg_handle,
+						 &key_hnd,
+						 "AveragePpm",
+						 info2->attributes,
+						 &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+#endif
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_COMMENT) {
+		status = dcerpc_winreg_set_sz(tmp_ctx,
+					      winreg_handle,
+					      &key_hnd,
+					      "Description",
+					      info2->comment,
+					      &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_DATATYPE) {
+		status = dcerpc_winreg_set_sz(tmp_ctx,
+					      winreg_handle,
+					      &key_hnd,
+					      "Datatype",
+					      info2->datatype,
+					      &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY) {
+		status = dcerpc_winreg_set_dword(tmp_ctx,
+						 winreg_handle,
+						 &key_hnd,
+						 "Default Priority",
+						 info2->defaultpriority,
+						 &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_DEVMODE) {
+		/*
+		 * Some client drivers freak out if there is a NULL devmode
+		 * (probably the driver is not checking before accessing
+		 * the devmode pointer)   --jerry
+		 */
+		if (devmode == NULL && lp_default_devmode(snum) && info2 != NULL) {
+			result = spoolss_create_default_devmode(tmp_ctx,
+								info2->printername,
+								&devmode);
+			if (!W_ERROR_IS_OK(result)) {
+				goto done;
+			}
+		}
+
+		if (devmode->size != (ndr_size_spoolss_DeviceMode(devmode, 0) - devmode->__driverextra_length)) {
+			result = WERR_INVALID_PARAM;
+			goto done;
+		}
+
+		ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, devmode,
+				(ndr_push_flags_fn_t) ndr_push_spoolss_DeviceMode);
+		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+			DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
+			result = WERR_NOMEM;
+			goto done;
+		}
+
+		status = dcerpc_winreg_set_binary(tmp_ctx,
+						  winreg_handle,
+						  &key_hnd,
+						  "Default DevMode",
+						  &blob,
+						  &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_DRIVERNAME) {
+		status = dcerpc_winreg_set_sz(tmp_ctx,
+					      winreg_handle,
+					      &key_hnd,
+					      "Printer Driver",
+					      info2->drivername,
+					      &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_LOCATION) {
+		status = dcerpc_winreg_set_sz(tmp_ctx,
+					      winreg_handle,
+					      &key_hnd,
+					      "Location",
+					      info2->location,
+					      &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_PARAMETERS) {
+		status = dcerpc_winreg_set_sz(tmp_ctx,
+					      winreg_handle,
+					      &key_hnd,
+					      "Parameters",
+					      info2->parameters,
+					      &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_PORTNAME) {
+		status = dcerpc_winreg_set_sz(tmp_ctx,
+					      winreg_handle,
+					      &key_hnd,
+					      "Port",
+					      info2->portname,
+					      &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTERNAME) {
+		/*
+		 * in addprinter: no servername and the printer is the name
+		 * in setprinter: servername is \\server
+		 *                and printer is \\server\\printer
+		 *
+		 * Samba manages only local printers.
+		 * we currently don't support things like i
+		 * path=\\other_server\printer
+		 *
+		 * We only store the printername, not \\server\printername
+		 */
+		const char *p = strrchr(info2->printername, '\\');
+		if (p == NULL) {
+			p = info2->printername;
+		} else {
+			p++;
+		}
+		status = dcerpc_winreg_set_sz(tmp_ctx,
+					      winreg_handle,
+					      &key_hnd,
+					      "Name",
+					      p,
+					      &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTPROCESSOR) {
+		status = dcerpc_winreg_set_sz(tmp_ctx,
+					      winreg_handle,
+					      &key_hnd,
+					      "Print Processor",
+					      info2->printprocessor,
+					      &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_PRIORITY) {
+		status = dcerpc_winreg_set_dword(tmp_ctx,
+						 winreg_handle,
+						 &key_hnd,
+						 "Priority",
+						 info2->priority,
+						 &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_SECDESC) {
+		/*
+		 * We need a security descriptor, if it isn't specified by
+		 * AddPrinter{Ex} then create a default descriptor.
+		 */
+		if (secdesc == NULL) {
+			result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
+			if (!W_ERROR_IS_OK(result)) {
+				goto done;
+			}
+		}
+		result = winreg_set_printer_secdesc(tmp_ctx,
+						    winreg_handle,
+						    sharename,
+						    secdesc);
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_SEPFILE) {
+		status = dcerpc_winreg_set_sz(tmp_ctx,
+					      winreg_handle,
+					      &key_hnd,
+					      "Separator File",
+					      info2->sepfile,
+					      &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_SHARENAME) {
+		status = dcerpc_winreg_set_sz(tmp_ctx,
+					      winreg_handle,
+					      &key_hnd,
+					      "Share Name",
+					      info2->sharename,
+					      &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_STARTTIME) {
+		status = dcerpc_winreg_set_dword(tmp_ctx,
+						 winreg_handle,
+						 &key_hnd,
+						 "StartTime",
+						 info2->starttime,
+						 &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_STATUS) {
+		status = dcerpc_winreg_set_dword(tmp_ctx,
+						 winreg_handle,
+						 &key_hnd,
+						 "Status",
+						 info2->status,
+						 &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2_mask & SPOOLSS_PRINTER_INFO_UNTILTIME) {
+		status = dcerpc_winreg_set_dword(tmp_ctx,
+						 winreg_handle,
+						 &key_hnd,
+						 "UntilTime",
+						 info2->untiltime,
+						 &result);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = ntstatus_to_werror(status);
+		}
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	status = dcerpc_winreg_set_dword(tmp_ctx,
+					 winreg_handle,
+					 &key_hnd,
+					 "ChangeID",
+					 winreg_printer_rev_changeid(),
+					 &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
+			  struct dcerpc_binding_handle *winreg_handle,
+			  const char *printer,
+			  struct spoolss_PrinterInfo2 **pinfo2)
+{
+	struct spoolss_PrinterInfo2 *info2;
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	struct spoolss_PrinterEnumValues *enum_values = NULL;
+	struct spoolss_PrinterEnumValues *v = NULL;
+	enum ndr_err_code ndr_err;
+	DATA_BLOB blob;
+	int snum = lp_servicenumber(printer);
+	uint32_t num_values = 0;
+	uint32_t i;
+	char *path;
+	NTSTATUS status;
+	WERROR result = WERR_OK;
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, printer);
+	if (path == NULL) {
+		TALLOC_FREE(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					"",
+					false,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(2, ("winreg_get_printer: Could not open key %s: %s\n",
+			  path, win_errstr(result)));
+		goto done;
+	}
+
+	result = winreg_printer_enumvalues(tmp_ctx,
+					   winreg_handle,
+					   &key_hnd,
+					   &num_values,
+					   &enum_values);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n",
+			  path, win_errstr(result)));
+		goto done;
+	}
+
+	info2 = talloc_zero(tmp_ctx, struct spoolss_PrinterInfo2);
+	if (info2 == NULL) {
+		result = WERR_NOMEM;
+		goto done;
+	}
+
+	FILL_STRING(info2, EMPTY_STRING, info2->servername);
+	FILL_STRING(info2, EMPTY_STRING, info2->printername);
+	FILL_STRING(info2, EMPTY_STRING, info2->sharename);
+	FILL_STRING(info2, EMPTY_STRING, info2->portname);
+	FILL_STRING(info2, EMPTY_STRING, info2->drivername);
+	FILL_STRING(info2, EMPTY_STRING, info2->comment);
+	FILL_STRING(info2, EMPTY_STRING, info2->location);
+	FILL_STRING(info2, EMPTY_STRING, info2->sepfile);
+	FILL_STRING(info2, EMPTY_STRING, info2->printprocessor);
+	FILL_STRING(info2, EMPTY_STRING, info2->datatype);
+	FILL_STRING(info2, EMPTY_STRING, info2->parameters);
+
+	for (i = 0; i < num_values; i++) {
+		v = &enum_values[i];
+
+		result = winreg_enumval_to_sz(info2,
+					      v,
+					      "Name",
+					      &info2->printername);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info2,
+					      v,
+					      "Share Name",
+					      &info2->sharename);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info2,
+					      v,
+					      "Port",
+					      &info2->portname);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info2,
+					      v,
+					      "Description",
+					      &info2->comment);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info2,
+					      v,
+					      "Location",
+					      &info2->location);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info2,
+					      v,
+					      "Separator File",
+					      &info2->sepfile);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info2,
+					      v,
+					      "Print Processor",
+					      &info2->printprocessor);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info2,
+					      v,
+					      "Datatype",
+					      &info2->datatype);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info2,
+					      v,
+					      "Parameters",
+					      &info2->parameters);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info2,
+					      v,
+					      "Printer Driver",
+					      &info2->drivername);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_dword(info2,
+						 v,
+						 "Attributes",
+						 &info2->attributes);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_dword(info2,
+						 v,
+						 "Priority",
+						 &info2->priority);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_dword(info2,
+						 v,
+						 "Default Priority",
+						 &info2->defaultpriority);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_dword(info2,
+						 v,
+						 "StartTime",
+						 &info2->starttime);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_dword(info2,
+						 v,
+						 "UntilTime",
+						 &info2->untiltime);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_dword(info2,
+						 v,
+						 "Status",
+						 &info2->status);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_dword(info2,
+						 v,
+						 "StartTime",
+						 &info2->starttime);
+		CHECK_ERROR(result);
+	}
+
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
+					"for %s: %s\n",
+					v->value_name,
+					win_errstr(result)));
+		goto done;
+	}
+
+	/* Construct the Device Mode */
+	status = dcerpc_winreg_query_binary(tmp_ctx,
+					    winreg_handle,
+					    &key_hnd,
+					    "Default DevMode",
+					    &blob,
+					    &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (W_ERROR_IS_OK(result)) {
+		info2->devmode = talloc_zero(info2, struct spoolss_DeviceMode);
+		if (info2->devmode == NULL) {
+			result = WERR_NOMEM;
+			goto done;
+		}
+		ndr_err = ndr_pull_struct_blob(&blob,
+					       info2->devmode,
+					       info2->devmode,
+					       (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeviceMode);
+		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+			DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
+			result = WERR_NOMEM;
+			goto done;
+		}
+	}
+
+	if (info2->devmode == NULL && lp_default_devmode(snum)) {
+		result = spoolss_create_default_devmode(info2,
+							info2->printername,
+							&info2->devmode);
+		if (!W_ERROR_IS_OK(result)) {
+			goto done;
+		}
+	}
+
+	if (info2->devmode) {
+		info2->devmode->size = ndr_size_spoolss_DeviceMode(info2->devmode, 0) - info2->devmode->driverextra_data.length;
+	}
+
+	result = winreg_get_printer_secdesc(info2,
+					    winreg_handle,
+					    printer,
+					    &info2->secdesc);
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	/* Fix for OS/2 drivers. */
+	if (get_remote_arch() == RA_OS2) {
+		spoolss_map_to_os2_driver(info2, &info2->drivername);
+	}
+
+	if (pinfo2) {
+		*pinfo2 = talloc_move(mem_ctx, &info2);
+	}
+
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
+				  struct dcerpc_binding_handle *winreg_handle,
+				  const char *sharename,
+				  struct spoolss_security_descriptor **psecdesc)
+{
+	struct spoolss_security_descriptor *secdesc;
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	const char *path;
+	TALLOC_CTX *tmp_ctx;
+	NTSTATUS status;
+	WERROR result;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, sharename);
+	if (path == NULL) {
+		talloc_free(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					"",
+					false,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+			goto create_default;
+		}
+		goto done;
+	}
+
+	status = dcerpc_winreg_query_sd(tmp_ctx,
+					winreg_handle,
+					&key_hnd,
+					"Security",
+					&secdesc,
+					&result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+			goto create_default;
+		}
+		goto done;
+	}
+
+	if (psecdesc) {
+		*psecdesc = talloc_move(mem_ctx, &secdesc);
+	}
+
+	result = WERR_OK;
+	goto done;
+
+create_default:
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					"",
+					true,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	/* If security descriptor is owned by S-1-1-0 and winbindd is up,
+	   this security descriptor has been created when winbindd was
+	   down.  Take ownership of security descriptor. */
+	if (dom_sid_equal(secdesc->owner_sid, &global_sid_World)) {
+		struct dom_sid owner_sid;
+
+		/* Change sd owner to workgroup administrator */
+
+		if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
+			struct spoolss_security_descriptor *new_secdesc;
+			size_t size;
+
+			/* Create new sd */
+			sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
+
+			new_secdesc = make_sec_desc(tmp_ctx,
+						    secdesc->revision,
+						    secdesc->type,
+						    &owner_sid,
+						    secdesc->group_sid,
+						    secdesc->sacl,
+						    secdesc->dacl,
+						    &size);
+
+			if (new_secdesc == NULL) {
+				result = WERR_NOMEM;
+				goto done;
+			}
+
+			/* Swap with other one */
+			secdesc = new_secdesc;
+		}
+	}
+
+	status = dcerpc_winreg_set_sd(tmp_ctx,
+					  winreg_handle,
+					  &key_hnd,
+					  "Security",
+					  secdesc,
+					  &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		return result;
+	}
+
+	if (psecdesc) {
+		*psecdesc = talloc_move(mem_ctx, &secdesc);
+	}
+
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	talloc_free(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
+				  struct dcerpc_binding_handle *winreg_handle,
+				  const char *sharename,
+				  const struct spoolss_security_descriptor *secdesc)
+{
+	const struct spoolss_security_descriptor *new_secdesc = secdesc;
+	struct spoolss_security_descriptor *old_secdesc;
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	const char *path;
+	TALLOC_CTX *tmp_ctx;
+	NTSTATUS status;
+	WERROR result;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, sharename);
+	if (path == NULL) {
+		talloc_free(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	/*
+	 * The old owner and group sids of the security descriptor are not
+	 * present when new ACEs are added or removed by changing printer
+	 * permissions through NT.  If they are NULL in the new security
+	 * descriptor then copy them over from the old one.
+	 */
+	if (!secdesc->owner_sid || !secdesc->group_sid) {
+		struct dom_sid *owner_sid, *group_sid;
+		struct security_acl *dacl, *sacl;
+		size_t size;
+
+		result = winreg_get_printer_secdesc(tmp_ctx,
+						    winreg_handle,
+						    sharename,
+						    &old_secdesc);
+		if (!W_ERROR_IS_OK(result)) {
+			talloc_free(tmp_ctx);
+			return result;
+		}
+
+		/* Pick out correct owner and group sids */
+		owner_sid = secdesc->owner_sid ?
+			    secdesc->owner_sid :
+			    old_secdesc->owner_sid;
+
+		group_sid = secdesc->group_sid ?
+			    secdesc->group_sid :
+			    old_secdesc->group_sid;
+
+		dacl = secdesc->dacl ?
+		       secdesc->dacl :
+		       old_secdesc->dacl;
+
+		sacl = secdesc->sacl ?
+		       secdesc->sacl :
+		       old_secdesc->sacl;
+
+		/* Make a deep copy of the security descriptor */
+		new_secdesc = make_sec_desc(tmp_ctx,
+					    secdesc->revision,
+					    secdesc->type,
+					    owner_sid,
+					    group_sid,
+					    sacl,
+					    dacl,
+					    &size);
+		if (new_secdesc == NULL) {
+			talloc_free(tmp_ctx);
+			return WERR_NOMEM;
+		}
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					"",
+					false,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sd(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "Security",
+				      new_secdesc,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	talloc_free(tmp_ctx);
+	return result;
+}
+
+/* Set printer data over the winreg pipe. */
+WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
+				 struct dcerpc_binding_handle *winreg_handle,
+				 const char *printer,
+				 const char *key,
+				 const char *value,
+				 enum winreg_Type type,
+				 uint8_t *data,
+				 uint32_t data_size)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	struct winreg_String wvalue = { 0, };
+	char *path;
+	WERROR result = WERR_OK;
+	NTSTATUS status;
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, printer);
+	if (path == NULL) {
+		TALLOC_FREE(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n",
+			key, value, access_mask, printer));
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					key,
+					true,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n",
+			  key, win_errstr(result)));
+		goto done;
+	}
+
+	wvalue.name = value;
+	status = dcerpc_winreg_SetValue(winreg_handle,
+					tmp_ctx,
+					&key_hnd,
+					wvalue,
+					type,
+					data,
+					data_size,
+					&result);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n",
+			  value, nt_errstr(status)));
+		result = ntstatus_to_werror(status);
+	}
+
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+/* Get printer data over a winreg pipe. */
+WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
+				 struct dcerpc_binding_handle *winreg_handle,
+				 const char *printer,
+				 const char *key,
+				 const char *value,
+				 enum winreg_Type *type,
+				 uint8_t **data,
+				 uint32_t *data_size)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	struct winreg_String wvalue;
+	enum winreg_Type type_in = REG_NONE;
+	char *path;
+	uint8_t *data_in = NULL;
+	uint32_t data_in_size = 0;
+	uint32_t value_len = 0;
+	WERROR result = WERR_OK;
+	NTSTATUS status;
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, printer);
+	if (path == NULL) {
+		TALLOC_FREE(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					key,
+					false,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(2, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
+			  key, win_errstr(result)));
+		goto done;
+	}
+
+	wvalue.name = value;
+
+	/*
+	 * call QueryValue once with data == NULL to get the
+	 * needed memory size to be allocated, then allocate
+	 * data buffer and call again.
+	 */
+	status = dcerpc_winreg_QueryValue(winreg_handle,
+					  tmp_ctx,
+					  &key_hnd,
+					  &wvalue,
+					  &type_in,
+					  NULL,
+					  &data_in_size,
+					  &value_len,
+					  &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
+			  value, nt_errstr(status)));
+		result = ntstatus_to_werror(status);
+		goto done;
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size);
+	if (data_in == NULL) {
+		result = WERR_NOMEM;
+		goto done;
+	}
+	value_len = 0;
+
+	status = dcerpc_winreg_QueryValue(winreg_handle,
+					  tmp_ctx,
+					  &key_hnd,
+					  &wvalue,
+					  &type_in,
+					  data_in,
+					  &data_in_size,
+					  &value_len,
+					  &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
+			  value, nt_errstr(status)));
+		result = ntstatus_to_werror(status);
+		goto done;
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	*type = type_in;
+	*data_size = data_in_size;
+	if (data_in_size) {
+		*data = talloc_move(mem_ctx, &data_in);
+	}
+
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+/* Enumerate on the values of a given key and provide the data. */
+WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
+				  struct dcerpc_binding_handle *winreg_handle,
+				  const char *printer,
+				  const char *key,
+				  uint32_t *pnum_values,
+				  struct spoolss_PrinterEnumValues **penum_values)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+
+	struct spoolss_PrinterEnumValues *enum_values = NULL;
+	uint32_t num_values = 0;
+	char *path;
+	WERROR result = WERR_OK;
+
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, printer);
+	if (path == NULL) {
+		TALLOC_FREE(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					key,
+					false,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(2, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
+			  key, win_errstr(result)));
+		goto done;
+	}
+
+	result = winreg_printer_enumvalues(tmp_ctx,
+					   winreg_handle,
+					   &key_hnd,
+					   &num_values,
+					   &enum_values);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
+			  key, win_errstr(result)));
+		goto done;
+	}
+
+	*pnum_values = num_values;
+	if (penum_values) {
+		*penum_values = talloc_move(mem_ctx, &enum_values);
+	}
+
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+/* Delete printer data over a winreg pipe. */
+WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx,
+				    struct dcerpc_binding_handle *winreg_handle,
+				    const char *printer,
+				    const char *key,
+				    const char *value)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	struct winreg_String wvalue = { 0, };
+	char *path;
+	WERROR result = WERR_OK;
+	NTSTATUS status;
+
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, printer);
+	if (path == NULL) {
+		TALLOC_FREE(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					key,
+					false,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n",
+			  key, win_errstr(result)));
+		goto done;
+	}
+
+	wvalue.name = value;
+	status = dcerpc_winreg_DeleteValue(winreg_handle,
+					   tmp_ctx,
+					   &key_hnd,
+					   wvalue,
+					   &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n",
+			  value, nt_errstr(status)));
+		result = ntstatus_to_werror(status);
+	}
+
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+/* Enumerate on the subkeys of a given key and provide the data. */
+WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
+			       struct dcerpc_binding_handle *winreg_handle,
+			       const char *printer,
+			       const char *key,
+			       uint32_t *pnum_subkeys,
+			       const char ***psubkeys)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	char *path;
+	const char **subkeys = NULL;
+	uint32_t num_subkeys = -1;
+
+	WERROR result = WERR_OK;
+	NTSTATUS status;
+
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, printer);
+	if (path == NULL) {
+		TALLOC_FREE(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					key,
+					false,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(2, ("winreg_enum_printer_key: Could not open key %s: %s\n",
+			  key, win_errstr(result)));
+		goto done;
+	}
+
+	status = dcerpc_winreg_enum_keys(tmp_ctx,
+					 winreg_handle,
+					 &key_hnd,
+					 &num_subkeys,
+					 &subkeys,
+					 &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n",
+			  key, win_errstr(result)));
+		goto done;
+	}
+
+	*pnum_subkeys = num_subkeys;
+	if (psubkeys) {
+		*psubkeys = talloc_move(mem_ctx, &subkeys);
+	}
+
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+/* Delete a key with subkeys of a given printer. */
+WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx,
+				 struct dcerpc_binding_handle *winreg_handle,
+				 const char *printer,
+				 const char *key)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	char *keyname;
+	char *path;
+	WERROR result;
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, printer);
+	if (path == NULL) {
+		TALLOC_FREE(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					key,
+					false,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		/* key doesn't exist */
+		if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+			result = WERR_OK;
+			goto done;
+		}
+
+		DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
+			  key, win_errstr(result)));
+		goto done;
+	}
+
+	if (is_valid_policy_hnd(&key_hnd)) {
+		dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
+	}
+
+	if (key == NULL || key[0] == '\0') {
+		keyname = path;
+	} else {
+		keyname = talloc_asprintf(tmp_ctx,
+					  "%s\\%s",
+					  path,
+					  key);
+		if (keyname == NULL) {
+			result = WERR_NOMEM;
+			goto done;
+		}
+	}
+
+	result = winreg_printer_delete_subkeys(tmp_ctx,
+					       winreg_handle,
+					       &hive_hnd,
+					       access_mask,
+					       keyname);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
+			  key, win_errstr(result)));
+		goto done;
+	}
+
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx,
+				      struct dcerpc_binding_handle *winreg_handle,
+				      const char *printer)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	char *path;
+	NTSTATUS status;
+	WERROR result;
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, printer);
+	if (path == NULL) {
+		TALLOC_FREE(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					"",
+					false,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_printer_update_changeid: Could not open key %s: %s\n",
+			  path, win_errstr(result)));
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_dword(tmp_ctx,
+					 winreg_handle,
+					 &key_hnd,
+					 "ChangeID",
+					 winreg_printer_rev_changeid(),
+					 &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
+				   struct dcerpc_binding_handle *winreg_handle,
+				   const char *printer,
+				   uint32_t *pchangeid)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	uint32_t changeid = 0;
+	char *path;
+	NTSTATUS status;
+	WERROR result;
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	path = winreg_printer_data_keyname(tmp_ctx, printer);
+	if (path == NULL) {
+		TALLOC_FREE(tmp_ctx);
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					path,
+					"",
+					false,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(2, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
+			  path, win_errstr(result)));
+		goto done;
+	}
+
+	DEBUG(10, ("winreg_printer_get_changeid: get changeid from %s\n", path));
+
+	status = dcerpc_winreg_query_dword(tmp_ctx,
+					   winreg_handle,
+					   &key_hnd,
+					   "ChangeID",
+					   &changeid,
+					   &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	if (pchangeid) {
+		*pchangeid = changeid;
+	}
+
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+/*
+ * The special behaviour of the spoolss forms is documented at the website:
+ *
+ * Managing Win32 Printserver Forms
+ * http://unixwiz.net/techtips/winspooler-forms.html
+ */
+
+WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx,
+			       struct dcerpc_binding_handle *winreg_handle,
+			       struct spoolss_AddFormInfo1 *form)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	struct winreg_String wvalue = { 0, };
+	DATA_BLOB blob;
+	uint32_t num_info = 0;
+	union spoolss_FormInfo *info = NULL;
+	uint32_t i;
+	WERROR result;
+	NTSTATUS status;
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					TOP_LEVEL_CONTROL_FORMS_KEY,
+					"",
+					true,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n",
+			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
+		goto done;
+	}
+
+	result = winreg_printer_enumforms1(tmp_ctx, winreg_handle,
+					   &num_info, &info);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n",
+			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
+		goto done;
+	}
+
+	/* If form name already exists or is builtin return ALREADY_EXISTS */
+	for (i = 0; i < num_info; i++) {
+		if (strequal(info[i].info1.form_name, form->form_name)) {
+			result = WERR_FILE_EXISTS;
+			goto done;
+		}
+	}
+
+	wvalue.name = form->form_name;
+
+	blob = data_blob_talloc(tmp_ctx, NULL, 32);
+	SIVAL(blob.data,  0, form->size.width);
+	SIVAL(blob.data,  4, form->size.height);
+	SIVAL(blob.data,  8, form->area.left);
+	SIVAL(blob.data, 12, form->area.top);
+	SIVAL(blob.data, 16, form->area.right);
+	SIVAL(blob.data, 20, form->area.bottom);
+	SIVAL(blob.data, 24, num_info + 1); /* FIXME */
+	SIVAL(blob.data, 28, form->flags);
+
+	status = dcerpc_winreg_SetValue(winreg_handle,
+					tmp_ctx,
+					&key_hnd,
+					wvalue,
+					REG_BINARY,
+					blob.data,
+					blob.length,
+					&result);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n",
+			  wvalue.name, nt_errstr(status)));
+		result = ntstatus_to_werror(status);
+	}
+
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(info);
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
+				 struct dcerpc_binding_handle *winreg_handle,
+				 uint32_t *pnum_info,
+				 union spoolss_FormInfo **pinfo)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	union spoolss_FormInfo *info;
+	struct spoolss_PrinterEnumValues *enum_values = NULL;
+	uint32_t num_values = 0;
+	uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
+	uint32_t i;
+	WERROR result;
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					TOP_LEVEL_CONTROL_FORMS_KEY,
+					"",
+					true,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		/* key doesn't exist */
+		if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+			result = WERR_OK;
+			goto done;
+		}
+
+		DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n",
+			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
+		goto done;
+	}
+
+	result = winreg_printer_enumvalues(tmp_ctx,
+					   winreg_handle,
+					   &key_hnd,
+					   &num_values,
+					   &enum_values);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
+			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
+		goto done;
+	}
+
+	info = talloc_array(tmp_ctx, union spoolss_FormInfo, num_builtin + num_values);
+	if (info == NULL) {
+		result = WERR_NOMEM;
+		goto done;
+	}
+
+	/* Enumerate BUILTIN forms */
+	for (i = 0; i < num_builtin; i++) {
+		info[i].info1 = builtin_forms1[i];
+	}
+
+	/* Enumerate registry forms */
+	for (i = 0; i < num_values; i++) {
+		union spoolss_FormInfo val;
+
+		if (enum_values[i].type != REG_BINARY ||
+		    enum_values[i].data_length != 32) {
+			continue;
+		}
+
+		val.info1.form_name = talloc_strdup(info, enum_values[i].value_name);
+		if (val.info1.form_name == NULL) {
+			result = WERR_NOMEM;
+			goto done;
+		}
+
+		val.info1.size.width  = IVAL(enum_values[i].data->data,  0);
+		val.info1.size.height = IVAL(enum_values[i].data->data,  4);
+		val.info1.area.left   = IVAL(enum_values[i].data->data,  8);
+		val.info1.area.top    = IVAL(enum_values[i].data->data, 12);
+		val.info1.area.right  = IVAL(enum_values[i].data->data, 16);
+		val.info1.area.bottom = IVAL(enum_values[i].data->data, 20);
+		/* skip form index      IVAL(enum_values[i].data->data, 24)));*/
+		val.info1.flags       = (enum spoolss_FormFlags) IVAL(enum_values[i].data->data, 28);
+
+		info[i + num_builtin] = val;
+	}
+
+	*pnum_info = num_builtin + num_values;
+	if (pinfo) {
+		*pinfo = talloc_move(mem_ctx, &info);
+	}
+
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(enum_values);
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx,
+				  struct dcerpc_binding_handle *winreg_handle,
+				  const char *form_name)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	struct winreg_String wvalue = { 0, };
+	uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
+	uint32_t i;
+	WERROR result = WERR_OK;
+	NTSTATUS status;
+	TALLOC_CTX *tmp_ctx;
+
+	for (i = 0; i < num_builtin; i++) {
+		if (strequal(builtin_forms1[i].form_name, form_name)) {
+			return WERR_INVALID_PARAMETER;
+		}
+	}
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					TOP_LEVEL_CONTROL_FORMS_KEY,
+					"",
+					false,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n",
+			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
+		if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+			result = WERR_INVALID_FORM_NAME;
+		}
+		goto done;
+	}
+
+	wvalue.name = form_name;
+	status = dcerpc_winreg_DeleteValue(winreg_handle,
+					   tmp_ctx,
+					   &key_hnd,
+					   wvalue,
+					   &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		/* If the value doesn't exist, return WERR_INVALID_FORM_NAME */
+		DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n",
+			  wvalue.name, nt_errstr(status)));
+		result = ntstatus_to_werror(status);
+		goto done;
+	}
+
+	if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+		result = WERR_INVALID_FORM_NAME;
+	}
+
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx,
+			       struct dcerpc_binding_handle *winreg_handle,
+			       const char *form_name,
+			       struct spoolss_AddFormInfo1 *form)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	struct winreg_String wvalue = { 0, };
+	DATA_BLOB blob;
+	uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
+	uint32_t i;
+	WERROR result;
+	NTSTATUS status;
+	TALLOC_CTX *tmp_ctx = NULL;
+
+	for (i = 0; i < num_builtin; i++) {
+		if (strequal(builtin_forms1[i].form_name, form->form_name)) {
+			result = WERR_INVALID_PARAM;
+			goto done;
+		}
+	}
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					TOP_LEVEL_CONTROL_FORMS_KEY,
+					"",
+					true,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
+			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
+		goto done;
+	}
+
+	/* If form_name != form->form_name then we renamed the form */
+	if (strequal(form_name, form->form_name)) {
+		result = winreg_printer_deleteform1(tmp_ctx, winreg_handle,
+						    form_name);
+		if (!W_ERROR_IS_OK(result)) {
+			DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
+				  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
+			goto done;
+		}
+	}
+
+	wvalue.name = form->form_name;
+
+	blob = data_blob_talloc(tmp_ctx, NULL, 32);
+	SIVAL(blob.data,  0, form->size.width);
+	SIVAL(blob.data,  4, form->size.height);
+	SIVAL(blob.data,  8, form->area.left);
+	SIVAL(blob.data, 12, form->area.top);
+	SIVAL(blob.data, 16, form->area.right);
+	SIVAL(blob.data, 20, form->area.bottom);
+	SIVAL(blob.data, 24, 42);
+	SIVAL(blob.data, 28, form->flags);
+
+	status = dcerpc_winreg_SetValue(winreg_handle,
+					tmp_ctx,
+					&key_hnd,
+					wvalue,
+					REG_BINARY,
+					blob.data,
+					blob.length,
+					&result);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n",
+			  wvalue.name, nt_errstr(status)));
+		result = ntstatus_to_werror(status);
+	}
+
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
+			       struct dcerpc_binding_handle *winreg_handle,
+			       const char *form_name,
+			       struct spoolss_FormInfo1 *r)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	struct winreg_String wvalue;
+	enum winreg_Type type_in = REG_NONE;
+	uint8_t *data_in = NULL;
+	uint32_t data_in_size = 0;
+	uint32_t value_len = 0;
+	uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
+	uint32_t i;
+	WERROR result;
+	NTSTATUS status;
+	TALLOC_CTX *tmp_ctx;
+
+	/* check builtin forms first */
+	for (i = 0; i < num_builtin; i++) {
+		if (strequal(builtin_forms1[i].form_name, form_name)) {
+			*r = builtin_forms1[i];
+			return WERR_OK;
+		}
+	}
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	result = winreg_printer_openkey(tmp_ctx,
+					winreg_handle,
+					TOP_LEVEL_CONTROL_FORMS_KEY,
+					"",
+					true,
+					access_mask,
+					&hive_hnd,
+					&key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(2, ("winreg_printer_getform1: Could not open key %s: %s\n",
+			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
+		goto done;
+	}
+
+	wvalue.name = form_name;
+
+	/*
+	 * call QueryValue once with data == NULL to get the
+	 * needed memory size to be allocated, then allocate
+	 * data buffer and call again.
+	 */
+	status = dcerpc_winreg_QueryValue(winreg_handle,
+					  tmp_ctx,
+					  &key_hnd,
+					  &wvalue,
+					  &type_in,
+					  NULL,
+					  &data_in_size,
+					  &value_len,
+					  &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
+			  wvalue.name, nt_errstr(status)));
+		result = ntstatus_to_werror(status);
+		goto done;
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size);
+	if (data_in == NULL) {
+		result = WERR_NOMEM;
+		goto done;
+	}
+	value_len = 0;
+
+	status = dcerpc_winreg_QueryValue(winreg_handle,
+					  tmp_ctx,
+					  &key_hnd,
+					  &wvalue,
+					  &type_in,
+					  data_in,
+					  &data_in_size,
+					  &value_len,
+					  &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
+			  wvalue.name, nt_errstr(status)));
+		result = ntstatus_to_werror(status);
+		goto done;
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	r->form_name = talloc_strdup(mem_ctx, form_name);
+	if (r->form_name == NULL) {
+		result = WERR_NOMEM;
+		goto done;
+	}
+
+	r->size.width  = IVAL(data_in,  0);
+	r->size.height = IVAL(data_in,  4);
+	r->area.left   = IVAL(data_in,  8);
+	r->area.top    = IVAL(data_in, 12);
+	r->area.right  = IVAL(data_in, 16);
+	r->area.bottom = IVAL(data_in, 20);
+	/* skip index    IVAL(data_in, 24)));*/
+	r->flags       = (enum spoolss_FormFlags) IVAL(data_in, 28);
+
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_add_driver(TALLOC_CTX *mem_ctx,
+			 struct dcerpc_binding_handle *winreg_handle,
+			 struct spoolss_AddDriverInfoCtr *r,
+			 const char **driver_name,
+			 uint32_t *driver_version)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	struct spoolss_DriverInfo8 info8;
+	TALLOC_CTX *tmp_ctx = NULL;
+	NTSTATUS status;
+	WERROR result;
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+	ZERO_STRUCT(info8);
+
+	if (!driver_info_ctr_to_info8(r, &info8)) {
+		result = WERR_INVALID_PARAMETER;
+		goto done;
+	}
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	result = winreg_printer_opendriver(tmp_ctx,
+					   winreg_handle,
+					   info8.driver_name,
+					   info8.architecture,
+					   info8.version,
+					   access_mask, true,
+					   &hive_hnd,
+					   &key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_add_driver: "
+			  "Could not open driver key (%s,%s,%d): %s\n",
+			  info8.driver_name, info8.architecture,
+			  info8.version, win_errstr(result)));
+		goto done;
+	}
+
+	/* TODO: "Attributes" ? */
+
+	status = dcerpc_winreg_set_dword(tmp_ctx,
+					 winreg_handle,
+					 &key_hnd,
+					 "Version",
+					 info8.version,
+					 &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "Driver",
+				      info8.driver_path,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "Data File",
+				      info8.data_file,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "Configuration File",
+				      info8.config_file,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "Help File",
+				      info8.help_file,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_multi_sz(tmp_ctx,
+					    winreg_handle,
+					    &key_hnd,
+					    "Dependent Files",
+					    info8.dependent_files,
+					    &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "Monitor",
+				      info8.monitor_name,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "Datatype",
+				      info8.default_datatype,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_multi_sz(tmp_ctx,
+					    winreg_handle,
+					    &key_hnd, "Previous Names",
+					    info8.previous_names,
+					    &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	result = winreg_printer_write_date(tmp_ctx, winreg_handle,
+					   &key_hnd, "DriverDate",
+					   info8.driver_date);
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	result = winreg_printer_write_ver(tmp_ctx, winreg_handle,
+					  &key_hnd, "DriverVersion",
+					  info8.driver_version);
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "Manufacturer",
+				      info8.manufacturer_name,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "OEM URL",
+				      info8.manufacturer_url,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "HardwareID",
+				      info8.hardware_id,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "Provider",
+				      info8.provider,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "Print Processor",
+				      info8.print_processor,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "VendorSetup",
+				      info8.vendor_setup,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_multi_sz(tmp_ctx,
+					    winreg_handle,
+					    &key_hnd,
+					    "Color Profiles",
+					    info8.color_profiles,
+					    &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_sz(tmp_ctx,
+				      winreg_handle,
+				      &key_hnd,
+				      "InfPath",
+				      info8.inf_path,
+				      &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_dword(tmp_ctx,
+					 winreg_handle,
+					 &key_hnd,
+					 "PrinterDriverAttributes",
+					 info8.printer_driver_attributes,
+					 &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	status = dcerpc_winreg_set_multi_sz(tmp_ctx,
+					    winreg_handle,
+					    &key_hnd,
+					    "CoreDependencies",
+					    info8.core_driver_dependencies,
+					    &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	result = winreg_printer_write_date(tmp_ctx, winreg_handle,
+					   &key_hnd, "MinInboxDriverVerDate",
+					   info8.min_inbox_driver_ver_date);
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	result = winreg_printer_write_ver(tmp_ctx, winreg_handle, &key_hnd,
+					  "MinInboxDriverVerVersion",
+					  info8.min_inbox_driver_ver_version);
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	*driver_name = info8.driver_name;
+	*driver_version = info8.version;
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
+			 struct dcerpc_binding_handle *winreg_handle,
+			 const char *architecture,
+			 const char *driver_name,
+			 uint32_t driver_version,
+			 struct spoolss_DriverInfo8 **_info8)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	struct spoolss_DriverInfo8 i8, *info8;
+	struct spoolss_PrinterEnumValues *enum_values = NULL;
+	struct spoolss_PrinterEnumValues *v;
+	uint32_t num_values = 0;
+	TALLOC_CTX *tmp_ctx;
+	WERROR result;
+	uint32_t i;
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+	ZERO_STRUCT(i8);
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	if (driver_version == DRIVER_ANY_VERSION) {
+		/* look for Win2k first and then for NT4 */
+		result = winreg_printer_opendriver(tmp_ctx,
+						   winreg_handle,
+						   driver_name,
+						   architecture,
+						   3,
+						   access_mask, false,
+						   &hive_hnd,
+						   &key_hnd);
+		if (!W_ERROR_IS_OK(result)) {
+			result = winreg_printer_opendriver(tmp_ctx,
+							   winreg_handle,
+							   driver_name,
+							   architecture,
+							   2,
+							   access_mask, false,
+							   &hive_hnd,
+							   &key_hnd);
+		}
+	} else {
+		/* ok normal case */
+		result = winreg_printer_opendriver(tmp_ctx,
+						   winreg_handle,
+						   driver_name,
+						   architecture,
+						   driver_version,
+						   access_mask, false,
+						   &hive_hnd,
+						   &key_hnd);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(5, ("winreg_get_driver: "
+			  "Could not open driver key (%s,%s,%d): %s\n",
+			  driver_name, architecture,
+			  driver_version, win_errstr(result)));
+		goto done;
+	}
+
+	result = winreg_printer_enumvalues(tmp_ctx,
+					   winreg_handle,
+					   &key_hnd,
+					   &num_values,
+					   &enum_values);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_get_driver: "
+			  "Could not enumerate values for (%s,%s,%d): %s\n",
+			  driver_name, architecture,
+			  driver_version, win_errstr(result)));
+		goto done;
+	}
+
+	info8 = talloc_zero(tmp_ctx, struct spoolss_DriverInfo8);
+	if (info8 == NULL) {
+		result = WERR_NOMEM;
+		goto done;
+	}
+
+	info8->driver_name = talloc_strdup(info8, driver_name);
+	if (info8->driver_name == NULL) {
+		result = WERR_NOMEM;
+		goto done;
+	}
+
+	info8->architecture = talloc_strdup(info8, architecture);
+	if (info8->architecture == NULL) {
+		result = WERR_NOMEM;
+		goto done;
+	}
+
+	result = WERR_OK;
+
+	for (i = 0; i < num_values; i++) {
+		const char *tmp_str;
+		uint32_t tmp = 0;
+
+		v = &enum_values[i];
+
+		result = winreg_enumval_to_dword(info8, v,
+						 "Version",
+						 &tmp);
+		if (NT_STATUS_IS_OK(result)) {
+			info8->version = (enum spoolss_DriverOSVersion) tmp;
+		}
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "Driver",
+					      &info8->driver_path);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "Data File",
+					      &info8->data_file);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "Configuration File",
+					      &info8->config_file);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "Help File",
+					      &info8->help_file);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_multi_sz(info8, v,
+						    "Dependent Files",
+						    &info8->dependent_files);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "Monitor",
+					      &info8->monitor_name);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "Datatype",
+					      &info8->default_datatype);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_multi_sz(info8, v,
+						    "Previous Names",
+						    &info8->previous_names);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "DriverDate",
+					      &tmp_str);
+		if (W_ERROR_IS_OK(result)) {
+			result = winreg_printer_date_to_NTTIME(tmp_str,
+						&info8->driver_date);
+		}
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "DriverVersion",
+					      &tmp_str);
+		if (W_ERROR_IS_OK(result)) {
+			result = winreg_printer_ver_to_dword(tmp_str,
+						&info8->driver_version);
+		}
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "Manufacturer",
+					      &info8->manufacturer_name);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "OEM URL",
+					      &info8->manufacturer_url);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "HardwareID",
+					      &info8->hardware_id);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "Provider",
+					      &info8->provider);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "Print Processor",
+					      &info8->print_processor);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "VendorSetup",
+					      &info8->vendor_setup);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_multi_sz(info8, v,
+						    "Color Profiles",
+						    &info8->color_profiles);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "InfPath",
+					      &info8->inf_path);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_dword(info8, v,
+						 "PrinterDriverAttributes",
+						 &info8->printer_driver_attributes);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_multi_sz(info8, v,
+						    "CoreDependencies",
+						    &info8->core_driver_dependencies);
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "MinInboxDriverVerDate",
+					      &tmp_str);
+		if (W_ERROR_IS_OK(result)) {
+			result = winreg_printer_date_to_NTTIME(tmp_str,
+					&info8->min_inbox_driver_ver_date);
+		}
+		CHECK_ERROR(result);
+
+		result = winreg_enumval_to_sz(info8, v,
+					      "MinInboxDriverVerVersion",
+					      &tmp_str);
+		if (W_ERROR_IS_OK(result)) {
+			result = winreg_printer_ver_to_dword(tmp_str,
+					&info8->min_inbox_driver_ver_version);
+		}
+		CHECK_ERROR(result);
+	}
+
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_enumval_to_TYPE() failed "
+			  "for %s: %s\n", v->value_name,
+			  win_errstr(result)));
+		goto done;
+	}
+
+	*_info8 = talloc_steal(mem_ctx, info8);
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_del_driver(TALLOC_CTX *mem_ctx,
+			 struct dcerpc_binding_handle *winreg_handle,
+			 struct spoolss_DriverInfo8 *info8,
+			 uint32_t version)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	TALLOC_CTX *tmp_ctx;
+	char *key_name;
+	WERROR result;
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	/* test that the key exists */
+	result = winreg_printer_opendriver(tmp_ctx,
+					   winreg_handle,
+					   info8->driver_name,
+					   info8->architecture,
+					   version,
+					   access_mask, false,
+					   &hive_hnd,
+					   &key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		/* key doesn't exist */
+		if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+			result = WERR_OK;
+			goto done;
+		}
+
+		DEBUG(5, ("winreg_del_driver: "
+			  "Could not open driver (%s,%s,%u): %s\n",
+			  info8->driver_name, info8->architecture,
+			  version, win_errstr(result)));
+		goto done;
+	}
+
+
+	if (is_valid_policy_hnd(&key_hnd)) {
+		dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
+	}
+
+	key_name = talloc_asprintf(tmp_ctx,
+				   "%s\\Environments\\%s\\Drivers\\Version-%u\\%s",
+				   TOP_LEVEL_CONTROL_KEY,
+				   info8->architecture, version,
+				   info8->driver_name);
+	if (key_name == NULL) {
+		result = WERR_NOMEM;
+		goto done;
+	}
+
+	result = winreg_printer_delete_subkeys(tmp_ctx,
+					       winreg_handle,
+					       &hive_hnd,
+					       access_mask,
+					       key_name);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_del_driver: "
+			  "Could not open driver (%s,%s,%u): %s\n",
+			  info8->driver_name, info8->architecture,
+			  version, win_errstr(result)));
+		goto done;
+	}
+
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}
+
+WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
+			      struct dcerpc_binding_handle *winreg_handle,
+			      const char *architecture,
+			      uint32_t version,
+			      uint32_t *num_drivers,
+			      const char ***drivers_p)
+{
+	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	struct policy_handle hive_hnd, key_hnd;
+	const char **drivers;
+	TALLOC_CTX *tmp_ctx;
+	WERROR result;
+	NTSTATUS status;
+
+	*num_drivers = 0;
+	*drivers_p = NULL;
+
+	ZERO_STRUCT(hive_hnd);
+	ZERO_STRUCT(key_hnd);
+
+	tmp_ctx = talloc_stackframe();
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	/* use NULL for the driver name so we open the key that is
+	 * parent of all drivers for this architecture and version */
+	result = winreg_printer_opendriver(tmp_ctx,
+					   winreg_handle,
+					   NULL,
+					   architecture,
+					   version,
+					   access_mask, false,
+					   &hive_hnd,
+					   &key_hnd);
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(5, ("winreg_get_driver_list: "
+			  "Could not open key (%s,%u): %s\n",
+			  architecture, version, win_errstr(result)));
+		result = WERR_OK;
+		goto done;
+	}
+
+	status = dcerpc_winreg_enum_keys(tmp_ctx,
+					 winreg_handle,
+					 &key_hnd,
+					 num_drivers,
+					 &drivers,
+					 &result);
+	if (!NT_STATUS_IS_OK(status)) {
+		result = ntstatus_to_werror(status);
+	}
+	if (!W_ERROR_IS_OK(result)) {
+		DEBUG(0, ("winreg_get_driver_list: "
+			  "Could not enumerate drivers for (%s,%u): %s\n",
+			  architecture, version, win_errstr(result)));
+		goto done;
+	}
+
+	*drivers_p = talloc_steal(mem_ctx, drivers);
+
+	result = WERR_OK;
+done:
+	if (winreg_handle != NULL) {
+		WERROR ignore;
+
+		if (is_valid_policy_hnd(&key_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+		}
+		if (is_valid_policy_hnd(&hive_hnd)) {
+			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+		}
+	}
+
+	TALLOC_FREE(tmp_ctx);
+	return result;
+}

Copied: branches/samba/experimental/source3/rpc_client/cli_winreg_spoolss.h (from rev 3862, tags/samba/upstream_3.6.0~rc3/source3/rpc_client/cli_winreg_spoolss.h)
===================================================================
--- branches/samba/experimental/source3/rpc_client/cli_winreg_spoolss.h	                        (rev 0)
+++ branches/samba/experimental/source3/rpc_client/cli_winreg_spoolss.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -0,0 +1,569 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *
+ *  SPOOLSS RPC Pipe server / winreg client routines
+ *
+ *  Copyright (c) 2010      Andreas Schneider <asn at 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
+ *  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/>.
+ */
+
+#ifndef _RPC_CLIENT_CLI_WINREG_SPOOLSS_H_
+#define _RPC_CLIENT_CLI_WINREG_SPOOLSS_H_
+
+struct dcerpc_binding_handle;
+
+enum spoolss_PrinterInfo2Mask {
+	SPOOLSS_PRINTER_INFO_ATTRIBUTES      = (int)(0x00000001),
+	SPOOLSS_PRINTER_INFO_AVERAGEPPM      = (int)(0x00000002),
+	SPOOLSS_PRINTER_INFO_CJOBS           = (int)(0x00000004),
+	SPOOLSS_PRINTER_INFO_COMMENT         = (int)(0x00000008),
+	SPOOLSS_PRINTER_INFO_DATATYPE        = (int)(0x00000010),
+	SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY = (int)(0x00000020),
+	SPOOLSS_PRINTER_INFO_DEVMODE         = (int)(0x00000040),
+	SPOOLSS_PRINTER_INFO_DRIVERNAME      = (int)(0x00000080),
+	SPOOLSS_PRINTER_INFO_LOCATION        = (int)(0x00000100),
+	SPOOLSS_PRINTER_INFO_NAME            = (int)(0x00000200),
+	SPOOLSS_PRINTER_INFO_PARAMETERS      = (int)(0x00000400),
+	SPOOLSS_PRINTER_INFO_PORTNAME        = (int)(0x00000800),
+	SPOOLSS_PRINTER_INFO_PRINTERNAME     = (int)(0x00001000),
+	SPOOLSS_PRINTER_INFO_PRINTPROCESSOR  = (int)(0x00002000),
+	SPOOLSS_PRINTER_INFO_PRIORITY        = (int)(0x00004000),
+	SPOOLSS_PRINTER_INFO_SECDESC         = (int)(0x00008000),
+	SPOOLSS_PRINTER_INFO_SEPFILE         = (int)(0x00010000),
+	SPOOLSS_PRINTER_INFO_SERVERNAME      = (int)(0x00020000),
+	SPOOLSS_PRINTER_INFO_SHARENAME       = (int)(0x00040000),
+	SPOOLSS_PRINTER_INFO_STARTTIME       = (int)(0x00080000),
+	SPOOLSS_PRINTER_INFO_STATUS          = (int)(0x00100000),
+	SPOOLSS_PRINTER_INFO_UNTILTIME       = (int)(0x00200000)
+};
+
+#define SPOOLSS_PRINTER_INFO_ALL SPOOLSS_PRINTER_INFO_ATTRIBUTES      | \
+                                 SPOOLSS_PRINTER_INFO_AVERAGEPPM      | \
+                                 SPOOLSS_PRINTER_INFO_CJOBS           | \
+                                 SPOOLSS_PRINTER_INFO_COMMENT         | \
+                                 SPOOLSS_PRINTER_INFO_DATATYPE        | \
+                                 SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY | \
+                                 SPOOLSS_PRINTER_INFO_DEVMODE         | \
+                                 SPOOLSS_PRINTER_INFO_DRIVERNAME      | \
+                                 SPOOLSS_PRINTER_INFO_LOCATION        | \
+                                 SPOOLSS_PRINTER_INFO_NAME            | \
+                                 SPOOLSS_PRINTER_INFO_PARAMETERS      | \
+                                 SPOOLSS_PRINTER_INFO_PORTNAME        | \
+                                 SPOOLSS_PRINTER_INFO_PRINTERNAME     | \
+                                 SPOOLSS_PRINTER_INFO_PRINTPROCESSOR  | \
+                                 SPOOLSS_PRINTER_INFO_PRIORITY        | \
+                                 SPOOLSS_PRINTER_INFO_SECDESC         | \
+                                 SPOOLSS_PRINTER_INFO_SEPFILE         | \
+                                 SPOOLSS_PRINTER_INFO_SERVERNAME      | \
+                                 SPOOLSS_PRINTER_INFO_SHARENAME       | \
+                                 SPOOLSS_PRINTER_INFO_STARTTIME       | \
+                                 SPOOLSS_PRINTER_INFO_STATUS          | \
+                                 SPOOLSS_PRINTER_INFO_UNTILTIME
+
+WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
+			     struct dcerpc_binding_handle *b,
+			     const char *sharename);
+
+/**
+ * @internal
+ *
+ * @brief Update the information of a printer in the registry.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  sharename  The share name.
+ *
+ * @param[in]  info2_mask A bitmask which defines which values should be set.
+ *
+ * @param[in]  info2    A SetPrinterInfo2 structure with the data to set.
+ *
+ * @param[in]  devmode  A device mode structure with the data to set.
+ *
+ * @param[in]  secdesc  A security descriptor structure with the data to set.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
+			     struct dcerpc_binding_handle *b,
+			     const char *sharename,
+			     uint32_t info2_mask,
+			     struct spoolss_SetPrinterInfo2 *info2,
+			     struct spoolss_DeviceMode *devmode,
+			     struct security_descriptor *secdesc);
+
+
+/**
+ * @brief Get the inforamtion of a printer stored in the registry.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  printer  The name of the printer to get.
+ *
+ * @param[out] pinfo2   A pointer to store a PRINTER_INFO_2 structure.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
+			  struct dcerpc_binding_handle *b,
+			  const char *printer,
+			  struct spoolss_PrinterInfo2 **pinfo2);
+
+/**
+ * @brief Get the security descriptor for a printer.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  sharename  The share name.
+ *
+ * @param[out] psecdesc   A pointer to store the security descriptor.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
+				  struct dcerpc_binding_handle *b,
+				  const char *sharename,
+				  struct spoolss_security_descriptor **psecdesc);
+
+/**
+ * @brief Set the security descriptor for a printer.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  sharename  The share name.
+ *
+ * @param[in]  secdesc  The security descriptor to save.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
+				  struct dcerpc_binding_handle *b,
+				  const char *sharename,
+				  const struct spoolss_security_descriptor *secdesc);
+
+/**
+ * @internal
+ *
+ * @brief Set printer data over the winreg pipe.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  printer  The printer name.
+ *
+ * @param[in]  key      The key of the printer data to store the value.
+ *
+ * @param[in]  value    The value name to save.
+ *
+ * @param[in]  type     The type of the value to use.
+ *
+ * @param[in]  data     The data which sould be saved under the given value.
+ *
+ * @param[in]  data_size The size of the data.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
+				 struct dcerpc_binding_handle *b,
+				 const char *printer,
+				 const char *key,
+				 const char *value,
+				 enum winreg_Type type,
+				 uint8_t *data,
+				 uint32_t data_size);
+
+/**
+ * @internal
+ *
+ * @brief Get printer data over a winreg pipe.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  printer  The printer name.
+ *
+ * @param[in]  key      The key of the printer data to get the value.
+ *
+ * @param[in]  value    The name of the value to query.
+ *
+ * @param[in]  type     The type of the value to query.
+ *
+ * @param[out] data     A pointer to store the data.
+ *
+ * @param[out] data_size A pointer to store the size of the data.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
+				 struct dcerpc_binding_handle *b,
+				 const char *printer,
+				 const char *key,
+				 const char *value,
+				 enum winreg_Type *type,
+				 uint8_t **data,
+				 uint32_t *data_size);
+
+/**
+ * @internal
+ *
+ * @brief Enumerate on the values of a given key and provide the data.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  printer  The printer name.
+ *
+ * @param[in]  key      The key of the printer data to get the value.
+ *
+ * @param[out] pnum_values A pointer to store the number of values we found.
+ *
+ * @param[out] penum_values A pointer to store the values and its data.
+ *
+ * @return                   WERR_OK on success, the corresponding DOS error
+ *                           code if something gone wrong.
+ */
+WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
+				  struct dcerpc_binding_handle *b,
+				  const char *printer,
+				  const char *key,
+				  uint32_t *pnum_values,
+				  struct spoolss_PrinterEnumValues **penum_values);
+
+/**
+ * @internal
+ *
+ * @brief Delete printer data over a winreg pipe.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  printer  The printer name.
+ *
+ * @param[in]  key      The key of the printer data to delete.
+ *
+ * @param[in]  value    The name of the value to delete.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx,
+				    struct dcerpc_binding_handle *b,
+				    const char *printer,
+				    const char *key,
+				    const char *value);
+
+/**
+ * @internal
+ *
+ * @brief Enumerate on the subkeys of a given key and provide the data.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  printer  The printer name.
+ *
+ * @param[in]  key      The key of the printer data to get the value.
+ *
+ * @param[out] pnum_subkeys A pointer to store the number of subkeys found.
+ *
+ * @param[in]  psubkeys A pointer to an array to store the names of the subkeys
+ *                      found.
+ *
+ * @return              WERR_OK on success, the corresponding DOS error
+ *                      code if something gone wrong.
+ */
+WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
+			       struct dcerpc_binding_handle *b,
+			       const char *printer,
+			       const char *key,
+			       uint32_t *pnum_subkeys,
+			       const char ***psubkeys);
+
+/**
+ * @internal
+ *
+ * @brief Delete a key with subkeys of a given printer.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  printer  The printer name.
+ *
+ * @param[in]  key      The key of the printer to delete.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx,
+				 struct dcerpc_binding_handle *b,
+				 const char *printer,
+				 const char *key);
+
+/**
+ * @brief Update the ChangeID of a printer.
+ *
+ * The ChangeID **must** be increasing over the lifetime of client's spoolss
+ * service in order for the client's cache to show updates.
+ *
+ * If a form is updated of a printer, the we need to update the ChangeID of the
+ * pritner.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  printer  The printer name.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx,
+				      struct dcerpc_binding_handle *b,
+				      const char *printer);
+
+/**
+ * @brief Get the ChangeID of the given printer.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  printer  The printer name.
+ *
+ * @param[in]  changeid A pointer to store the changeid.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
+				   struct dcerpc_binding_handle *b,
+				   const char *printer,
+				   uint32_t *pchangeid);
+
+/**
+ * @internal
+ *
+ * @brief This function adds a form to the list of available forms that can be
+ * selected for the specified printer.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  form     The form to add.
+ *
+ * @return              WERR_OK on success.
+ *                      WERR_ALREADY_EXISTS if the form already exists or is a
+ *                                          builtin form.
+ *                      A corresponding DOS error is something went wrong.
+ */
+WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx,
+			       struct dcerpc_binding_handle *b,
+			       struct spoolss_AddFormInfo1 *form);
+
+/*
+ * @brief This function enumerates the forms supported by the specified printer.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[out] pnum_info A pointer to store the FormInfo count.
+ *
+ * @param[out] pinfo     A pointer to store an array with FormInfo.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
+				 struct dcerpc_binding_handle *b,
+				 uint32_t *pnum_info,
+				 union spoolss_FormInfo **pinfo);
+
+/**
+ * @brief This function removes a form name from the list of supported forms.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  form_name The name of the form to delete.
+ *
+ * @return              WERR_OK on success.
+ *                      WERR_INVALID_PARAM if the form is a builtin form.
+ *                      WERR_INVALID_FORM_NAME if the form or key doesn't exist.
+ *                      A corresponding DOS error is something went wrong.
+ */
+WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx,
+				  struct dcerpc_binding_handle *b,
+				  const char *form_name);
+
+/**
+ * @brief This function sets the form information for the specified printer.
+ *
+ * If one provides both the name in the API call and inside the FormInfo
+ * structure, then the form gets renamed.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  form_name The name of the form to set or rename.
+ *
+ * @param[in]  form     The FormInfo structure to save.
+ *
+ * @return              WERR_OK on success.
+ *                      WERR_INVALID_PARAM if the form is a builtin form.
+ *                      A corresponding DOS error is something went wrong.
+ */
+WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx,
+			       struct dcerpc_binding_handle *b,
+			       const char *form_name,
+			       struct spoolss_AddFormInfo1 *form);
+
+/**
+ * @brief This function retrieves information about a specified form.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  form_name The name of the form to query.
+ *
+ * @param[out] form     A pointer to a form structure to fill out.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
+			       struct dcerpc_binding_handle *b,
+			       const char *form_name,
+			       struct spoolss_FormInfo1 *form);
+
+/**
+ * @brief This function adds a new spool driver
+ *
+ * @param[in]  mem_ctx	       A talloc memory context.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  r	       The structure containing the new driver data.
+ *
+ * @param[out] driver_name     Returns the driver name.
+ *
+ * @param[out] driver_version  Returns the driver version.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_add_driver(TALLOC_CTX *mem_ctx,
+			 struct dcerpc_binding_handle *b,
+			 struct spoolss_AddDriverInfoCtr *r,
+			 const char **driver_name,
+			 uint32_t *driver_version);
+
+/**
+ * @brief This function gets printer driver information
+ *
+ * @param[in]  mem_ctx	       A talloc memory context.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  architecture    The architecture type.
+ *
+ * @param[in]  driver_name     The driver name.
+ *
+ * @param[in]  driver_version  The driver version.
+ *
+ * @param[out] _info8   The structure that holds the full driver information.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+
+WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
+			 struct dcerpc_binding_handle *b,
+			 const char *architecture,
+			 const char *driver_name,
+			 uint32_t driver_version,
+			 struct spoolss_DriverInfo8 **_info8);
+
+/**
+ * @brief This function deletes a printer driver information
+ *
+ * @param[in]  mem_ctx	       A talloc memory context.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[out] info8    The structure that holds the full driver information.
+ *
+ * @param[in]  version  The driver type version.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+
+WERROR winreg_del_driver(TALLOC_CTX *mem_ctx,
+			 struct dcerpc_binding_handle *b,
+			 struct spoolss_DriverInfo8 *info8,
+			 uint32_t version);
+
+/**
+ * @brief This function gets printer drivers list for the specified
+ *        architecture and type version
+ *
+ * @param[in]  mem_ctx	       A talloc memory context.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  architecture    The architecture type.
+ *
+ * @param[in]  version         The driver version.
+ *
+ * @param[out] num_drivers     The number of drivers.
+ *
+ * @param[out] version         The drivers names.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+
+WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
+			      struct dcerpc_binding_handle *b,
+			      const char *architecture,
+			      uint32_t version,
+			      uint32_t *num_drivers,
+			      const char ***drivers);
+
+#endif /* _RPC_CLIENT_CLI_WINREG_SPOOLSS_H_ */

Modified: branches/samba/experimental/source3/rpc_client/init_lsa.h
===================================================================
--- branches/samba/experimental/source3/rpc_client/init_lsa.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_client/init_lsa.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Guenther Deschner                  2008.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 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/>.
+ */
+
+#ifndef _RPC_CLIENT_INIT_LSA_H_
+#define _RPC_CLIENT_INIT_LSA_H_
+
 struct lsa_String;
 struct lsa_StringLarge;
 struct lsa_AsciiString;
@@ -9,3 +31,5 @@
 void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s);
 void init_lsa_AsciiString(struct lsa_AsciiString *name, const char *s);
 void init_lsa_AsciiStringLarge(struct lsa_AsciiStringLarge *name, const char *s);
+
+#endif /* _RPC_CLIENT_INIT_LSA_H_ */

Modified: branches/samba/experimental/source3/rpc_client/init_netlogon.h
===================================================================
--- branches/samba/experimental/source3/rpc_client/init_netlogon.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_client/init_netlogon.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Guenther Deschner                  2008.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 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/>.
+ */
+
+#ifndef _RPC_CLIENT_INIT_NETLOGON_H_
+#define _RPC_CLIENT_INIT_NETLOGON_H_
+
 /* The following definitions come from rpc_client/init_netlogon.c  */
 
 void init_netr_CryptPassword(const char *pwd,
@@ -3,2 +25,4 @@
 			     unsigned char session_key[16],
 			     struct netr_CryptPassword *pwd_buf);
+
+#endif /* _RPC_CLIENT_INIT_NETLOGON_H_ */

Modified: branches/samba/experimental/source3/rpc_client/init_samr.h
===================================================================
--- branches/samba/experimental/source3/rpc_client/init_samr.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_client/init_samr.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Guenther Deschner                  2008.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 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/>.
+ */
+
+#ifndef _RPC_CLIENT_INIT_SAMR_H_
+#define _RPC_CLIENT_INIT_SAMR_H_
+
 /* The following definitions come from rpc_client/init_samr.c  */
 
 void init_samr_CryptPasswordEx(const char *pwd,
@@ -7,3 +29,4 @@
 			     DATA_BLOB *session_key,
 			     struct samr_CryptPassword *pwd_buf);
 
+#endif /* _RPC_CLIENT_INIT_SAMR_H_ */

Modified: branches/samba/experimental/source3/rpc_client/init_spoolss.c
===================================================================
--- branches/samba/experimental/source3/rpc_client/init_spoolss.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_client/init_spoolss.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -20,6 +20,9 @@
 #include "includes.h"
 #include "../librpc/gen_ndr/ndr_spoolss.h"
 #include "rpc_client/init_spoolss.h"
+#include "../libcli/security/security.h"
+#include "secrets.h"
+#include "passdb/machine_sid.h"
 
 /*******************************************************************
 ********************************************************************/
@@ -119,3 +122,264 @@
 	s->cjobs		= i->cjobs;
 	s->averageppm		= i->averageppm;
 }
+
+/****************************************************************************
+****************************************************************************/
+
+bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
+			      struct spoolss_DriverInfo8 *_info8)
+{
+	struct spoolss_DriverInfo8 info8;
+
+	ZERO_STRUCT(info8);
+
+	switch (r->level) {
+	case 3:
+		info8.version		= r->info.info3->version;
+		info8.driver_name	= r->info.info3->driver_name;
+		info8.architecture	= r->info.info3->architecture;
+		info8.driver_path	= r->info.info3->driver_path;
+		info8.data_file		= r->info.info3->data_file;
+		info8.config_file	= r->info.info3->config_file;
+		info8.help_file		= r->info.info3->help_file;
+		info8.monitor_name	= r->info.info3->monitor_name;
+		info8.default_datatype	= r->info.info3->default_datatype;
+		if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
+			info8.dependent_files	= r->info.info3->dependent_files->string;
+		}
+		break;
+	case 6:
+		info8.version		= r->info.info6->version;
+		info8.driver_name	= r->info.info6->driver_name;
+		info8.architecture	= r->info.info6->architecture;
+		info8.driver_path	= r->info.info6->driver_path;
+		info8.data_file		= r->info.info6->data_file;
+		info8.config_file	= r->info.info6->config_file;
+		info8.help_file		= r->info.info6->help_file;
+		info8.monitor_name	= r->info.info6->monitor_name;
+		info8.default_datatype	= r->info.info6->default_datatype;
+		if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
+			info8.dependent_files	= r->info.info6->dependent_files->string;
+		}
+		info8.driver_date	= r->info.info6->driver_date;
+		info8.driver_version	= r->info.info6->driver_version;
+		info8.manufacturer_name = r->info.info6->manufacturer_name;
+		info8.manufacturer_url	= r->info.info6->manufacturer_url;
+		info8.hardware_id	= r->info.info6->hardware_id;
+		info8.provider		= r->info.info6->provider;
+		break;
+	case 8:
+		info8.version		= r->info.info8->version;
+		info8.driver_name	= r->info.info8->driver_name;
+		info8.architecture	= r->info.info8->architecture;
+		info8.driver_path	= r->info.info8->driver_path;
+		info8.data_file		= r->info.info8->data_file;
+		info8.config_file	= r->info.info8->config_file;
+		info8.help_file		= r->info.info8->help_file;
+		info8.monitor_name	= r->info.info8->monitor_name;
+		info8.default_datatype	= r->info.info8->default_datatype;
+		if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
+			info8.dependent_files	= r->info.info8->dependent_files->string;
+		}
+		if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
+			info8.previous_names	= r->info.info8->previous_names->string;
+		}
+		info8.driver_date	= r->info.info8->driver_date;
+		info8.driver_version	= r->info.info8->driver_version;
+		info8.manufacturer_name = r->info.info8->manufacturer_name;
+		info8.manufacturer_url	= r->info.info8->manufacturer_url;
+		info8.hardware_id	= r->info.info8->hardware_id;
+		info8.provider		= r->info.info8->provider;
+		info8.print_processor	= r->info.info8->print_processor;
+		info8.vendor_setup	= r->info.info8->vendor_setup;
+		if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
+			info8.color_profiles = r->info.info8->color_profiles->string;
+		}
+		info8.inf_path		= r->info.info8->inf_path;
+		info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
+		if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
+			info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
+		}
+		info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
+		info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
+		break;
+	default:
+		return false;
+	}
+
+	*_info8 = info8;
+
+	return true;
+}
+
+/****************************************************************************
+ Create and allocate a default devicemode.
+****************************************************************************/
+
+WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
+				      const char *devicename,
+				      struct spoolss_DeviceMode **devmode)
+{
+	struct spoolss_DeviceMode *dm;
+	char *dname;
+
+	dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
+	if (dm == NULL) {
+		return WERR_NOMEM;
+	}
+
+	dname = talloc_asprintf(dm, "%s", devicename);
+	if (dname == NULL) {
+		return WERR_NOMEM;
+	}
+	if (strlen(dname) > MAXDEVICENAME) {
+		dname[MAXDEVICENAME] = '\0';
+	}
+	dm->devicename = dname;
+
+	dm->formname = talloc_strdup(dm, "Letter");
+	if (dm->formname == NULL) {
+		return WERR_NOMEM;
+	}
+
+	dm->specversion          = DMSPEC_NT4_AND_ABOVE;
+	dm->driverversion        = 0x0400;
+	dm->size                 = 0x00DC;
+	dm->__driverextra_length = 0;
+	dm->fields               = DEVMODE_FORMNAME |
+				   DEVMODE_TTOPTION |
+				   DEVMODE_PRINTQUALITY |
+				   DEVMODE_DEFAULTSOURCE |
+				   DEVMODE_COPIES |
+				   DEVMODE_SCALE |
+				   DEVMODE_PAPERSIZE |
+				   DEVMODE_ORIENTATION;
+	dm->orientation          = DMORIENT_PORTRAIT;
+	dm->papersize            = DMPAPER_LETTER;
+	dm->paperlength          = 0;
+	dm->paperwidth           = 0;
+	dm->scale                = 0x64;
+	dm->copies               = 1;
+	dm->defaultsource        = DMBIN_FORMSOURCE;
+	dm->printquality         = DMRES_HIGH;           /* 0x0258 */
+	dm->color                = DMRES_MONOCHROME;
+	dm->duplex               = DMDUP_SIMPLEX;
+	dm->yresolution          = 0;
+	dm->ttoption             = DMTT_SUBDEV;
+	dm->collate              = DMCOLLATE_FALSE;
+	dm->icmmethod            = 0;
+	dm->icmintent            = 0;
+	dm->mediatype            = 0;
+	dm->dithertype           = 0;
+
+	dm->logpixels            = 0;
+	dm->bitsperpel           = 0;
+	dm->pelswidth            = 0;
+	dm->pelsheight           = 0;
+	dm->displayflags         = 0;
+	dm->displayfrequency     = 0;
+	dm->reserved1            = 0;
+	dm->reserved2            = 0;
+	dm->panningwidth         = 0;
+	dm->panningheight        = 0;
+
+	dm->driverextra_data.data = NULL;
+	dm->driverextra_data.length = 0;
+
+        *devmode = dm;
+	return WERR_OK;
+}
+
+WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
+				      struct spoolss_security_descriptor **secdesc)
+{
+	struct security_ace ace[7];	/* max number of ace entries */
+	int i = 0;
+	uint32_t sa;
+	struct security_acl *psa = NULL;
+	struct security_descriptor *psd = NULL;
+	struct dom_sid adm_sid;
+	size_t sd_size;
+
+	/* Create an ACE where Everyone is allowed to print */
+
+	sa = PRINTER_ACE_PRINT;
+	init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
+		     sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+
+	/* Add the domain admins group if we are a DC */
+
+	if ( IS_DC ) {
+		struct dom_sid domadmins_sid;
+
+		sid_compose(&domadmins_sid, get_global_sam_sid(),
+			    DOMAIN_RID_ADMINS);
+
+		sa = PRINTER_ACE_FULL_CONTROL;
+		init_sec_ace(&ace[i++], &domadmins_sid,
+			SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
+			SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
+		init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+			sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+	}
+	else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
+		sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
+
+		sa = PRINTER_ACE_FULL_CONTROL;
+		init_sec_ace(&ace[i++], &adm_sid,
+			SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
+			SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
+		init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+			sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+	}
+
+	/* add BUILTIN\Administrators as FULL CONTROL */
+
+	sa = PRINTER_ACE_FULL_CONTROL;
+	init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
+		SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
+		SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
+	init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
+		SEC_ACE_TYPE_ACCESS_ALLOWED,
+		sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+
+	/* add BUILTIN\Print Operators as FULL CONTROL */
+
+	sa = PRINTER_ACE_FULL_CONTROL;
+	init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
+		SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
+		SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
+	init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
+		SEC_ACE_TYPE_ACCESS_ALLOWED,
+		sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+
+	/* Make the security descriptor owned by the BUILTIN\Administrators */
+
+	/* The ACL revision number in rpc_secdesc.h differs from the one
+	   created by NT when setting ACE entries in printer
+	   descriptors.  NT4 complains about the property being edited by a
+	   NT5 machine. */
+
+	if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
+		psd = make_sec_desc(mem_ctx,
+				    SD_REVISION,
+				    SEC_DESC_SELF_RELATIVE,
+				    &global_sid_Builtin_Administrators,
+				    &global_sid_Builtin_Administrators,
+				    NULL,
+				    psa,
+				    &sd_size);
+	}
+
+	if (psd == NULL) {
+		DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
+		return WERR_NOMEM;
+	}
+
+	DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
+		 (unsigned int)sd_size));
+
+	*secdesc = psd;
+
+	return WERR_OK;
+}

Modified: branches/samba/experimental/source3/rpc_client/init_spoolss.h
===================================================================
--- branches/samba/experimental/source3/rpc_client/init_spoolss.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_client/init_spoolss.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,4 +1,25 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  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
+ *  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/>.
+ */
 
+#ifndef _RPC_CLIENT_INIT_SPOOLSS_H_
+#define _RPC_CLIENT_INIT_SPOOLSS_H_
+
 /* The following definitions come from rpc_client/init_spoolss.c  */
 
 bool init_systemtime(struct spoolss_Time *r,
@@ -13,4 +34,14 @@
 				union spoolss_PrinterData *data);
 void spoolss_printerinfo2_to_setprinterinfo2(const struct spoolss_PrinterInfo2 *i,
 					     struct spoolss_SetPrinterInfo2 *s);
+bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
+			      struct spoolss_DriverInfo8 *_info8);
 
+WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
+				      const char *devicename,
+				      struct spoolss_DeviceMode **devmode);
+
+WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
+				      struct spoolss_security_descriptor **secdesc);
+
+#endif /* _RPC_CLIENT_INIT_SPOOLSS_H_ */

Modified: branches/samba/experimental/source3/rpc_client/util_netlogon.h
===================================================================
--- branches/samba/experimental/source3/rpc_client/util_netlogon.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_client/util_netlogon.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,25 @@
+/*
+   Unix SMB/CIFS implementation.
+   Authentication utility functions
+   Copyright (C) Volker Lendecke 2010
+
+   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/>.
+*/
+
+#ifndef _RPC_CLIENT_UTIL_NETLOGON_H_
+#define _RPC_CLIENT_UTIL_NETLOGON_H_
+
 /* The following definitions come from rpc_client/util_netlogon.c  */
 
 NTSTATUS copy_netr_SamBaseInfo(TALLOC_CTX *mem_ctx,
@@ -3,2 +25,4 @@
 			       const struct netr_SamBaseInfo *in,
 			       struct netr_SamBaseInfo *out);
+
+#endif /* _RPC_CLIENT_UTIL_NETLOGON_H_ */

Modified: branches/samba/experimental/source3/rpc_server/dcesrv_gssapi.c
===================================================================
--- branches/samba/experimental/source3/rpc_server/dcesrv_gssapi.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_server/dcesrv_gssapi.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -105,7 +105,6 @@
 				     struct auth_serversupplied_info **server_info)
 {
 	TALLOC_CTX *tmp_ctx;
-	DATA_BLOB auth_data;
 	DATA_BLOB pac;
 	struct PAC_DATA *pac_data;
 	struct PAC_LOGON_INFO *logon_info = NULL;
@@ -135,6 +134,11 @@
 		goto done;
 	}
 
+	status = gse_get_client_name(gse_ctx, tmp_ctx, &princ_name);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto done;
+	}
+
 	pac_data = talloc_zero(tmp_ctx, struct PAC_DATA);
 	if (!pac_data) {
 		status = NT_STATUS_NO_MEMORY;

Modified: branches/samba/experimental/source3/rpc_server/rpc_ep_setup.c
===================================================================
--- branches/samba/experimental/source3/rpc_server/rpc_ep_setup.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_server/rpc_ep_setup.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -39,7 +39,7 @@
 #include "../librpc/gen_ndr/srv_svcctl.h"
 #include "../librpc/gen_ndr/srv_wkssvc.h"
 
-#include "printing/nt_printing_migrate.h"
+#include "printing/nt_printing_migrate_internal.h"
 #include "rpc_server/eventlog/srv_eventlog_reg.h"
 #include "rpc_server/svcctl/srv_svcctl_reg.h"
 #include "rpc_server/spoolss/srv_spoolss_nt.h"

Modified: branches/samba/experimental/source3/rpc_server/spoolss/srv_spoolss_nt.c
===================================================================
--- branches/samba/experimental/source3/rpc_server/spoolss/srv_spoolss_nt.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_server/spoolss/srv_spoolss_nt.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -53,6 +53,7 @@
 #include "util_tdb.h"
 #include "libsmb/libsmb.h"
 #include "printing/printer_list.h"
+#include "rpc_client/cli_winreg_spoolss.h"
 
 /* macros stolen from s4 spoolss server */
 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
@@ -463,7 +464,7 @@
 	/* this does not need a become root since the access check has been
 	   done on the handle already */
 
-	result = winreg_delete_printer_key(p->mem_ctx,
+	result = winreg_delete_printer_key_internal(p->mem_ctx,
 					   get_session_info_system(),
 					   p->msg_ctx,
 					   Printer->sharename,
@@ -685,7 +686,7 @@
 			continue;
 		}
 
-		result = winreg_get_printer(mem_ctx,
+		result = winreg_get_printer_internal(mem_ctx,
 					    session_info,
 					    msg_ctx,
 					    sname,
@@ -1540,6 +1541,7 @@
 	const char *drivername;
 	int snum;
 	int n_services = lp_numservices();
+	struct dcerpc_binding_handle *b = NULL;
 
 	tmp_ctx = talloc_new(NULL);
 	if (!tmp_ctx) return;
@@ -1572,7 +1574,17 @@
 			continue;
 		}
 
-		result = winreg_get_printer(tmp_ctx, session_info, msg,
+		if (b == NULL) {
+			result = winreg_printer_binding_handle(tmp_ctx,
+							       session_info,
+							       msg,
+							       &b);
+			if (!W_ERROR_IS_OK(result)) {
+				break;
+			}
+		}
+
+		result = winreg_get_printer(tmp_ctx, b,
 					    lp_const_servicename(snum),
 					    &pinfo2);
 
@@ -1591,9 +1603,7 @@
 		DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
 
 		/* all we care about currently is the change_id */
-		result = winreg_printer_update_changeid(tmp_ctx,
-							session_info,
-							msg,
+		result = winreg_printer_update_changeid(tmp_ctx, b,
 							pinfo2->printername);
 
 		if (!W_ERROR_IS_OK(result)) {
@@ -1911,7 +1921,7 @@
 		DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
 			? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
 
-		winreg_create_printer(p->mem_ctx,
+		winreg_create_printer_internal(p->mem_ctx,
 				      get_session_info_system(),
 				      p->msg_ctx,
 				      lp_const_servicename(snum));
@@ -2002,7 +2012,7 @@
 	}
 
 	if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
-		winreg_delete_printer_key(p->mem_ctx,
+		winreg_delete_printer_key_internal(p->mem_ctx,
 					  get_session_info_system(),
 					  p->msg_ctx,
 					  lp_const_servicename(snum),
@@ -2056,6 +2066,7 @@
 	struct spoolss_DriverInfo8 *info_win2k = NULL;
 	int				version;
 	WERROR				status;
+	struct dcerpc_binding_handle *b;
 
 	/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
 	   and not a printer admin, then fail */
@@ -2077,9 +2088,15 @@
 	if ((version = get_version_id(r->in.architecture)) == -1)
 		return WERR_INVALID_ENVIRONMENT;
 
-	status = winreg_get_driver(p->mem_ctx,
-				   get_session_info_system(),
-				   p->msg_ctx,
+	status = winreg_printer_binding_handle(p->mem_ctx,
+					       get_session_info_system(),
+					       p->msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(status)) {
+		return status;
+	}
+
+	status = winreg_get_driver(p->mem_ctx, b,
 				   r->in.architecture, r->in.driver,
 				   version, &info);
 	if (!W_ERROR_IS_OK(status)) {
@@ -2088,9 +2105,7 @@
 		if ( version == 2 ) {
 			version = 3;
 
-			status = winreg_get_driver(p->mem_ctx,
-						   get_session_info_system(),
-						   p->msg_ctx,
+			status = winreg_get_driver(p->mem_ctx, b,
 						   r->in.architecture,
 						   r->in.driver,
 						   version, &info);
@@ -2116,18 +2131,14 @@
 	}
 
 	if (version == 2) {
-		status = winreg_get_driver(p->mem_ctx,
-					   get_session_info_system(),
-					   p->msg_ctx,
+		status = winreg_get_driver(p->mem_ctx, b,
 					   r->in.architecture,
 					   r->in.driver, 3, &info_win2k);
 		if (W_ERROR_IS_OK(status)) {
 			/* if we get to here, we now have 2 driver info structures to remove */
 			/* remove the Win2k driver first*/
 
-			status = winreg_del_driver(p->mem_ctx,
-						   get_session_info_system(),
-						   p->msg_ctx,
+			status = winreg_del_driver(p->mem_ctx, b,
 						   info_win2k, 3);
 			talloc_free(info_win2k);
 
@@ -2138,9 +2149,7 @@
 		}
 	}
 
-	status = winreg_del_driver(p->mem_ctx,
-				   get_session_info_system(),
-				   p->msg_ctx,
+	status = winreg_del_driver(p->mem_ctx, b,
 				   info, version);
 
 done:
@@ -2161,6 +2170,7 @@
 	int				version;
 	bool				delete_files;
 	WERROR				status;
+	struct dcerpc_binding_handle *b;
 
 	/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
 	   and not a printer admin, then fail */
@@ -2185,9 +2195,15 @@
 	if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
 		version = r->in.version;
 
-	status = winreg_get_driver(p->mem_ctx,
-				   get_session_info_system(),
-				   p->msg_ctx,
+	status = winreg_printer_binding_handle(p->mem_ctx,
+					       get_session_info_system(),
+					       p->msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(status)) {
+		return status;
+	}
+
+	status = winreg_get_driver(p->mem_ctx, b,
 				   r->in.architecture,
 				   r->in.driver,
 				   version,
@@ -2207,9 +2223,7 @@
 		/* try for Win2k driver if "Windows NT x86" */
 
 		version = 3;
-		status = winreg_get_driver(info,
-					   get_session_info_system(),
-					   p->msg_ctx,
+		status = winreg_get_driver(info, b,
 					   r->in.architecture,
 					   r->in.driver,
 					   version, &info);
@@ -2258,9 +2272,7 @@
 	/* also check for W32X86/3 if necessary; maybe we already have? */
 
 	if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION)  ) {
-		status = winreg_get_driver(info,
-					   get_session_info_system(),
-					   p->msg_ctx,
+		status = winreg_get_driver(info, b,
 					   r->in.architecture,
 					   r->in.driver, 3, &info_win2k);
 		if (W_ERROR_IS_OK(status)) {
@@ -2280,9 +2292,7 @@
 			/* if we get to here, we now have 2 driver info structures to remove */
 			/* remove the Win2k driver first*/
 
-			status = winreg_del_driver(info,
-						   get_session_info_system(),
-						   p->msg_ctx,
+			status = winreg_del_driver(info, b,
 						   info_win2k,
 						   3);
 
@@ -2304,9 +2314,7 @@
 		}
 	}
 
-	status = winreg_del_driver(info,
-				   get_session_info_system(),
-				   p->msg_ctx,
+	status = winreg_del_driver(info, b,
 				   info,
 				   version);
 	if (!W_ERROR_IS_OK(status)) {
@@ -3591,7 +3599,7 @@
 			}
 
 			/* Maybe we should use the SYSTEM session_info here... */
-			result = winreg_get_printer(mem_ctx,
+			result = winreg_get_printer_internal(mem_ctx,
 						    get_session_info_system(),
 						    p->msg_ctx,
 						    lp_servicename(snum),
@@ -3679,7 +3687,7 @@
 	}
 
 	/* Maybe we should use the SYSTEM session_info here... */
-	result = winreg_get_printer(mem_ctx,
+	result = winreg_get_printer_internal(mem_ctx,
 				    get_session_info_system(),
 				    p->msg_ctx,
 				    lp_servicename(snum), &pinfo2);
@@ -3928,7 +3936,7 @@
 	r->high_part_total_bytes	= 0x0;
 
 	/* ChangeID in milliseconds*/
-	winreg_printer_get_changeid(mem_ctx, session_info, msg_ctx,
+	winreg_printer_get_changeid_internal(mem_ctx, session_info, msg_ctx,
 				    info2->sharename, &r->change_id);
 
 	r->last_error			= WERR_OK;
@@ -4281,6 +4289,7 @@
 	union spoolss_PrinterInfo *info = NULL;
 	uint32_t count = 0;
 	WERROR result = WERR_OK;
+	struct dcerpc_binding_handle *b = NULL;
 
 	*count_p = 0;
 	*info_p = NULL;
@@ -4299,9 +4308,17 @@
 		DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
 			printer, snum));
 
-		result = winreg_create_printer(mem_ctx,
-					       session_info,
-					       msg_ctx,
+		if (b == NULL) {
+			result = winreg_printer_binding_handle(mem_ctx,
+							       session_info,
+							       msg_ctx,
+							       &b);
+			if (!W_ERROR_IS_OK(result)) {
+				goto out;
+			}
+		}
+
+		result = winreg_create_printer(mem_ctx, b,
 					       printer);
 		if (!W_ERROR_IS_OK(result)) {
 			goto out;
@@ -4315,7 +4332,7 @@
 			goto out;
 		}
 
-		result = winreg_get_printer(mem_ctx, session_info, msg_ctx,
+		result = winreg_get_printer(mem_ctx, b,
 					    printer, &info2);
 		if (!W_ERROR_IS_OK(result)) {
 			goto out;
@@ -4732,7 +4749,7 @@
 		return WERR_BADFID;
 	}
 
-	result = winreg_get_printer(p->mem_ctx,
+	result = winreg_get_printer_internal(p->mem_ctx,
 				    get_session_info_system(),
 				    p->msg_ctx,
 				    lp_const_servicename(snum),
@@ -5505,14 +5522,21 @@
 	struct spoolss_PrinterInfo2 *pinfo2 = NULL;
 	struct spoolss_DriverInfo8 *driver;
 	WERROR result;
+	struct dcerpc_binding_handle *b;
 
 	if (level == 101) {
 		return WERR_UNKNOWN_LEVEL;
 	}
 
-	result = winreg_get_printer(mem_ctx,
-				    session_info,
-				    msg_ctx,
+	result = winreg_printer_binding_handle(mem_ctx,
+					       session_info,
+					       msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(result)) {
+		return result;
+	}
+
+	result = winreg_get_printer(mem_ctx, b,
 				    lp_const_servicename(snum),
 				    &pinfo2);
 
@@ -5523,7 +5547,7 @@
 		return WERR_INVALID_PRINTER_NAME;
 	}
 
-	result = winreg_get_driver(mem_ctx, session_info, msg_ctx,
+	result = winreg_get_driver(mem_ctx, b,
 				   architecture,
 				   pinfo2->drivername, version, &driver);
 
@@ -5542,7 +5566,7 @@
 
 		/* Yes - try again with a WinNT driver. */
 		version = 2;
-		result = winreg_get_driver(mem_ctx, session_info, msg_ctx,
+		result = winreg_get_driver(mem_ctx, b,
 					   architecture,
 					   pinfo2->drivername,
 					   version, &driver);
@@ -5926,8 +5950,8 @@
 	const char *printer;
 	WERROR result;
 	int snum;
-
 	struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
+	struct dcerpc_binding_handle *b;
 
 	if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
 		DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
@@ -5955,15 +5979,21 @@
 		goto done;
 	}
 
+	result = winreg_printer_binding_handle(p->mem_ctx,
+					       get_session_info_system(),
+					       p->msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
 	/* NT seems to like setting the security descriptor even though
 	   nothing may have actually changed. */
-	result = winreg_get_printer_secdesc(p->mem_ctx,
-					    get_session_info_system(),
-					    p->msg_ctx,
+	result = winreg_get_printer_secdesc(p->mem_ctx, b,
 					    printer,
 					    &old_secdesc);
 	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
+		DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc_internal() failed\n"));
 		result = WERR_BADFID;
 		goto done;
 	}
@@ -6009,9 +6039,7 @@
 		goto done;
 	}
 
-	result = winreg_set_printer_secdesc(p->mem_ctx,
-					    get_session_info_system(),
-					    p->msg_ctx,
+	result = winreg_set_printer_secdesc(p->mem_ctx, b,
 					    printer,
 					    new_secdesc);
 
@@ -6217,12 +6245,19 @@
 	const char *spooling;
 	DATA_BLOB buffer;
 	WERROR result = WERR_OK;
+	struct dcerpc_binding_handle *b;
 
+	result = winreg_printer_binding_handle(mem_ctx,
+					       session_info,
+					       msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(result)) {
+		return result;
+	}
+
 	if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
 		push_reg_sz(mem_ctx, &buffer, printer->drivername);
-		winreg_set_printer_dataex(mem_ctx,
-					  session_info,
-					  msg_ctx,
+		winreg_set_printer_dataex(mem_ctx, b,
 					  printer->sharename,
 					  SPOOL_DSSPOOLER_KEY,
 					  SPOOL_REG_DRIVERNAME,
@@ -6242,9 +6277,7 @@
 
 	if (force_update || !strequal(printer->comment, old_printer->comment)) {
 		push_reg_sz(mem_ctx, &buffer, printer->comment);
-		winreg_set_printer_dataex(mem_ctx,
-					  session_info,
-					  msg_ctx,
+		winreg_set_printer_dataex(mem_ctx, b,
 					  printer->sharename,
 					  SPOOL_DSSPOOLER_KEY,
 					  SPOOL_REG_DESCRIPTION,
@@ -6261,9 +6294,7 @@
 
 	if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
 		push_reg_sz(mem_ctx, &buffer, printer->sharename);
-		winreg_set_printer_dataex(mem_ctx,
-					  session_info,
-					  msg_ctx,
+		winreg_set_printer_dataex(mem_ctx, b,
 					  printer->sharename,
 					  SPOOL_DSSPOOLER_KEY,
 					  SPOOL_REG_PRINTSHARENAME,
@@ -6290,9 +6321,7 @@
 		}
 
 		push_reg_sz(mem_ctx, &buffer, p);
-		winreg_set_printer_dataex(mem_ctx,
-					  session_info,
-					  msg_ctx,
+		winreg_set_printer_dataex(mem_ctx, b,
 					  printer->sharename,
 					  SPOOL_DSSPOOLER_KEY,
 					  SPOOL_REG_PRINTERNAME,
@@ -6308,9 +6337,7 @@
 
 	if (force_update || !strequal(printer->portname, old_printer->portname)) {
 		push_reg_sz(mem_ctx, &buffer, printer->portname);
-		winreg_set_printer_dataex(mem_ctx,
-					  session_info,
-					  msg_ctx,
+		winreg_set_printer_dataex(mem_ctx, b,
 					  printer->sharename,
 					  SPOOL_DSSPOOLER_KEY,
 					  SPOOL_REG_PORTNAME,
@@ -6327,9 +6354,7 @@
 
 	if (force_update || !strequal(printer->location, old_printer->location)) {
 		push_reg_sz(mem_ctx, &buffer, printer->location);
-		winreg_set_printer_dataex(mem_ctx,
-					  session_info,
-					  msg_ctx,
+		winreg_set_printer_dataex(mem_ctx, b,
 					  printer->sharename,
 					  SPOOL_DSSPOOLER_KEY,
 					  SPOOL_REG_LOCATION,
@@ -6347,9 +6372,7 @@
 
 	if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
 		push_reg_sz(mem_ctx, &buffer, printer->sepfile);
-		winreg_set_printer_dataex(mem_ctx,
-					  session_info,
-					  msg_ctx,
+		winreg_set_printer_dataex(mem_ctx, b,
 					  printer->sharename,
 					  SPOOL_DSSPOOLER_KEY,
 					  SPOOL_REG_PRINTSEPARATORFILE,
@@ -6368,9 +6391,7 @@
 	if (force_update || printer->starttime != old_printer->starttime) {
 		buffer = data_blob_talloc(mem_ctx, NULL, 4);
 		SIVAL(buffer.data, 0, printer->starttime);
-		winreg_set_printer_dataex(mem_ctx,
-					  session_info,
-					  msg_ctx,
+		winreg_set_printer_dataex(mem_ctx, b,
 					  printer->sharename,
 					  SPOOL_DSSPOOLER_KEY,
 					  SPOOL_REG_PRINTSTARTTIME,
@@ -6382,9 +6403,7 @@
 	if (force_update || printer->untiltime != old_printer->untiltime) {
 		buffer = data_blob_talloc(mem_ctx, NULL, 4);
 		SIVAL(buffer.data, 0, printer->untiltime);
-		winreg_set_printer_dataex(mem_ctx,
-					  session_info,
-					  msg_ctx,
+		winreg_set_printer_dataex(mem_ctx, b,
 					  printer->sharename,
 					  SPOOL_DSSPOOLER_KEY,
 					  SPOOL_REG_PRINTENDTIME,
@@ -6396,9 +6415,7 @@
 	if (force_update || printer->priority != old_printer->priority) {
 		buffer = data_blob_talloc(mem_ctx, NULL, 4);
 		SIVAL(buffer.data, 0, printer->priority);
-		winreg_set_printer_dataex(mem_ctx,
-					  session_info,
-					  msg_ctx,
+		winreg_set_printer_dataex(mem_ctx, b,
 					  printer->sharename,
 					  SPOOL_DSSPOOLER_KEY,
 					  SPOOL_REG_PRIORITY,
@@ -6411,9 +6428,7 @@
 		buffer = data_blob_talloc(mem_ctx, NULL, 4);
 		SIVAL(buffer.data, 0, (printer->attributes &
 				       PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
-		winreg_set_printer_dataex(mem_ctx,
-					  session_info,
-					  msg_ctx,
+		winreg_set_printer_dataex(mem_ctx, b,
 					  printer->sharename,
 					  SPOOL_DSSPOOLER_KEY,
 					  SPOOL_REG_PRINTKEEPPRINTEDJOBS,
@@ -6435,9 +6450,7 @@
 				spooling = "unknown";
 		}
 		push_reg_sz(mem_ctx, &buffer, spooling);
-		winreg_set_printer_dataex(mem_ctx,
-					  session_info,
-					  msg_ctx,
+		winreg_set_printer_dataex(mem_ctx, b,
 					  printer->sharename,
 					  SPOOL_DSSPOOLER_KEY,
 					  SPOOL_REG_PRINTSPOOLING,
@@ -6447,9 +6460,7 @@
 	}
 
 	push_reg_sz(mem_ctx, &buffer, global_myname());
-	winreg_set_printer_dataex(mem_ctx,
-				  session_info,
-				  msg_ctx,
+	winreg_set_printer_dataex(mem_ctx, b,
 				  printer->sharename,
 				  SPOOL_DSSPOOLER_KEY,
 				  SPOOL_REG_SHORTSERVERNAME,
@@ -6469,9 +6480,7 @@
 	}
 
 	push_reg_sz(mem_ctx, &buffer, longname);
-	winreg_set_printer_dataex(mem_ctx,
-				  session_info,
-				  msg_ctx,
+	winreg_set_printer_dataex(mem_ctx, b,
 				  printer->sharename,
 				  SPOOL_DSSPOOLER_KEY,
 				  SPOOL_REG_SERVERNAME,
@@ -6482,9 +6491,7 @@
 	uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
 				  global_myname(), printer->sharename);
 	push_reg_sz(mem_ctx, &buffer, uncname);
-	winreg_set_printer_dataex(mem_ctx,
-				  session_info,
-				  msg_ctx,
+	winreg_set_printer_dataex(mem_ctx, b,
 				  printer->sharename,
 				  SPOOL_DSSPOOLER_KEY,
 				  SPOOL_REG_UNCNAME,
@@ -6513,6 +6520,7 @@
 	int snum;
 	WERROR result = WERR_OK;
 	TALLOC_CTX *tmp_ctx;
+	struct dcerpc_binding_handle *b;
 
 	DEBUG(8,("update_printer\n"));
 
@@ -6531,9 +6539,15 @@
 		goto done;
 	}
 
-	result = winreg_get_printer(tmp_ctx,
-				    get_session_info_system(),
-				    p->msg_ctx,
+	result = winreg_printer_binding_handle(tmp_ctx,
+					       get_session_info_system(),
+					       p->msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(result)) {
+		goto done;
+	}
+
+	result = winreg_get_printer(tmp_ctx, b,
 				    lp_const_servicename(snum),
 				    &old_printer);
 	if (!W_ERROR_IS_OK(result)) {
@@ -6587,9 +6601,7 @@
 	if (devmode == NULL) {
 		printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
 	}
-	result = winreg_update_printer(tmp_ctx,
-				       get_session_info_system(),
-				       p->msg_ctx,
+	result = winreg_update_printer(tmp_ctx, b,
 				       printer->sharename,
 				       printer_mask,
 				       printer,
@@ -6628,7 +6640,7 @@
 	if (!get_printer_snum(p, handle, &snum, NULL))
 		return WERR_BADFID;
 
-	result = winreg_get_printer(p->mem_ctx,
+	result = winreg_get_printer_internal(p->mem_ctx,
 				    get_session_info_system(),
 				    p->msg_ctx,
 				    lp_servicename(snum),
@@ -6677,7 +6689,7 @@
 		return WERR_ACCESS_DENIED;
 	}
 
-	return winreg_update_printer(p->mem_ctx,
+	return winreg_update_printer_internal(p->mem_ctx,
 				     get_session_info_system(),
 				     p->msg_ctx,
 				     lp_const_servicename(snum),
@@ -7091,7 +7103,7 @@
 		return WERR_BADFID;
 	}
 
-	result = winreg_get_printer(p->mem_ctx,
+	result = winreg_get_printer_internal(p->mem_ctx,
 				    get_session_info_system(),
 				    p->msg_ctx,
 				    lp_const_servicename(snum),
@@ -7276,12 +7288,21 @@
 	WERROR result = WERR_OK;
 	uint32_t num_drivers;
 	const char **drivers;
+	struct dcerpc_binding_handle *b;
 
 	*count_p = 0;
 	*info_p = NULL;
 
+	result = winreg_printer_binding_handle(mem_ctx,
+					       session_info,
+					       msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(result)) {
+		goto out;
+	}
+
 	for (version=0; version<DRIVER_MAX_VERSION; version++) {
-		result = winreg_get_driver_list(mem_ctx, session_info, msg_ctx,
+		result = winreg_get_driver_list(mem_ctx, b,
 						architecture, version,
 						&num_drivers, &drivers);
 		if (!W_ERROR_IS_OK(result)) {
@@ -7306,8 +7327,7 @@
 		for (i = 0; i < num_drivers; i++) {
 			DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
 
-			result = winreg_get_driver(mem_ctx, session_info,
-						   msg_ctx,
+			result = winreg_get_driver(mem_ctx, b,
 						   architecture, drivers[i],
 						   version, &driver);
 			if (!W_ERROR_IS_OK(result)) {
@@ -7502,7 +7522,7 @@
 
 	switch (r->in.level) {
 	case 1:
-		result = winreg_printer_enumforms1(p->mem_ctx,
+		result = winreg_printer_enumforms1_internal(p->mem_ctx,
 						   get_session_info_system(),
 						   p->msg_ctx,
 						   r->out.count,
@@ -7552,7 +7572,7 @@
 
 	switch (r->in.level) {
 	case 1:
-		result = winreg_printer_getform1(p->mem_ctx,
+		result = winreg_printer_getform1_internal(p->mem_ctx,
 						 get_session_info_system(),
 						 p->msg_ctx,
 						 r->in.form_name,
@@ -7927,7 +7947,7 @@
 			 info2,
 			 NULL);
 
-	err = winreg_update_printer(p->mem_ctx,
+	err = winreg_update_printer_internal(p->mem_ctx,
 				    get_session_info_system(),
 				    p->msg_ctx,
 				    info2->sharename,
@@ -8054,7 +8074,7 @@
 		goto done;
 	}
 
-	err = winreg_add_driver(p->mem_ctx,
+	err = winreg_add_driver_internal(p->mem_ctx,
 				get_session_info_system(),
 				p->msg_ctx,
 				r->in.info_ctr,
@@ -8461,8 +8481,8 @@
 	struct spoolss_AddFormInfo1 *form = r->in.info.info1;
 	int snum = -1;
 	WERROR status = WERR_OK;
-
 	struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
+	struct dcerpc_binding_handle *b;
 
 	DEBUG(5,("_spoolss_AddForm\n"));
 
@@ -8495,9 +8515,15 @@
 		return WERR_INVALID_PARAM;
 	}
 
-	status = winreg_printer_addform1(p->mem_ctx,
-					 get_session_info_system(),
-					 p->msg_ctx,
+	status = winreg_printer_binding_handle(p->mem_ctx,
+					       get_session_info_system(),
+					       p->msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(status)) {
+		return status;
+	}
+
+	status = winreg_printer_addform1(p->mem_ctx, b,
 					 form);
 	if (!W_ERROR_IS_OK(status)) {
 		return status;
@@ -8511,9 +8537,7 @@
 			return WERR_BADFID;
 		}
 
-		status = winreg_printer_update_changeid(p->mem_ctx,
-							get_session_info_system(),
-							p->msg_ctx,
+		status = winreg_printer_update_changeid(p->mem_ctx, b,
 							lp_const_servicename(snum));
 		if (!W_ERROR_IS_OK(status)) {
 			return status;
@@ -8534,6 +8558,7 @@
 	struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 	int snum = -1;
 	WERROR status = WERR_OK;
+	struct dcerpc_binding_handle *b;
 
 	DEBUG(5,("_spoolss_DeleteForm\n"));
 
@@ -8554,9 +8579,15 @@
 		return WERR_ACCESS_DENIED;
 	}
 
-	status = winreg_printer_deleteform1(p->mem_ctx,
-					    get_session_info_system(),
-					    p->msg_ctx,
+	status = winreg_printer_binding_handle(p->mem_ctx,
+					       get_session_info_system(),
+					       p->msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(status)) {
+		return status;
+	}
+
+	status = winreg_printer_deleteform1(p->mem_ctx, b,
 					    form_name);
 	if (!W_ERROR_IS_OK(status)) {
 		return status;
@@ -8570,9 +8601,7 @@
 			return WERR_BADFID;
 		}
 
-		status = winreg_printer_update_changeid(p->mem_ctx,
-							get_session_info_system(),
-							p->msg_ctx,
+		status = winreg_printer_update_changeid(p->mem_ctx, b,
 							lp_const_servicename(snum));
 		if (!W_ERROR_IS_OK(status)) {
 			return status;
@@ -8593,6 +8622,7 @@
 	const char *form_name = r->in.form_name;
 	int snum = -1;
 	WERROR status = WERR_OK;
+	struct dcerpc_binding_handle *b;
 
 	struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
@@ -8618,9 +8648,15 @@
 		return WERR_ACCESS_DENIED;
 	}
 
-	status = winreg_printer_setform1(p->mem_ctx,
-					 get_session_info_system(),
-					 p->msg_ctx,
+	status = winreg_printer_binding_handle(p->mem_ctx,
+					       get_session_info_system(),
+					       p->msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(status)) {
+		return status;
+	}
+
+	status = winreg_printer_setform1(p->mem_ctx, b,
 					 form_name,
 					 form);
 	if (!W_ERROR_IS_OK(status)) {
@@ -8635,9 +8671,7 @@
 			return WERR_BADFID;
 		}
 
-		status = winreg_printer_update_changeid(p->mem_ctx,
-							get_session_info_system(),
-							p->msg_ctx,
+		status = winreg_printer_update_changeid(p->mem_ctx, b,
 							lp_const_servicename(snum));
 		if (!W_ERROR_IS_OK(status)) {
 			return status;
@@ -9129,7 +9163,7 @@
 		return WERR_BADFID;
 	}
 
-	result = winreg_get_printer(p->mem_ctx,
+	result = winreg_get_printer_internal(p->mem_ctx,
 				    get_session_info_system(),
 				    p->msg_ctx,
 				    lp_const_servicename(snum),
@@ -9187,11 +9221,11 @@
 	int 			snum = 0;
 	WERROR result = WERR_OK;
 	DATA_BLOB blob;
-	enum winreg_Type val_type;
-	uint8_t *val_data;
-	uint32_t val_size;
+	enum winreg_Type val_type = REG_NONE;
+	uint8_t *val_data = NULL;
+	uint32_t val_size = 0;
+	struct dcerpc_binding_handle *b;
 
-
 	DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
 
 	DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
@@ -9248,6 +9282,14 @@
 		return WERR_INVALID_PARAM;
 	}
 
+	result = winreg_printer_binding_handle(p->mem_ctx,
+					       get_session_info_system(),
+					       p->msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(result)) {
+		return result;
+	}
+
 	/* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
 	if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
 	    strequal(r->in.value_name, "ChangeId")) {
@@ -9256,9 +9298,7 @@
 		if (r->in.offered >= *r->out.needed) {
 			uint32_t changeid = 0;
 
-			result = winreg_printer_get_changeid(p->mem_ctx,
-							     get_session_info_system(),
-							     p->msg_ctx,
+			result = winreg_printer_get_changeid(p->mem_ctx, b,
 							     printer,
 							     &changeid);
 			if (!W_ERROR_IS_OK(result)) {
@@ -9271,9 +9311,7 @@
 		goto done;
 	}
 
-	result = winreg_get_printer_dataex(p->mem_ctx,
-					   get_session_info_system(),
-					   p->msg_ctx,
+	result = winreg_get_printer_dataex(p->mem_ctx, b,
 					   printer,
 					   r->in.key_name,
 					   r->in.value_name,
@@ -9310,6 +9348,7 @@
 	WERROR 			result = WERR_OK;
 	struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 	char			*oid_string;
+	struct dcerpc_binding_handle *b;
 
 	DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
 
@@ -9346,9 +9385,15 @@
 		return WERR_ACCESS_DENIED;
 	}
 
-	result = winreg_get_printer(Printer,
-				    get_session_info_system(),
-				    p->msg_ctx,
+	result = winreg_printer_binding_handle(p->mem_ctx,
+					       get_session_info_system(),
+					       p->msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(result)) {
+		return result;
+	}
+
+	result = winreg_get_printer(Printer, b,
 				    lp_servicename(snum),
 				    &pinfo2);
 	if (!W_ERROR_IS_OK(result)) {
@@ -9365,9 +9410,7 @@
 
 	/* save the registry data */
 
-	result = winreg_set_printer_dataex(p->mem_ctx,
-					   get_session_info_system(),
-					   p->msg_ctx,
+	result = winreg_set_printer_dataex(p->mem_ctx, b,
 					   pinfo2->sharename,
 					   r->in.key_name,
 					   r->in.value_name,
@@ -9391,9 +9434,7 @@
 			 * previous set_printer_dataex() call.  I have no idea if
 			 * this is right.    --jerry
 			 */
-			winreg_set_printer_dataex(p->mem_ctx,
-						  get_session_info_system(),
-						  p->msg_ctx,
+			winreg_set_printer_dataex(p->mem_ctx, b,
 						  pinfo2->sharename,
 						  str,
 						  r->in.value_name,
@@ -9402,9 +9443,7 @@
 						  strlen(oid_string) + 1);
 		}
 
-		result = winreg_printer_update_changeid(p->mem_ctx,
-							get_session_info_system(),
-							p->msg_ctx,
+		result = winreg_printer_update_changeid(p->mem_ctx, b,
 							lp_const_servicename(snum));
 
 	}
@@ -9450,14 +9489,14 @@
 	}
 	printer = lp_const_servicename(snum);
 
-	status = winreg_delete_printer_dataex(p->mem_ctx,
+	status = winreg_delete_printer_dataex_internal(p->mem_ctx,
 					      get_session_info_system(),
 					      p->msg_ctx,
 					      printer,
 					      r->in.key_name,
 					      r->in.value_name);
 	if (W_ERROR_IS_OK(status)) {
-		status = winreg_printer_update_changeid(p->mem_ctx,
+		status = winreg_printer_update_changeid_internal(p->mem_ctx,
 							get_session_info_system(),
 							p->msg_ctx,
 							printer);
@@ -9492,7 +9531,7 @@
 		return WERR_BADFID;
 	}
 
-	result = winreg_enum_printer_key(p->mem_ctx,
+	result = winreg_enum_printer_key_internal(p->mem_ctx,
 					 get_session_info_system(),
 					 p->msg_ctx,
 					 lp_const_servicename(snum),
@@ -9540,6 +9579,7 @@
 	int 			snum=0;
 	WERROR			status;
 	const char *printer;
+	struct dcerpc_binding_handle *b;
 
 	DEBUG(5,("_spoolss_DeletePrinterKey\n"));
 
@@ -9565,16 +9605,20 @@
 
 	printer = lp_const_servicename(snum);
 
+	status = winreg_printer_binding_handle(p->mem_ctx,
+					       get_session_info_system(),
+					       p->msg_ctx,
+					       &b);
+	if (!W_ERROR_IS_OK(status)) {
+		return status;
+	}
+
 	/* delete the key and all subkeys */
-	status = winreg_delete_printer_key(p->mem_ctx,
-					   get_session_info_system(),
-					   p->msg_ctx,
+	status = winreg_delete_printer_key(p->mem_ctx, b,
 					   printer,
 					   r->in.key_name);
 	if (W_ERROR_IS_OK(status)) {
-		status = winreg_printer_update_changeid(p->mem_ctx,
-							get_session_info_system(),
-							p->msg_ctx,
+		status = winreg_printer_update_changeid(p->mem_ctx, b,
 							printer);
 	}
 
@@ -9623,7 +9667,7 @@
 	}
 
 	/* now look for a match on the key name */
-	result = winreg_enum_printer_dataex(p->mem_ctx,
+	result = winreg_enum_printer_dataex_internal(p->mem_ctx,
 					    get_session_info_system(),
 					    p->msg_ctx,
 					    lp_const_servicename(snum),

Modified: branches/samba/experimental/source3/rpc_server/spoolss/srv_spoolss_util.c
===================================================================
--- branches/samba/experimental/source3/rpc_server/spoolss/srv_spoolss_util.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_server/spoolss/srv_spoolss_util.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -20,247 +20,19 @@
  */
 
 #include "includes.h"
-#include "nt_printing.h"
-#include "srv_spoolss_util.h"
-#include "../librpc/gen_ndr/ndr_spoolss.h"
-#include "../librpc/gen_ndr/ndr_winreg_c.h"
-#include "../librpc/gen_ndr/ndr_security.h"
-#include "secrets.h"
 #include "rpc_server/rpc_ncacn_np.h"
-#include "../libcli/security/security.h"
-#include "rpc_client/cli_winreg.h"
-#include "../libcli/registry/util_reg.h"
+#include "../librpc/gen_ndr/ndr_spoolss.h"
+#include "../librpc/gen_ndr/ndr_winreg.h"
+#include "srv_spoolss_util.h"
+#include "rpc_client/cli_winreg_spoolss.h"
 
-#define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
-#define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
-#define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
-#define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
-
-#define EMPTY_STRING ""
-
-#define FILL_STRING(mem_ctx, in, out) \
-	do { \
-		if (in && strlen(in)) { \
-			out = talloc_strdup(mem_ctx, in); \
-		} else { \
-			out = talloc_strdup(mem_ctx, ""); \
-		} \
-		W_ERROR_HAVE_NO_MEMORY(out); \
-	} while (0);
-
-#define CHECK_ERROR(result) \
-	if (W_ERROR_IS_OK(result)) continue; \
-	if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \
-	if (!W_ERROR_IS_OK(result)) break
-
-/*        FLAGS,                NAME,                              with,   height,   left, top, right, bottom */
-static const struct spoolss_FormInfo1 builtin_forms1[] = {
-	{ SPOOLSS_FORM_BUILTIN, "10x11",                          {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
-	{ SPOOLSS_FORM_BUILTIN, "10x14",                          {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
-	{ SPOOLSS_FORM_BUILTIN, "11x17",                          {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
-	{ SPOOLSS_FORM_BUILTIN, "12x11",                          {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
-	{ SPOOLSS_FORM_BUILTIN, "15x11",                          {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
-	{ SPOOLSS_FORM_BUILTIN, "6 3/4 Envelope",                 {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
-	{ SPOOLSS_FORM_BUILTIN, "9x11",                           {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
-	{ SPOOLSS_FORM_BUILTIN, "A0",                             {0xcd528,0x122488},{0x0,0x0,0xcd528,0x122488} },
-	{ SPOOLSS_FORM_BUILTIN, "A1",                             {0x91050,0xcd528}, {0x0,0x0,0x91050,0xcd528} },
-	{ SPOOLSS_FORM_BUILTIN, "A2",                             {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
-	{ SPOOLSS_FORM_BUILTIN, "A3 Extra Transverse",            {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
-	{ SPOOLSS_FORM_BUILTIN, "A3 Extra",                       {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
-	{ SPOOLSS_FORM_BUILTIN, "A3 Rotated",                     {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
-	{ SPOOLSS_FORM_BUILTIN, "A3 Transverse",                  {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
-	{ SPOOLSS_FORM_BUILTIN, "A3",                             {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
-	{ SPOOLSS_FORM_BUILTIN, "A4 Extra",                       {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
-	{ SPOOLSS_FORM_BUILTIN, "A4 Plus",                        {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
-	{ SPOOLSS_FORM_BUILTIN, "A4 Rotated",                     {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
-	{ SPOOLSS_FORM_BUILTIN, "A4 Small",                       {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
-	{ SPOOLSS_FORM_BUILTIN, "A4 Transverse",                  {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
-	{ SPOOLSS_FORM_BUILTIN, "A4",                             {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
-	{ SPOOLSS_FORM_BUILTIN, "A5 Extra",                       {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
-	{ SPOOLSS_FORM_BUILTIN, "A5 Rotated",                     {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
-	{ SPOOLSS_FORM_BUILTIN, "A5 Transverse",                  {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
-	{ SPOOLSS_FORM_BUILTIN, "A5",                             {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
-	{ SPOOLSS_FORM_BUILTIN, "A6 Rotated",                     {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
-	{ SPOOLSS_FORM_BUILTIN, "A6",                             {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
-	{ SPOOLSS_FORM_BUILTIN, "B4 (ISO)",                       {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
-	{ SPOOLSS_FORM_BUILTIN, "B4 (JIS) Rotated",               {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
-	{ SPOOLSS_FORM_BUILTIN, "B4 (JIS)",                       {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} },
-	{ SPOOLSS_FORM_BUILTIN, "B5 (ISO) Extra",                 {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
-	{ SPOOLSS_FORM_BUILTIN, "B5 (JIS) Rotated",               {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
-	{ SPOOLSS_FORM_BUILTIN, "B5 (JIS) Transverse",            {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
-	{ SPOOLSS_FORM_BUILTIN, "B5 (JIS)",                       {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
-	{ SPOOLSS_FORM_BUILTIN, "B6 (JIS) Rotated",               {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
-	{ SPOOLSS_FORM_BUILTIN, "B6 (JIS)",                       {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
-	{ SPOOLSS_FORM_BUILTIN, "C size sheet",                   {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
-	{ SPOOLSS_FORM_BUILTIN, "D size sheet",                   {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
-	{ SPOOLSS_FORM_BUILTIN, "Double Japan Postcard Rotated",  {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
-	{ SPOOLSS_FORM_BUILTIN, "E size sheet",                   {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope #10",                   {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope #11",                   {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope #12",                   {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope #14",                   {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope #9",                    {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope B4",                    {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope B5",                    {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope B6",                    {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope C3",                    {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope C4",                    {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope C5",                    {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope C6",                    {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope C65",                   {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope DL",                    {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope Invite",                {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope Monarch",               {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} },
-	{ SPOOLSS_FORM_BUILTIN, "Envelope",                       {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
-	{ SPOOLSS_FORM_BUILTIN, "Executive",                      {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
-	{ SPOOLSS_FORM_BUILTIN, "Folio",                          {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
-	{ SPOOLSS_FORM_BUILTIN, "German Legal Fanfold",           {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
-	{ SPOOLSS_FORM_BUILTIN, "German Std Fanfold",             {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
-	{ SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
-	{ SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
-	{ SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
-	{ SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
-	{ SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4 Rotated",  {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
-	{ SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4",          {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
-	{ SPOOLSS_FORM_BUILTIN, "Japanese Double Postcard",       {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
-	{ SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #3",      {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
-	{ SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #4",      {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
-	{ SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #2",      {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
-	{ SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #3",      {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
-	{ SPOOLSS_FORM_BUILTIN, "Japanese Postcard Rotated",      {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
-	{ SPOOLSS_FORM_BUILTIN, "Japanese Postcard",              {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} },
-	{ SPOOLSS_FORM_BUILTIN, "Ledger",                         {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
-	{ SPOOLSS_FORM_BUILTIN, "Legal Extra",                    {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} },
-	{ SPOOLSS_FORM_BUILTIN, "Legal",                          {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
-	{ SPOOLSS_FORM_BUILTIN, "Letter Extra Transverse",        {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
-	{ SPOOLSS_FORM_BUILTIN, "Letter Extra",                   {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
-	{ SPOOLSS_FORM_BUILTIN, "Letter Plus",                    {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} },
-	{ SPOOLSS_FORM_BUILTIN, "Letter Rotated",                 {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} },
-	{ SPOOLSS_FORM_BUILTIN, "Letter Small",                   {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
-	{ SPOOLSS_FORM_BUILTIN, "Letter Transverse",              {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
-	{ SPOOLSS_FORM_BUILTIN, "Letter",                         {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
-	{ SPOOLSS_FORM_BUILTIN, "Note",                           {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC 16K Rotated",                {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC 16K",                        {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC 32K Rotated",                {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC 32K",                        {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC 32K(Big) Rotated",           {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC 32K(Big)",                   {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #1 Rotated",        {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #1",                {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #10 Rotated",       {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #10",               {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #2 Rotated",        {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #2",                {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #3 Rotated",        {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #3",                {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #4 Rotated",        {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #4",                {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #5 Rotated",        {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #5",                {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #6 Rotated",        {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #6",                {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #7 Rotated",        {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #7",                {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #8 Rotated",        {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #8",                {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #9 Rotated",        {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} },
-	{ SPOOLSS_FORM_BUILTIN, "PRC Envelope #9",                {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
-	{ SPOOLSS_FORM_BUILTIN, "Quarto",                         {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
-	{ SPOOLSS_FORM_BUILTIN, "Reserved48",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
-	{ SPOOLSS_FORM_BUILTIN, "Reserved49",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
-	{ SPOOLSS_FORM_BUILTIN, "Statement",                      {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
-	{ SPOOLSS_FORM_BUILTIN, "Super A",                        {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
-	{ SPOOLSS_FORM_BUILTIN, "Super B",                        {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
-	{ SPOOLSS_FORM_BUILTIN, "Tabloid Extra",                  {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
-	{ SPOOLSS_FORM_BUILTIN, "Tabloid",                        {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
-	{ SPOOLSS_FORM_BUILTIN, "US Std Fanfold",                 {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} }
-};
-
-/********************************************************************
- static helper functions
-********************************************************************/
-
-/****************************************************************************
- Update the changeid time.
-****************************************************************************/
-/**
- * @internal
- *
- * @brief Update the ChangeID time of a printer.
- *
- * This is SO NASTY as some drivers need this to change, others need it
- * static. This value will change every second, and I must hope that this
- * is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
- * UTAH ! JRA.
- *
- * @return              The ChangeID.
- */
-static uint32_t winreg_printer_rev_changeid(void)
+WERROR winreg_printer_binding_handle(TALLOC_CTX *mem_ctx,
+				     const struct auth_serversupplied_info *session_info,
+				     struct messaging_context *msg_ctx,
+				     struct dcerpc_binding_handle **winreg_binding_handle)
 {
-	struct timeval tv;
-
-	get_process_uptime(&tv);
-
-#if 1	/* JERRY */
-	/* Return changeid as msec since spooler restart */
-	return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-#else
-	/*
-	 * This setting seems to work well but is too untested
-	 * to replace the above calculation.  Left in for experimentation
-	 * of the reader            --jerry (Tue Mar 12 09:15:05 CST 2002)
-	 */
-	return tv.tv_sec * 10 + tv.tv_usec / 100000;
-#endif
-}
-
-/**
- * @internal
- *
- * @brief Connect to the interal winreg server and open the given printer key.
- *
- * The function will create the needed subkeys if they don't exist.
- *
- * @param[in]  mem_ctx       The memory context to use.
- *
- * @param[in]  session_info   The supplied server info.
- *
- * @param[out] binding_handle A pointer for the winreg dcerpc binding handle.
- *
- * @param[in]  path          The path to the key to open.
- *
- * @param[in]  key           The key to open.
- *
- * @param[in]  create_key    Set to true if the key should be created if it
- *                           doesn't exist.
- *
- * @param[in]  access_mask   The access mask to open the key.
- *
- * @param[out] hive_handle   A policy handle for the opened hive.
- *
- * @param[out] key_handle    A policy handle for the opened key.
- *
- * @return                   WERR_OK on success, the corresponding DOS error
- *                           code if something gone wrong.
- */
-static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx,
-			      const struct auth_serversupplied_info *session_info,
-			      struct messaging_context *msg_ctx,
-			      struct dcerpc_binding_handle **winreg_binding_handle,
-			      const char *path,
-			      const char *key,
-			      bool create_key,
-			      uint32_t access_mask,
-			      struct policy_handle *hive_handle,
-			      struct policy_handle *key_handle)
-{
 	static struct client_address client_id;
-	struct dcerpc_binding_handle *binding_handle;
-	struct winreg_String wkey, wkeyclass;
-	char *keyname;
 	NTSTATUS status;
-	WERROR result = WERR_OK;
 
 	strlcpy(client_id.addr, "127.0.0.1", sizeof(client_id.addr));
 	client_id.name = "127.0.0.1";
@@ -270,3982 +42,421 @@
 				       &client_id,
 				       session_info,
 				       msg_ctx,
-				       &binding_handle);
+				       winreg_binding_handle);
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("winreg_printer_openkey: Could not connect to winreg pipe: %s\n",
+		DEBUG(0, ("winreg_printer_binding_handle: Could not connect to winreg pipe: %s\n",
 			  nt_errstr(status)));
 		return ntstatus_to_werror(status);
 	}
 
-	status = dcerpc_winreg_OpenHKLM(binding_handle,
-					mem_ctx,
-					NULL,
-					access_mask,
-					hive_handle,
-					&result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
-			  nt_errstr(status)));
-		talloc_free(binding_handle);
-		return ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
-			  win_errstr(result)));
-		talloc_free(binding_handle);
-		return result;
-	}
-
-	if (key && *key) {
-		keyname = talloc_asprintf(mem_ctx, "%s\\%s", path, key);
-	} else {
-		keyname = talloc_strdup(mem_ctx, path);
-	}
-	if (keyname == NULL) {
-		talloc_free(binding_handle);
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(wkey);
-	wkey.name = keyname;
-
-	if (create_key) {
-		enum winreg_CreateAction action = REG_ACTION_NONE;
-
-		ZERO_STRUCT(wkeyclass);
-		wkeyclass.name = "";
-
-		status = dcerpc_winreg_CreateKey(binding_handle,
-						 mem_ctx,
-						 hive_handle,
-						 wkey,
-						 wkeyclass,
-						 0,
-						 access_mask,
-						 NULL,
-						 key_handle,
-						 &action,
-						 &result);
-		switch (action) {
-			case REG_ACTION_NONE:
-				DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n"));
-				break;
-			case REG_CREATED_NEW_KEY:
-				DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname));
-				break;
-			case REG_OPENED_EXISTING_KEY:
-				DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname));
-				break;
-		}
-	} else {
-		status = dcerpc_winreg_OpenKey(binding_handle,
-					       mem_ctx,
-					       hive_handle,
-					       wkey,
-					       0,
-					       access_mask,
-					       key_handle,
-					       &result);
-	}
-	if (!NT_STATUS_IS_OK(status)) {
-		talloc_free(binding_handle);
-		return ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		talloc_free(binding_handle);
-		return result;
-	}
-
-	*winreg_binding_handle = binding_handle;
-
 	return WERR_OK;
 }
 
-/**
- * @brief Create the registry keyname for the given printer.
- *
- * @param[in]  mem_ctx  The memory context to use.
- *
- * @param[in]  printer  The name of the printer to get the registry key.
- *
- * @return     The registry key or NULL on error.
- */
-static char *winreg_printer_data_keyname(TALLOC_CTX *mem_ctx, const char *printer) {
-	return talloc_asprintf(mem_ctx, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY, printer);
-}
-
-/**
- * @internal
- *
- * @brief Enumerate values of an opened key handle and retrieve the data.
- *
- * @param[in]  mem_ctx  The memory context to use.
- *
- * @param[in]  winreg_handle The binding handle for the rpc connection.
- *
- * @param[in]  key_hnd  The opened key handle.
- *
- * @param[out] pnum_values A pointer to store he number of values found.
- *
- * @param[out] pnum_values A pointer to store the number of values we found.
- *
- * @return                   WERR_OK on success, the corresponding DOS error
- *                           code if something gone wrong.
- */
-static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
-					struct dcerpc_binding_handle *winreg_handle,
-					struct policy_handle *key_hnd,
-					uint32_t *pnum_values,
-					struct spoolss_PrinterEnumValues **penum_values)
+WERROR winreg_delete_printer_key_internal(TALLOC_CTX *mem_ctx,
+					  const struct auth_serversupplied_info *session_info,
+					  struct messaging_context *msg_ctx,
+					  const char *printer,
+					  const char *key)
 {
-	TALLOC_CTX *tmp_ctx;
-	uint32_t num_subkeys, max_subkeylen, max_classlen;
-	uint32_t num_values, max_valnamelen, max_valbufsize;
-	uint32_t secdescsize;
-	uint32_t i;
-	NTTIME last_changed_time;
-	struct winreg_String classname;
+	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	struct spoolss_PrinterEnumValues *enum_values;
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	WERROR result = WERR_OK;
-	NTSTATUS status;
-
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(classname);
-
-	status = dcerpc_winreg_QueryInfoKey(winreg_handle,
-					    tmp_ctx,
-					    key_hnd,
-					    &classname,
-					    &num_subkeys,
-					    &max_subkeylen,
-					    &max_classlen,
-					    &num_values,
-					    &max_valnamelen,
-					    &max_valbufsize,
-					    &secdescsize,
-					    &last_changed_time,
-					    &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
-			  nt_errstr(status)));
-		result = ntstatus_to_werror(status);
-		goto error;
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
-			  win_errstr(result)));
-		goto error;
-	}
-
-	if (num_values == 0) {
-		*pnum_values = 0;
-		TALLOC_FREE(tmp_ctx);
-		return WERR_OK;
-	}
-
-	enum_values = TALLOC_ARRAY(tmp_ctx, struct spoolss_PrinterEnumValues, num_values);
-	if (enum_values == NULL) {
-		result = WERR_NOMEM;
-		goto error;
-	}
-
-	for (i = 0; i < num_values; i++) {
-		struct spoolss_PrinterEnumValues val;
-		struct winreg_ValNameBuf name_buf;
-		enum winreg_Type type = REG_NONE;
-		uint8_t *data;
-		uint32_t data_size;
-		uint32_t length;
-		char n = '\0';
-
-		name_buf.name = &n;
-		name_buf.size = max_valnamelen + 2;
-		name_buf.length = 0;
-
-		data_size = max_valbufsize;
-		data = NULL;
-		if (data_size) {
-			data = (uint8_t *) TALLOC(tmp_ctx, data_size);
-		}
-		length = 0;
-
-		status = dcerpc_winreg_EnumValue(winreg_handle,
-						 tmp_ctx,
-						 key_hnd,
-						 i,
-						 &name_buf,
-						 &type,
-						 data,
-						 data_size ? &data_size : NULL,
-						 &length,
-						 &result);
-		if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
-			result = WERR_OK;
-			status = NT_STATUS_OK;
-			break;
-		}
-
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
-				  nt_errstr(status)));
-			result = ntstatus_to_werror(status);
-			goto error;
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
-				  win_errstr(result)));
-			goto error;
-		}
-
-		if (name_buf.name == NULL) {
-			result = WERR_INVALID_PARAMETER;
-			goto error;
-		}
-
-		val.value_name = talloc_strdup(enum_values, name_buf.name);
-		if (val.value_name == NULL) {
-			result = WERR_NOMEM;
-			goto error;
-		}
-		val.value_name_len = strlen_m_term(val.value_name) * 2;
-
-		val.type = type;
-		val.data_length = length;
-		val.data = NULL;
-		if (val.data_length) {
-			val.data = talloc(enum_values, DATA_BLOB);
-			if (val.data == NULL) {
-				result = WERR_NOMEM;
-				goto error;
-			}
-			*val.data = data_blob_talloc(val.data, data, val.data_length);
-		}
-
-		enum_values[i] = val;
-	}
-
-	*pnum_values = num_values;
-	if (penum_values) {
-		*penum_values = talloc_move(mem_ctx, &enum_values);
-	}
-
-	result = WERR_OK;
-
- error:
-	TALLOC_FREE(tmp_ctx);
-	return result;
+	return winreg_delete_printer_key(mem_ctx, b,
+					 printer,
+					 key);
 }
 
-/**
- * @internal
- *
- * @brief A function to delete a key and its subkeys recurively.
- *
- * @param[in]  mem_ctx  The memory context to use.
- *
- * @param[in]  winreg_handle The binding handle for the rpc connection.
- *
- * @param[in]  hive_handle A opened hive handle to the key.
- *
- * @param[in]  access_mask The access mask to access the key.
- *
- * @param[in]  key      The key to delete
- *
- * @return              WERR_OK on success, the corresponding DOS error
- *                      code if something gone wrong.
- */
-static WERROR winreg_printer_delete_subkeys(TALLOC_CTX *mem_ctx,
-					    struct dcerpc_binding_handle *winreg_handle,
-					    struct policy_handle *hive_handle,
-					    uint32_t access_mask,
-					    const char *key)
+WERROR winreg_printer_update_changeid_internal(TALLOC_CTX *mem_ctx,
+					       const struct auth_serversupplied_info *session_info,
+					       struct messaging_context *msg_ctx,
+					       const char *printer)
 {
-	const char **subkeys = NULL;
-	uint32_t num_subkeys = 0;
-	struct policy_handle key_hnd;
-	struct winreg_String wkey = { 0, };
-	WERROR result = WERR_OK;
-	NTSTATUS status;
-	uint32_t i;
+	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	ZERO_STRUCT(key_hnd);
-	wkey.name = key;
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key));
-	/* open the key */
-	status = dcerpc_winreg_OpenKey(winreg_handle,
-				       mem_ctx,
-				       hive_handle,
-				       wkey,
-				       0,
-				       access_mask,
-				       &key_hnd,
-				       &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
-			  wkey.name, nt_errstr(status)));
-		return ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
-			  wkey.name, win_errstr(result)));
-		return result;
-	}
-
-	status = dcerpc_winreg_enum_keys(mem_ctx,
-					 winreg_handle,
-					 &key_hnd,
-					 &num_subkeys,
-					 &subkeys,
-					 &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	for (i = 0; i < num_subkeys; i++) {
-		/* create key + subkey */
-		char *subkey = talloc_asprintf(mem_ctx, "%s\\%s", key, subkeys[i]);
-		if (subkey == NULL) {
-			goto done;
-		}
-
-		DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey));
-		result = winreg_printer_delete_subkeys(mem_ctx,
-						       winreg_handle,
-						       hive_handle,
-						       access_mask,
-						       subkey);
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (is_valid_policy_hnd(&key_hnd)) {
-		WERROR ignore;
-		dcerpc_winreg_CloseKey(winreg_handle, mem_ctx, &key_hnd, &ignore);
-	}
-
-	wkey.name = key;
-
-	status = dcerpc_winreg_DeleteKey(winreg_handle,
-					 mem_ctx,
-					 hive_handle,
-					 wkey,
-					 &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-
-done:
-	if (is_valid_policy_hnd(&key_hnd)) {
-		WERROR ignore;
-
-		dcerpc_winreg_CloseKey(winreg_handle, mem_ctx, &key_hnd, &ignore);
-	}
-
-	return result;
+	return winreg_printer_update_changeid(mem_ctx, b,
+					      printer);
 }
 
-static WERROR winreg_printer_opendriver(TALLOC_CTX *mem_ctx,
-					const struct auth_serversupplied_info *session_info,
-					struct messaging_context *msg_ctx,
-					const char *drivername,
-					const char *architecture,
-					uint32_t version,
-					uint32_t access_mask,
-					bool create,
-					struct dcerpc_binding_handle **winreg_binding_handle,
-					struct policy_handle *hive_hnd,
-					struct policy_handle *key_hnd)
+WERROR winreg_printer_get_changeid_internal(TALLOC_CTX *mem_ctx,
+					    const struct auth_serversupplied_info *session_info,
+					    struct messaging_context *msg_ctx,
+					    const char *printer,
+					    uint32_t *pchangeid)
 {
 	WERROR result;
-	char *key_name;
+	struct dcerpc_binding_handle *b;
 
-	key_name = talloc_asprintf(mem_ctx, "%s\\Environments\\%s\\Drivers\\Version-%u",
-				   TOP_LEVEL_CONTROL_KEY,
-				   architecture, version);
-	if (!key_name) {
-		return WERR_NOMEM;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	result = winreg_printer_openkey(mem_ctx,
-					session_info,
-					msg_ctx,
-					winreg_binding_handle,
-					key_name,
-					drivername,
-					create,
-					access_mask,
-					hive_hnd,
-					key_hnd);
-	return result;
+	return winreg_printer_get_changeid(mem_ctx, b,
+					   printer,
+					   pchangeid);
 }
 
-static WERROR winreg_enumval_to_dword(TALLOC_CTX *mem_ctx,
-				      struct spoolss_PrinterEnumValues *v,
-				      const char *valuename, uint32_t *dw)
+WERROR winreg_get_printer_internal(TALLOC_CTX *mem_ctx,
+				   const struct auth_serversupplied_info *session_info,
+				   struct messaging_context *msg_ctx,
+				   const char *printer,
+				   struct spoolss_PrinterInfo2 **pinfo2)
 {
-	/* just return if it is not the one we are looking for */
-	if (strcmp(valuename, v->value_name) != 0) {
-		return WERR_NOT_FOUND;
-	}
+	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	if (v->type != REG_DWORD) {
-		return WERR_INVALID_DATATYPE;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	if (v->data_length != 4) {
-		*dw = 0;
-		return WERR_OK;
-	}
+	return winreg_get_printer(mem_ctx, b,
+				  printer,
+				  pinfo2);
 
-	*dw = IVAL(v->data->data, 0);
-	return WERR_OK;
 }
 
-static WERROR winreg_enumval_to_sz(TALLOC_CTX *mem_ctx,
-				   struct spoolss_PrinterEnumValues *v,
-				   const char *valuename, const char **_str)
+WERROR winreg_create_printer_internal(TALLOC_CTX *mem_ctx,
+				      const struct auth_serversupplied_info *session_info,
+				      struct messaging_context *msg_ctx,
+				      const char *sharename)
 {
-	/* just return if it is not the one we are looking for */
-	if (strcmp(valuename, v->value_name) != 0) {
-		return WERR_NOT_FOUND;
-	}
+	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	if (v->type != REG_SZ) {
-		return WERR_INVALID_DATATYPE;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	if (v->data_length == 0) {
-		*_str = talloc_strdup(mem_ctx, EMPTY_STRING);
-		if (*_str == NULL) {
-			return WERR_NOMEM;
-		}
-		return WERR_OK;
-	}
-
-	if (!pull_reg_sz(mem_ctx, v->data, _str)) {
-		return WERR_NOMEM;
-	}
-
-	return WERR_OK;
+	return winreg_create_printer(mem_ctx, b,
+				     sharename);
 }
 
-static WERROR winreg_enumval_to_multi_sz(TALLOC_CTX *mem_ctx,
-					 struct spoolss_PrinterEnumValues *v,
-					 const char *valuename,
-					 const char ***array)
+WERROR winreg_update_printer_internal(TALLOC_CTX *mem_ctx,
+				      const struct auth_serversupplied_info *session_info,
+				      struct messaging_context *msg_ctx,
+				      const char *sharename,
+				      uint32_t info2_mask,
+				      struct spoolss_SetPrinterInfo2 *info2,
+				      struct spoolss_DeviceMode *devmode,
+				      struct security_descriptor *secdesc)
 {
-	/* just return if it is not the one we are looking for */
-	if (strcmp(valuename, v->value_name) != 0) {
-		return WERR_NOT_FOUND;
-	}
+	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	if (v->type != REG_MULTI_SZ) {
-		return WERR_INVALID_DATATYPE;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	if (v->data_length == 0) {
-		*array = talloc_array(mem_ctx, const char *, 1);
-		if (*array == NULL) {
-			return WERR_NOMEM;
-		}
-		*array[0] = NULL;
-		return WERR_OK;
-	}
-
-	if (!pull_reg_multi_sz(mem_ctx, v->data, array)) {
-		return WERR_NOMEM;
-	}
-
-	return WERR_OK;
+	return winreg_update_printer(mem_ctx, b,
+				     sharename,
+				     info2_mask,
+				     info2,
+				     devmode,
+				     secdesc);
 }
 
-static WERROR winreg_printer_write_date(TALLOC_CTX *mem_ctx,
-					struct dcerpc_binding_handle *winreg_handle,
-					struct policy_handle *key_handle,
-					const char *value,
-					NTTIME data)
+WERROR winreg_set_printer_dataex_internal(TALLOC_CTX *mem_ctx,
+					  const struct auth_serversupplied_info *session_info,
+					  struct messaging_context *msg_ctx,
+					  const char *printer,
+					  const char *key,
+					  const char *value,
+					  enum winreg_Type type,
+					  uint8_t *data,
+					  uint32_t data_size)
 {
-	struct winreg_String wvalue = { 0, };
-	DATA_BLOB blob;
-	WERROR result = WERR_OK;
-	NTSTATUS status;
-	const char *str;
-	struct tm *tm;
-	time_t t;
+	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	if (data == 0) {
-		str = talloc_strdup(mem_ctx, "01/01/1601");
-	} else {
-		t = nt_time_to_unix(data);
-		tm = localtime(&t);
-		if (tm == NULL) {
-			return map_werror_from_unix(errno);
-		}
-		str = talloc_asprintf(mem_ctx, "%02d/%02d/%04d",
-				      tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
-	}
-	if (!str) {
-		return WERR_NOMEM;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	wvalue.name = value;
-	if (!push_reg_sz(mem_ctx, &blob, str)) {
-		return WERR_NOMEM;
-	}
-	status = dcerpc_winreg_SetValue(winreg_handle,
-					mem_ctx,
-					key_handle,
-					wvalue,
-					REG_SZ,
-					blob.data,
-					blob.length,
-					&result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
-			wvalue.name, win_errstr(result)));
-	}
-
-	return result;
+	return winreg_set_printer_dataex(mem_ctx, b,
+					 printer,
+					 key,
+					 value,
+					 type,
+					 data,
+					 data_size);
 }
 
-static WERROR winreg_printer_date_to_NTTIME(const char *str, NTTIME *data)
+WERROR winreg_enum_printer_dataex_internal(TALLOC_CTX *mem_ctx,
+					   const struct auth_serversupplied_info *session_info,
+					   struct messaging_context *msg_ctx,
+					   const char *printer,
+					   const char *key,
+					   uint32_t *pnum_values,
+					   struct spoolss_PrinterEnumValues **penum_values)
 {
-	struct tm tm;
-	time_t t;
+	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	if (strequal(str, "01/01/1601")) {
-		*data = 0;
-		return WERR_OK;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	ZERO_STRUCT(tm);
-
-	if (sscanf(str, "%d/%d/%d",
-		   &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3) {
-		return WERR_INVALID_PARAMETER;
-	}
-	tm.tm_mon -= 1;
-	tm.tm_year -= 1900;
-	tm.tm_isdst = -1;
-
-	t = mktime(&tm);
-	unix_to_nt_time(data, t);
-
-	return WERR_OK;
+	return winreg_enum_printer_dataex(mem_ctx, b,
+					  printer,
+					  key,
+					  pnum_values,
+					  penum_values);
 }
 
-static WERROR winreg_printer_write_ver(TALLOC_CTX *mem_ctx,
-				       struct dcerpc_binding_handle *winreg_handle,
-				       struct policy_handle *key_handle,
-				       const char *value,
-				       uint64_t data)
+WERROR winreg_get_printer_dataex_internal(TALLOC_CTX *mem_ctx,
+					  const struct auth_serversupplied_info *session_info,
+					  struct messaging_context *msg_ctx,
+					  const char *printer,
+					  const char *key,
+					  const char *value,
+					  enum winreg_Type *type,
+					  uint8_t **data,
+					  uint32_t *data_size)
 {
-	struct winreg_String wvalue = { 0, };
-	DATA_BLOB blob;
-	WERROR result = WERR_OK;
-	NTSTATUS status;
-	char *str;
+	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	/* FIXME: check format is right,
-	 *	this needs to be something like: 6.1.7600.16385 */
-	str = talloc_asprintf(mem_ctx, "%u.%u.%u.%u",
-			      (unsigned)((data >> 48) & 0xFFFF),
-			      (unsigned)((data >> 32) & 0xFFFF),
-			      (unsigned)((data >> 16) & 0xFFFF),
-			      (unsigned)(data & 0xFFFF));
-	if (!str) {
-		return WERR_NOMEM;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	wvalue.name = value;
-	if (!push_reg_sz(mem_ctx, &blob, str)) {
-		return WERR_NOMEM;
-	}
-	status = dcerpc_winreg_SetValue(winreg_handle,
-					mem_ctx,
-					key_handle,
-					wvalue,
-					REG_SZ,
-					blob.data,
-					blob.length,
-					&result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
-			wvalue.name, win_errstr(result)));
-	}
-
-	return result;
+	return winreg_get_printer_dataex(mem_ctx, b,
+					 printer,
+					 key,
+					 value,
+					 type,
+					 data,
+					 data_size);
 }
 
-static WERROR winreg_printer_ver_to_dword(const char *str, uint64_t *data)
+WERROR winreg_delete_printer_dataex_internal(TALLOC_CTX *mem_ctx,
+					     const struct auth_serversupplied_info *session_info,
+					     struct messaging_context *msg_ctx,
+					     const char *printer,
+					     const char *key,
+					     const char *value)
 {
-	unsigned int v1, v2, v3, v4;
+	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	if (sscanf(str, "%u.%u.%u.%u", &v1, &v2, &v3, &v4) != 4) {
-		return WERR_INVALID_PARAMETER;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	*data = ((uint64_t)(v1 & 0xFFFF) << 48) +
-		((uint64_t)(v2 & 0xFFFF) << 32) +
-		((uint64_t)(v3 & 0xFFFF) << 16) +
-		(uint64_t)(v2 & 0xFFFF);
-
-	return WERR_OK;
-}
-
-/********************************************************************
- Public winreg function for spoolss
-********************************************************************/
-
-WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
-			     const struct auth_serversupplied_info *session_info,
-			     struct messaging_context *msg_ctx,
-			     const char *sharename)
-{
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	struct spoolss_SetPrinterInfo2 *info2;
-	struct security_descriptor *secdesc;
-	struct winreg_String wkey, wkeyclass;
-	const char *path;
-	const char *subkeys[] = { SPOOL_DSDRIVER_KEY, SPOOL_DSSPOOLER_KEY, SPOOL_PRINTERDATA_KEY };
-	uint32_t i, count = ARRAY_SIZE(subkeys);
-	uint32_t info2_mask = 0;
-	WERROR result = WERR_OK;
-	TALLOC_CTX *tmp_ctx;
-
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	path = winreg_printer_data_keyname(tmp_ctx, sharename);
-	if (path == NULL) {
-		TALLOC_FREE(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					"",
-					false,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("winreg_create_printer: Skipping, %s already exists\n", path));
-		goto done;
-	} else if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
-		DEBUG(2, ("winreg_create_printer: Creating default values in %s\n", path));
-	} else if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_create_printer: Could not open key %s: %s\n",
-			path, win_errstr(result)));
-		goto done;
-	}
-
-	/* Create the main key */
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					"",
-					true,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
-			path, win_errstr(result)));
-		goto done;
-	}
-
-	if (is_valid_policy_hnd(&key_hnd)) {
-		dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
-	}
-
-	/* Create subkeys */
-	for (i = 0; i < count; i++) {
-		NTSTATUS status;
-		enum winreg_CreateAction action = REG_ACTION_NONE;
-
-		ZERO_STRUCT(key_hnd);
-		ZERO_STRUCT(wkey);
-
-		wkey.name = talloc_asprintf(tmp_ctx, "%s\\%s", path, subkeys[i]);
-		if (wkey.name == NULL) {
-			result = WERR_NOMEM;
-			goto done;
-		}
-
-		ZERO_STRUCT(wkeyclass);
-		wkeyclass.name = "";
-
-		status = dcerpc_winreg_CreateKey(winreg_handle,
-						 tmp_ctx,
-						 &hive_hnd,
-						 wkey,
-						 wkeyclass,
-						 0,
-						 access_mask,
-						 NULL,
-						 &key_hnd,
-						 &action,
-						 &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
-				wkey.name, win_errstr(result)));
-			goto done;
-		}
-
-		if (strequal(subkeys[i], SPOOL_DSSPOOLER_KEY)) {
-			const char *dnssuffix;
-			const char *longname;
-			const char *uncname;
-
-			status = dcerpc_winreg_set_sz(tmp_ctx,
-						      winreg_handle,
-						      &key_hnd,
-						      SPOOL_REG_PRINTERNAME,
-						      sharename,
-						      &result);
-			if (!NT_STATUS_IS_OK(status)) {
-				result = ntstatus_to_werror(status);
-			}
-			if (!W_ERROR_IS_OK(result)) {
-				goto done;
-			}
-
-			status = dcerpc_winreg_set_sz(tmp_ctx,
-						      winreg_handle,
-						      &key_hnd,
-						      SPOOL_REG_SHORTSERVERNAME,
-						      global_myname(),
-						      &result);
-			if (!NT_STATUS_IS_OK(status)) {
-				result = ntstatus_to_werror(status);
-			}
-			if (!W_ERROR_IS_OK(result)) {
-				goto done;
-			}
-
-			/* We make the assumption that the netbios name
-			 * is the same as the DNS name since the former
-			 * will be what we used to join the domain
-			 */
-			dnssuffix = get_mydnsdomname(tmp_ctx);
-			if (dnssuffix != NULL && dnssuffix[0] != '\0') {
-				longname = talloc_asprintf(tmp_ctx, "%s.%s", global_myname(), dnssuffix);
-			} else {
-				longname = talloc_strdup(tmp_ctx, global_myname());
-			}
-			if (longname == NULL) {
-				result = WERR_NOMEM;
-				goto done;
-			}
-
-			status = dcerpc_winreg_set_sz(tmp_ctx,
-						      winreg_handle,
-						      &key_hnd,
-						      SPOOL_REG_SERVERNAME,
-						      longname,
-						      &result);
-			if (!NT_STATUS_IS_OK(status)) {
-				result = ntstatus_to_werror(status);
-			}
-			if (!W_ERROR_IS_OK(result)) {
-				goto done;
-			}
-
-			uncname = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
-						  longname, sharename);
-			if (uncname == NULL) {
-				result = WERR_NOMEM;
-				goto done;
-			}
-
-			status = dcerpc_winreg_set_sz(tmp_ctx,
-						      winreg_handle,
-						      &key_hnd,
-						      SPOOL_REG_UNCNAME,
-						      uncname,
-						      &result);
-			if (!NT_STATUS_IS_OK(status)) {
-				result = ntstatus_to_werror(status);
-			}
-			if (!W_ERROR_IS_OK(result)) {
-				goto done;
-			}
-
-			status = dcerpc_winreg_set_dword(tmp_ctx,
-							 winreg_handle,
-							 &key_hnd,
-							 SPOOL_REG_VERSIONNUMBER,
-							 4,
-							 &result);
-			if (!NT_STATUS_IS_OK(status)) {
-				result = ntstatus_to_werror(status);
-			}
-			if (!W_ERROR_IS_OK(result)) {
-				goto done;
-			}
-
-			status = dcerpc_winreg_set_dword(tmp_ctx,
-							 winreg_handle,
-							 &key_hnd,
-							 SPOOL_REG_PRINTSTARTTIME,
-							 0,
-							 &result);
-			if (!NT_STATUS_IS_OK(status)) {
-				result = ntstatus_to_werror(status);
-			}
-			if (!W_ERROR_IS_OK(result)) {
-				goto done;
-			}
-
-			status = dcerpc_winreg_set_dword(tmp_ctx,
-							 winreg_handle,
-							 &key_hnd,
-							 SPOOL_REG_PRINTENDTIME,
-							 0,
-							 &result);
-			if (!NT_STATUS_IS_OK(status)) {
-				result = ntstatus_to_werror(status);
-			}
-			if (!W_ERROR_IS_OK(result)) {
-				goto done;
-			}
-
-			status = dcerpc_winreg_set_dword(tmp_ctx,
-							 winreg_handle,
-							 &key_hnd,
-							 SPOOL_REG_PRIORITY,
-							 1,
-							 &result);
-			if (!NT_STATUS_IS_OK(status)) {
-				result = ntstatus_to_werror(status);
-			}
-			if (!W_ERROR_IS_OK(result)) {
-				goto done;
-			}
-
-			status = dcerpc_winreg_set_dword(tmp_ctx,
-							 winreg_handle,
-							 &key_hnd,
-							 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
-							 0,
-							 &result);
-			if (!NT_STATUS_IS_OK(status)) {
-				result = ntstatus_to_werror(status);
-			}
-			if (!W_ERROR_IS_OK(result)) {
-				goto done;
-			}
-		}
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
-		}
-	}
-	info2 = talloc_zero(tmp_ctx, struct spoolss_SetPrinterInfo2);
-	if (info2 == NULL) {
-		result = WERR_NOMEM;
-		goto done;
-	}
-
-	info2->printername = sharename;
-	if (info2->printername == NULL) {
-		result = WERR_NOMEM;
-		goto done;
-	}
-	info2_mask |= SPOOLSS_PRINTER_INFO_PRINTERNAME;
-
-	info2->sharename = sharename;
-	info2_mask |= SPOOLSS_PRINTER_INFO_SHARENAME;
-
-	info2->portname = SAMBA_PRINTER_PORT_NAME;
-	info2_mask |= SPOOLSS_PRINTER_INFO_PORTNAME;
-
-	info2->printprocessor = "winprint";
-	info2_mask |= SPOOLSS_PRINTER_INFO_PRINTPROCESSOR;
-
-	info2->datatype = "RAW";
-	info2_mask |= SPOOLSS_PRINTER_INFO_DATATYPE;
-
-	info2->comment = "";
-	info2_mask |= SPOOLSS_PRINTER_INFO_COMMENT;
-
-	info2->attributes = PRINTER_ATTRIBUTE_SAMBA;
-	info2_mask |= SPOOLSS_PRINTER_INFO_ATTRIBUTES;
-
-	info2->starttime = 0; /* Minutes since 12:00am GMT */
-	info2_mask |= SPOOLSS_PRINTER_INFO_STARTTIME;
-
-	info2->untiltime = 0; /* Minutes since 12:00am GMT */
-	info2_mask |= SPOOLSS_PRINTER_INFO_UNTILTIME;
-
-	info2->priority = 1;
-	info2_mask |= SPOOLSS_PRINTER_INFO_PRIORITY;
-
-	info2->defaultpriority = 1;
-	info2_mask |= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY;
-
-	result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-	info2_mask |= SPOOLSS_PRINTER_INFO_SECDESC;
-
-	/*
-	 * Don't write a default Device Mode to the registry! The Device Mode is
-	 * only written to disk with a SetPrinter level 2 or 8.
-	 */
-
-	result = winreg_update_printer(tmp_ctx,
-				       session_info,
-				       msg_ctx,
-				       sharename,
-				       info2_mask,
-				       info2,
-				       NULL,
-				       secdesc);
-
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	talloc_free(tmp_ctx);
-	return result;
-}
-
-WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
-			     const struct auth_serversupplied_info *session_info,
-			     struct messaging_context *msg_ctx,
-			     const char *sharename,
-			     uint32_t info2_mask,
-			     struct spoolss_SetPrinterInfo2 *info2,
-			     struct spoolss_DeviceMode *devmode,
-			     struct security_descriptor *secdesc)
-{
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	int snum = lp_servicenumber(sharename);
-	enum ndr_err_code ndr_err;
-	DATA_BLOB blob;
-	char *path;
-	WERROR result = WERR_OK;
-	NTSTATUS status;
-	TALLOC_CTX *tmp_ctx;
-
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	path = winreg_printer_data_keyname(tmp_ctx, sharename);
-	if (path == NULL) {
-		TALLOC_FREE(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					"",
-					true,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n",
-			path, win_errstr(result)));
-		goto done;
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_ATTRIBUTES) {
-		status = dcerpc_winreg_set_dword(tmp_ctx,
-						 winreg_handle,
-						 &key_hnd,
-						 "Attributes",
-						 info2->attributes,
-						 &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-#if 0
-	if (info2_mask & SPOOLSS_PRINTER_INFO_AVERAGEPPM) {
-		status = dcerpc_winreg_set_dword(tmp_ctx,
-						 winreg_handle,
-						 &key_hnd,
-						 "AveragePpm",
-						 info2->attributes,
-						 &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-#endif
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_COMMENT) {
-		status = dcerpc_winreg_set_sz(tmp_ctx,
-					      winreg_handle,
-					      &key_hnd,
-					      "Description",
-					      info2->comment,
-					      &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_DATATYPE) {
-		status = dcerpc_winreg_set_sz(tmp_ctx,
-					      winreg_handle,
-					      &key_hnd,
-					      "Datatype",
-					      info2->datatype,
-					      &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY) {
-		status = dcerpc_winreg_set_dword(tmp_ctx,
-						 winreg_handle,
-						 &key_hnd,
-						 "Default Priority",
-						 info2->defaultpriority,
-						 &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_DEVMODE) {
-		/*
-		 * Some client drivers freak out if there is a NULL devmode
-		 * (probably the driver is not checking before accessing
-		 * the devmode pointer)   --jerry
-		 */
-		if (devmode == NULL && lp_default_devmode(snum) && info2 != NULL) {
-			result = spoolss_create_default_devmode(tmp_ctx,
-								info2->printername,
-								&devmode);
-			if (!W_ERROR_IS_OK(result)) {
-				goto done;
-			}
-		}
-
-		if (devmode->size != (ndr_size_spoolss_DeviceMode(devmode, 0) - devmode->__driverextra_length)) {
-			result = WERR_INVALID_PARAM;
-			goto done;
-		}
-
-		ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, devmode,
-				(ndr_push_flags_fn_t) ndr_push_spoolss_DeviceMode);
-		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-			DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
-			result = WERR_NOMEM;
-			goto done;
-		}
-
-		status = dcerpc_winreg_set_binary(tmp_ctx,
-						  winreg_handle,
-						  &key_hnd,
-						  "Default DevMode",
-						  &blob,
-						  &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_DRIVERNAME) {
-		status = dcerpc_winreg_set_sz(tmp_ctx,
-					      winreg_handle,
-					      &key_hnd,
-					      "Printer Driver",
-					      info2->drivername,
-					      &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_LOCATION) {
-		status = dcerpc_winreg_set_sz(tmp_ctx,
-					      winreg_handle,
-					      &key_hnd,
-					      "Location",
-					      info2->location,
-					      &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_PARAMETERS) {
-		status = dcerpc_winreg_set_sz(tmp_ctx,
-					      winreg_handle,
-					      &key_hnd,
-					      "Parameters",
-					      info2->parameters,
-					      &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_PORTNAME) {
-		status = dcerpc_winreg_set_sz(tmp_ctx,
-					      winreg_handle,
-					      &key_hnd,
-					      "Port",
-					      info2->portname,
-					      &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTERNAME) {
-		/*
-		 * in addprinter: no servername and the printer is the name
-		 * in setprinter: servername is \\server
-		 *                and printer is \\server\\printer
-		 *
-		 * Samba manages only local printers.
-		 * we currently don't support things like i
-		 * path=\\other_server\printer
-		 *
-		 * We only store the printername, not \\server\printername
-		 */
-		const char *p = strrchr(info2->printername, '\\');
-		if (p == NULL) {
-			p = info2->printername;
-		} else {
-			p++;
-		}
-		status = dcerpc_winreg_set_sz(tmp_ctx,
-					      winreg_handle,
-					      &key_hnd,
-					      "Name",
-					      p,
-					      &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTPROCESSOR) {
-		status = dcerpc_winreg_set_sz(tmp_ctx,
-					      winreg_handle,
-					      &key_hnd,
-					      "Print Processor",
-					      info2->printprocessor,
-					      &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_PRIORITY) {
-		status = dcerpc_winreg_set_dword(tmp_ctx,
-						 winreg_handle,
-						 &key_hnd,
-						 "Priority",
-						 info2->priority,
-						 &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_SECDESC) {
-		/*
-		 * We need a security descriptor, if it isn't specified by
-		 * AddPrinter{Ex} then create a default descriptor.
-		 */
-		if (secdesc == NULL) {
-			result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
-			if (!W_ERROR_IS_OK(result)) {
-				goto done;
-			}
-		}
-		result = winreg_set_printer_secdesc(tmp_ctx,
-						    session_info,
-						    msg_ctx,
-						    sharename,
-						    secdesc);
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_SEPFILE) {
-		status = dcerpc_winreg_set_sz(tmp_ctx,
-					      winreg_handle,
-					      &key_hnd,
-					      "Separator File",
-					      info2->sepfile,
-					      &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_SHARENAME) {
-		status = dcerpc_winreg_set_sz(tmp_ctx,
-					      winreg_handle,
-					      &key_hnd,
-					      "Share Name",
-					      info2->sharename,
-					      &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_STARTTIME) {
-		status = dcerpc_winreg_set_dword(tmp_ctx,
-						 winreg_handle,
-						 &key_hnd,
-						 "StartTime",
-						 info2->starttime,
-						 &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_STATUS) {
-		status = dcerpc_winreg_set_dword(tmp_ctx,
-						 winreg_handle,
-						 &key_hnd,
-						 "Status",
-						 info2->status,
-						 &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2_mask & SPOOLSS_PRINTER_INFO_UNTILTIME) {
-		status = dcerpc_winreg_set_dword(tmp_ctx,
-						 winreg_handle,
-						 &key_hnd,
-						 "UntilTime",
-						 info2->untiltime,
-						 &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			result = ntstatus_to_werror(status);
-		}
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	status = dcerpc_winreg_set_dword(tmp_ctx,
-					 winreg_handle,
-					 &key_hnd,
-					 "ChangeID",
-					 winreg_printer_rev_changeid(),
-					 &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
-}
-
-WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
-			  const struct auth_serversupplied_info *session_info,
-			  struct messaging_context *msg_ctx,
-			  const char *printer,
-			  struct spoolss_PrinterInfo2 **pinfo2)
-{
-	struct spoolss_PrinterInfo2 *info2;
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	struct spoolss_PrinterEnumValues *enum_values = NULL;
-	struct spoolss_PrinterEnumValues *v = NULL;
-	enum ndr_err_code ndr_err;
-	DATA_BLOB blob;
-	int snum = lp_servicenumber(printer);
-	uint32_t num_values = 0;
-	uint32_t i;
-	char *path;
-	NTSTATUS status;
-	WERROR result = WERR_OK;
-	TALLOC_CTX *tmp_ctx;
-
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	path = winreg_printer_data_keyname(tmp_ctx, printer);
-	if (path == NULL) {
-		TALLOC_FREE(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					"",
-					false,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("winreg_get_printer: Could not open key %s: %s\n",
-			  path, win_errstr(result)));
-		goto done;
-	}
-
-	result = winreg_printer_enumvalues(tmp_ctx,
-					   winreg_handle,
-					   &key_hnd,
-					   &num_values,
-					   &enum_values);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n",
-			  path, win_errstr(result)));
-		goto done;
-	}
-
-	info2 = talloc_zero(tmp_ctx, struct spoolss_PrinterInfo2);
-	if (info2 == NULL) {
-		result = WERR_NOMEM;
-		goto done;
-	}
-
-	FILL_STRING(info2, EMPTY_STRING, info2->servername);
-	FILL_STRING(info2, EMPTY_STRING, info2->printername);
-	FILL_STRING(info2, EMPTY_STRING, info2->sharename);
-	FILL_STRING(info2, EMPTY_STRING, info2->portname);
-	FILL_STRING(info2, EMPTY_STRING, info2->drivername);
-	FILL_STRING(info2, EMPTY_STRING, info2->comment);
-	FILL_STRING(info2, EMPTY_STRING, info2->location);
-	FILL_STRING(info2, EMPTY_STRING, info2->sepfile);
-	FILL_STRING(info2, EMPTY_STRING, info2->printprocessor);
-	FILL_STRING(info2, EMPTY_STRING, info2->datatype);
-	FILL_STRING(info2, EMPTY_STRING, info2->parameters);
-
-	for (i = 0; i < num_values; i++) {
-		v = &enum_values[i];
-
-		result = winreg_enumval_to_sz(info2,
-					      v,
-					      "Name",
-					      &info2->printername);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info2,
-					      v,
-					      "Share Name",
-					      &info2->sharename);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info2,
-					      v,
-					      "Port",
-					      &info2->portname);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info2,
-					      v,
-					      "Description",
-					      &info2->comment);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info2,
-					      v,
-					      "Location",
-					      &info2->location);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info2,
-					      v,
-					      "Separator File",
-					      &info2->sepfile);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info2,
-					      v,
-					      "Print Processor",
-					      &info2->printprocessor);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info2,
-					      v,
-					      "Datatype",
-					      &info2->datatype);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info2,
-					      v,
-					      "Parameters",
-					      &info2->parameters);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info2,
-					      v,
-					      "Printer Driver",
-					      &info2->drivername);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_dword(info2,
-						 v,
-						 "Attributes",
-						 &info2->attributes);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_dword(info2,
-						 v,
-						 "Priority",
-						 &info2->priority);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_dword(info2,
-						 v,
-						 "Default Priority",
-						 &info2->defaultpriority);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_dword(info2,
-						 v,
-						 "StartTime",
-						 &info2->starttime);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_dword(info2,
-						 v,
-						 "UntilTime",
-						 &info2->untiltime);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_dword(info2,
-						 v,
-						 "Status",
-						 &info2->status);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_dword(info2,
-						 v,
-						 "StartTime",
-						 &info2->starttime);
-		CHECK_ERROR(result);
-	}
-
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
-					"for %s: %s\n",
-					v->value_name,
-					win_errstr(result)));
-		goto done;
-	}
-
-	/* Construct the Device Mode */
-	status = dcerpc_winreg_query_binary(tmp_ctx,
-					    winreg_handle,
-					    &key_hnd,
-					    "Default DevMode",
-					    &blob,
-					    &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (W_ERROR_IS_OK(result)) {
-		info2->devmode = talloc_zero(info2, struct spoolss_DeviceMode);
-		if (info2->devmode == NULL) {
-			result = WERR_NOMEM;
-			goto done;
-		}
-		ndr_err = ndr_pull_struct_blob(&blob,
-					       info2->devmode,
-					       info2->devmode,
-					       (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeviceMode);
-		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-			DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
-			result = WERR_NOMEM;
-			goto done;
-		}
-	}
-
-	if (info2->devmode == NULL && lp_default_devmode(snum)) {
-		result = spoolss_create_default_devmode(info2,
-							info2->printername,
-							&info2->devmode);
-		if (!W_ERROR_IS_OK(result)) {
-			goto done;
-		}
-	}
-
-	if (info2->devmode) {
-		info2->devmode->size = ndr_size_spoolss_DeviceMode(info2->devmode, 0) - info2->devmode->driverextra_data.length;
-	}
-
-	result = winreg_get_printer_secdesc(info2,
-					    session_info,
-					    msg_ctx,
+	return winreg_delete_printer_dataex(mem_ctx, b,
 					    printer,
-					    &info2->secdesc);
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	/* Fix for OS/2 drivers. */
-	if (get_remote_arch() == RA_OS2) {
-		spoolss_map_to_os2_driver(info2, &info2->drivername);
-	}
-
-	if (pinfo2) {
-		*pinfo2 = talloc_move(mem_ctx, &info2);
-	}
-
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
+					    key,
+					    value);
 }
 
-WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
+WERROR winreg_get_driver_internal(TALLOC_CTX *mem_ctx,
 				  const struct auth_serversupplied_info *session_info,
 				  struct messaging_context *msg_ctx,
-				  const char *sharename,
-				  struct spoolss_security_descriptor **psecdesc)
+				  const char *architecture,
+				  const char *driver_name,
+				  uint32_t driver_version,
+				  struct spoolss_DriverInfo8 **_info8)
 {
-	struct spoolss_security_descriptor *secdesc;
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	const char *path;
-	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status;
 	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	path = winreg_printer_data_keyname(tmp_ctx, sharename);
-	if (path == NULL) {
-		talloc_free(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					"",
-					false,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
-			goto create_default;
-		}
-		goto done;
-	}
-
-	status = dcerpc_winreg_query_sd(tmp_ctx,
-					winreg_handle,
-					&key_hnd,
-					"Security",
-					&secdesc,
-					&result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
-			goto create_default;
-		}
-		goto done;
-	}
-
-	if (psecdesc) {
-		*psecdesc = talloc_move(mem_ctx, &secdesc);
-	}
-
-	result = WERR_OK;
-	goto done;
-
-create_default:
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					"",
-					true,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	/* If security descriptor is owned by S-1-1-0 and winbindd is up,
-	   this security descriptor has been created when winbindd was
-	   down.  Take ownership of security descriptor. */
-	if (dom_sid_equal(secdesc->owner_sid, &global_sid_World)) {
-		struct dom_sid owner_sid;
-
-		/* Change sd owner to workgroup administrator */
-
-		if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
-			struct spoolss_security_descriptor *new_secdesc;
-			size_t size;
-
-			/* Create new sd */
-			sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
-
-			new_secdesc = make_sec_desc(tmp_ctx,
-						    secdesc->revision,
-						    secdesc->type,
-						    &owner_sid,
-						    secdesc->group_sid,
-						    secdesc->sacl,
-						    secdesc->dacl,
-						    &size);
-
-			if (new_secdesc == NULL) {
-				result = WERR_NOMEM;
-				goto done;
-			}
-
-			/* Swap with other one */
-			secdesc = new_secdesc;
-		}
-	}
-
-	status = dcerpc_winreg_set_sd(tmp_ctx,
-					  winreg_handle,
-					  &key_hnd,
-					  "Security",
-					  secdesc,
-					  &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		return result;
-	}
-
-	if (psecdesc) {
-		*psecdesc = talloc_move(mem_ctx, &secdesc);
-	}
-
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	talloc_free(tmp_ctx);
-	return result;
+	return winreg_get_driver(mem_ctx, b,
+				 architecture,
+				 driver_name,
+				 driver_version,
+				 _info8);
 }
 
-WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
-				  const struct auth_serversupplied_info *session_info,
-				  struct messaging_context *msg_ctx,
-				  const char *sharename,
-				  const struct spoolss_security_descriptor *secdesc)
+WERROR winreg_get_driver_list_internal(TALLOC_CTX *mem_ctx,
+				       const struct auth_serversupplied_info *session_info,
+				       struct messaging_context *msg_ctx,
+				       const char *architecture,
+				       uint32_t version,
+				       uint32_t *num_drivers,
+				       const char ***drivers_p)
 {
-	const struct spoolss_security_descriptor *new_secdesc = secdesc;
-	struct spoolss_security_descriptor *old_secdesc;
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	const char *path;
-	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status;
 	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	path = winreg_printer_data_keyname(tmp_ctx, sharename);
-	if (path == NULL) {
-		talloc_free(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	/*
-	 * The old owner and group sids of the security descriptor are not
-	 * present when new ACEs are added or removed by changing printer
-	 * permissions through NT.  If they are NULL in the new security
-	 * descriptor then copy them over from the old one.
-	 */
-	if (!secdesc->owner_sid || !secdesc->group_sid) {
-		struct dom_sid *owner_sid, *group_sid;
-		struct security_acl *dacl, *sacl;
-		size_t size;
-
-		result = winreg_get_printer_secdesc(tmp_ctx,
-						    session_info,
-						    msg_ctx,
-						    sharename,
-						    &old_secdesc);
-		if (!W_ERROR_IS_OK(result)) {
-			talloc_free(tmp_ctx);
-			return result;
-		}
-
-		/* Pick out correct owner and group sids */
-		owner_sid = secdesc->owner_sid ?
-			    secdesc->owner_sid :
-			    old_secdesc->owner_sid;
-
-		group_sid = secdesc->group_sid ?
-			    secdesc->group_sid :
-			    old_secdesc->group_sid;
-
-		dacl = secdesc->dacl ?
-		       secdesc->dacl :
-		       old_secdesc->dacl;
-
-		sacl = secdesc->sacl ?
-		       secdesc->sacl :
-		       old_secdesc->sacl;
-
-		/* Make a deep copy of the security descriptor */
-		new_secdesc = make_sec_desc(tmp_ctx,
-					    secdesc->revision,
-					    secdesc->type,
-					    owner_sid,
-					    group_sid,
-					    sacl,
-					    dacl,
-					    &size);
-		if (new_secdesc == NULL) {
-			talloc_free(tmp_ctx);
-			return WERR_NOMEM;
-		}
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					"",
-					false,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sd(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "Security",
-				      new_secdesc,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	talloc_free(tmp_ctx);
-	return result;
+	return winreg_get_driver_list(mem_ctx, b,
+				      architecture,
+				      version,
+				      num_drivers,
+				      drivers_p);
 }
 
-/* Set printer data over the winreg pipe. */
-WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
-				 const struct auth_serversupplied_info *session_info,
-				 struct messaging_context *msg_ctx,
-				 const char *printer,
-				 const char *key,
-				 const char *value,
-				 enum winreg_Type type,
-				 uint8_t *data,
-				 uint32_t data_size)
-{
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	struct winreg_String wvalue = { 0, };
-	char *path;
-	WERROR result = WERR_OK;
-	NTSTATUS status;
-	TALLOC_CTX *tmp_ctx;
-
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	path = winreg_printer_data_keyname(tmp_ctx, printer);
-	if (path == NULL) {
-		TALLOC_FREE(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n",
-			key, value, access_mask, printer));
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					key,
-					true,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n",
-			  key, win_errstr(result)));
-		goto done;
-	}
-
-	wvalue.name = value;
-	status = dcerpc_winreg_SetValue(winreg_handle,
-					tmp_ctx,
-					&key_hnd,
-					wvalue,
-					type,
-					data,
-					data_size,
-					&result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n",
-			  value, nt_errstr(status)));
-		result = ntstatus_to_werror(status);
-	}
-
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
-}
-
-/* Get printer data over a winreg pipe. */
-WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
-				 const struct auth_serversupplied_info *session_info,
-				 struct messaging_context *msg_ctx,
-				 const char *printer,
-				 const char *key,
-				 const char *value,
-				 enum winreg_Type *type,
-				 uint8_t **data,
-				 uint32_t *data_size)
-{
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	struct winreg_String wvalue;
-	enum winreg_Type type_in;
-	char *path;
-	uint8_t *data_in;
-	uint32_t data_in_size = 0;
-	uint32_t value_len = 0;
-	WERROR result = WERR_OK;
-	NTSTATUS status;
-	TALLOC_CTX *tmp_ctx;
-
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	path = winreg_printer_data_keyname(tmp_ctx, printer);
-	if (path == NULL) {
-		TALLOC_FREE(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					key,
-					false,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
-			  key, win_errstr(result)));
-		goto done;
-	}
-
-	wvalue.name = value;
-
-	/*
-	 * call QueryValue once with data == NULL to get the
-	 * needed memory size to be allocated, then allocate
-	 * data buffer and call again.
-	 */
-	status = dcerpc_winreg_QueryValue(winreg_handle,
-					  tmp_ctx,
-					  &key_hnd,
-					  &wvalue,
-					  &type_in,
-					  NULL,
-					  &data_in_size,
-					  &value_len,
-					  &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
-			  value, nt_errstr(status)));
-		result = ntstatus_to_werror(status);
-		goto done;
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size);
-	if (data_in == NULL) {
-		result = WERR_NOMEM;
-		goto done;
-	}
-	value_len = 0;
-
-	status = dcerpc_winreg_QueryValue(winreg_handle,
-					  tmp_ctx,
-					  &key_hnd,
-					  &wvalue,
-					  &type_in,
-					  data_in,
-					  &data_in_size,
-					  &value_len,
-					  &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
-			  value, nt_errstr(status)));
-		result = ntstatus_to_werror(status);
-		goto done;
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	*type = type_in;
-	*data_size = data_in_size;
-	if (data_in_size) {
-		*data = talloc_move(mem_ctx, &data_in);
-	}
-
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
-}
-
-/* Enumerate on the values of a given key and provide the data. */
-WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
+WERROR winreg_del_driver_internal(TALLOC_CTX *mem_ctx,
 				  const struct auth_serversupplied_info *session_info,
 				  struct messaging_context *msg_ctx,
-				  const char *printer,
-				  const char *key,
-				  uint32_t *pnum_values,
-				  struct spoolss_PrinterEnumValues **penum_values)
+				  struct spoolss_DriverInfo8 *info8,
+				  uint32_t version)
 {
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-
-	struct spoolss_PrinterEnumValues *enum_values = NULL;
-	uint32_t num_values = 0;
-	char *path;
-	WERROR result = WERR_OK;
-
-	TALLOC_CTX *tmp_ctx;
-
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	path = winreg_printer_data_keyname(tmp_ctx, printer);
-	if (path == NULL) {
-		TALLOC_FREE(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					key,
-					false,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
-			  key, win_errstr(result)));
-		goto done;
-	}
-
-	result = winreg_printer_enumvalues(tmp_ctx,
-					   winreg_handle,
-					   &key_hnd,
-					   &num_values,
-					   &enum_values);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
-			  key, win_errstr(result)));
-		goto done;
-	}
-
-	*pnum_values = num_values;
-	if (penum_values) {
-		*penum_values = talloc_move(mem_ctx, &enum_values);
-	}
-
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
-}
-
-/* Delete printer data over a winreg pipe. */
-WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx,
-				    const struct auth_serversupplied_info *session_info,
-				    struct messaging_context *msg_ctx,
-				    const char *printer,
-				    const char *key,
-				    const char *value)
-{
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	struct winreg_String wvalue = { 0, };
-	char *path;
-	WERROR result = WERR_OK;
-	NTSTATUS status;
-
-	TALLOC_CTX *tmp_ctx;
-
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	path = winreg_printer_data_keyname(tmp_ctx, printer);
-	if (path == NULL) {
-		TALLOC_FREE(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					key,
-					false,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n",
-			  key, win_errstr(result)));
-		goto done;
-	}
-
-	wvalue.name = value;
-	status = dcerpc_winreg_DeleteValue(winreg_handle,
-					   tmp_ctx,
-					   &key_hnd,
-					   wvalue,
-					   &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n",
-			  value, nt_errstr(status)));
-		result = ntstatus_to_werror(status);
-	}
-
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
-}
-
-/* Enumerate on the subkeys of a given key and provide the data. */
-WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
-			       const struct auth_serversupplied_info *session_info,
-			       struct messaging_context *msg_ctx,
-			       const char *printer,
-			       const char *key,
-			       uint32_t *pnum_subkeys,
-			       const char ***psubkeys)
-{
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	char *path;
-	const char **subkeys = NULL;
-	uint32_t num_subkeys = -1;
-
-	WERROR result = WERR_OK;
-	NTSTATUS status;
-
-	TALLOC_CTX *tmp_ctx;
-
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	path = winreg_printer_data_keyname(tmp_ctx, printer);
-	if (path == NULL) {
-		TALLOC_FREE(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					key,
-					false,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("winreg_enum_printer_key: Could not open key %s: %s\n",
-			  key, win_errstr(result)));
-		goto done;
-	}
-
-	status = dcerpc_winreg_enum_keys(tmp_ctx,
-					 winreg_handle,
-					 &key_hnd,
-					 &num_subkeys,
-					 &subkeys,
-					 &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n",
-			  key, win_errstr(result)));
-		goto done;
-	}
-
-	*pnum_subkeys = num_subkeys;
-	if (psubkeys) {
-		*psubkeys = talloc_move(mem_ctx, &subkeys);
-	}
-
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
-}
-
-/* Delete a key with subkeys of a given printer. */
-WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx,
-				 const struct auth_serversupplied_info *session_info,
-				 struct messaging_context *msg_ctx,
-				 const char *printer,
-				 const char *key)
-{
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	char *keyname;
-	char *path;
 	WERROR result;
-	TALLOC_CTX *tmp_ctx;
+	struct dcerpc_binding_handle *b;
 
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	path = winreg_printer_data_keyname(tmp_ctx, printer);
-	if (path == NULL) {
-		TALLOC_FREE(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					key,
-					false,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		/* key doesn't exist */
-		if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
-			result = WERR_OK;
-			goto done;
-		}
-
-		DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
-			  key, win_errstr(result)));
-		goto done;
-	}
-
-	if (is_valid_policy_hnd(&key_hnd)) {
-		dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
-	}
-
-	if (key == NULL || key[0] == '\0') {
-		keyname = path;
-	} else {
-		keyname = talloc_asprintf(tmp_ctx,
-					  "%s\\%s",
-					  path,
-					  key);
-		if (keyname == NULL) {
-			result = WERR_NOMEM;
-			goto done;
-		}
-	}
-
-	result = winreg_printer_delete_subkeys(tmp_ctx,
-					       winreg_handle,
-					       &hive_hnd,
-					       access_mask,
-					       keyname);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
-			  key, win_errstr(result)));
-		goto done;
-	}
-
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
+	return winreg_del_driver(mem_ctx, b,
+				 info8,
+				 version);
 }
 
-WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx,
-				      const struct auth_serversupplied_info *session_info,
-				      struct messaging_context *msg_ctx,
-				      const char *printer)
+WERROR winreg_add_driver_internal(TALLOC_CTX *mem_ctx,
+				  const struct auth_serversupplied_info *session_info,
+				  struct messaging_context *msg_ctx,
+				  struct spoolss_AddDriverInfoCtr *r,
+				  const char **driver_name,
+				  uint32_t *driver_version)
 {
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	char *path;
-	NTSTATUS status;
 	WERROR result;
-	TALLOC_CTX *tmp_ctx;
+	struct dcerpc_binding_handle *b;
 
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	path = winreg_printer_data_keyname(tmp_ctx, printer);
-	if (path == NULL) {
-		TALLOC_FREE(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					"",
-					false,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_printer_update_changeid: Could not open key %s: %s\n",
-			  path, win_errstr(result)));
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_dword(tmp_ctx,
-					 winreg_handle,
-					 &key_hnd,
-					 "ChangeID",
-					 winreg_printer_rev_changeid(),
-					 &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
+	return winreg_add_driver(mem_ctx, b,
+				 r,
+				 driver_name,
+				 driver_version);
 }
 
-WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
-				   const struct auth_serversupplied_info *session_info,
-				   struct messaging_context *msg_ctx,
-				   const char *printer,
-				   uint32_t *pchangeid)
+WERROR winreg_get_printer_secdesc_internal(TALLOC_CTX *mem_ctx,
+					   const struct auth_serversupplied_info *session_info,
+					   struct messaging_context *msg_ctx,
+					   const char *sharename,
+					   struct spoolss_security_descriptor **psecdesc)
 {
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	uint32_t changeid = 0;
-	char *path;
-	NTSTATUS status;
 	WERROR result;
-	TALLOC_CTX *tmp_ctx;
+	struct dcerpc_binding_handle *b;
 
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	path = winreg_printer_data_keyname(tmp_ctx, printer);
-	if (path == NULL) {
-		TALLOC_FREE(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					path,
-					"",
-					false,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
-			  path, win_errstr(result)));
-		goto done;
-	}
-
-	DEBUG(10, ("winreg_printer_get_changeid: get changeid from %s\n", path));
-
-	status = dcerpc_winreg_query_dword(tmp_ctx,
-					   winreg_handle,
-					   &key_hnd,
-					   "ChangeID",
-					   &changeid,
-					   &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	if (pchangeid) {
-		*pchangeid = changeid;
-	}
-
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
+	return winreg_get_printer_secdesc(mem_ctx, b,
+					  sharename,
+					  psecdesc);
 }
 
-/*
- * The special behaviour of the spoolss forms is documented at the website:
- *
- * Managing Win32 Printserver Forms
- * http://unixwiz.net/techtips/winspooler-forms.html
- */
-
-WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx,
-			       const struct auth_serversupplied_info *session_info,
-			       struct messaging_context *msg_ctx,
-			       struct spoolss_AddFormInfo1 *form)
+WERROR winreg_set_printer_secdesc_internal(TALLOC_CTX *mem_ctx,
+					   const struct auth_serversupplied_info *session_info,
+					   struct messaging_context *msg_ctx,
+					   const char *sharename,
+					   const struct spoolss_security_descriptor *secdesc)
 {
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	struct winreg_String wvalue = { 0, };
-	DATA_BLOB blob;
-	uint32_t num_info = 0;
-	union spoolss_FormInfo *info = NULL;
-	uint32_t i;
 	WERROR result;
-	NTSTATUS status;
-	TALLOC_CTX *tmp_ctx;
+	struct dcerpc_binding_handle *b;
 
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					TOP_LEVEL_CONTROL_FORMS_KEY,
-					"",
-					true,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n",
-			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
-		goto done;
-	}
-
-	result = winreg_printer_enumforms1(tmp_ctx, session_info, msg_ctx,
-					   &num_info, &info);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n",
-			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
-		goto done;
-	}
-
-	/* If form name already exists or is builtin return ALREADY_EXISTS */
-	for (i = 0; i < num_info; i++) {
-		if (strequal(info[i].info1.form_name, form->form_name)) {
-			result = WERR_FILE_EXISTS;
-			goto done;
-		}
-	}
-
-	wvalue.name = form->form_name;
-
-	blob = data_blob_talloc(tmp_ctx, NULL, 32);
-	SIVAL(blob.data,  0, form->size.width);
-	SIVAL(blob.data,  4, form->size.height);
-	SIVAL(blob.data,  8, form->area.left);
-	SIVAL(blob.data, 12, form->area.top);
-	SIVAL(blob.data, 16, form->area.right);
-	SIVAL(blob.data, 20, form->area.bottom);
-	SIVAL(blob.data, 24, num_info + 1); /* FIXME */
-	SIVAL(blob.data, 28, form->flags);
-
-	status = dcerpc_winreg_SetValue(winreg_handle,
-					tmp_ctx,
-					&key_hnd,
-					wvalue,
-					REG_BINARY,
-					blob.data,
-					blob.length,
-					&result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n",
-			  wvalue.name, nt_errstr(status)));
-		result = ntstatus_to_werror(status);
-	}
-
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(info);
-	TALLOC_FREE(tmp_ctx);
-	return result;
+	return winreg_set_printer_secdesc(mem_ctx, b,
+					  sharename,
+					  secdesc);
 }
 
-WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
-				 const struct auth_serversupplied_info *session_info,
-				 struct messaging_context *msg_ctx,
-				 uint32_t *pnum_info,
-				 union spoolss_FormInfo **pinfo)
+WERROR winreg_printer_enumforms1_internal(TALLOC_CTX *mem_ctx,
+					  const struct auth_serversupplied_info *session_info,
+					  struct messaging_context *msg_ctx,
+					  uint32_t *pnum_info,
+					  union spoolss_FormInfo **pinfo)
 {
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	union spoolss_FormInfo *info;
-	struct spoolss_PrinterEnumValues *enum_values = NULL;
-	uint32_t num_values = 0;
-	uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
-	uint32_t i;
 	WERROR result;
-	TALLOC_CTX *tmp_ctx;
+	struct dcerpc_binding_handle *b;
 
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					TOP_LEVEL_CONTROL_FORMS_KEY,
-					"",
-					true,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		/* key doesn't exist */
-		if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
-			result = WERR_OK;
-			goto done;
-		}
-
-		DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n",
-			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
-		goto done;
-	}
-
-	result = winreg_printer_enumvalues(tmp_ctx,
-					   winreg_handle,
-					   &key_hnd,
-					   &num_values,
-					   &enum_values);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
-			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
-		goto done;
-	}
-
-	info = TALLOC_ARRAY(tmp_ctx, union spoolss_FormInfo, num_builtin + num_values);
-	if (info == NULL) {
-		result = WERR_NOMEM;
-		goto done;
-	}
-
-	/* Enumerate BUILTIN forms */
-	for (i = 0; i < num_builtin; i++) {
-		info[i].info1 = builtin_forms1[i];
-	}
-
-	/* Enumerate registry forms */
-	for (i = 0; i < num_values; i++) {
-		union spoolss_FormInfo val;
-
-		if (enum_values[i].type != REG_BINARY ||
-		    enum_values[i].data_length != 32) {
-			continue;
-		}
-
-		val.info1.form_name = talloc_strdup(info, enum_values[i].value_name);
-		if (val.info1.form_name == NULL) {
-			result = WERR_NOMEM;
-			goto done;
-		}
-
-		val.info1.size.width  = IVAL(enum_values[i].data->data,  0);
-		val.info1.size.height = IVAL(enum_values[i].data->data,  4);
-		val.info1.area.left   = IVAL(enum_values[i].data->data,  8);
-		val.info1.area.top    = IVAL(enum_values[i].data->data, 12);
-		val.info1.area.right  = IVAL(enum_values[i].data->data, 16);
-		val.info1.area.bottom = IVAL(enum_values[i].data->data, 20);
-		/* skip form index      IVAL(enum_values[i].data->data, 24)));*/
-		val.info1.flags       = (enum spoolss_FormFlags) IVAL(enum_values[i].data->data, 28);
-
-		info[i + num_builtin] = val;
-	}
-
-	*pnum_info = num_builtin + num_values;
-	if (pinfo) {
-		*pinfo = talloc_move(mem_ctx, &info);
-	}
-
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(enum_values);
-	TALLOC_FREE(tmp_ctx);
-	return result;
+	return winreg_printer_enumforms1(mem_ctx, b,
+					 pnum_info,
+					 pinfo);
 }
 
-WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx,
-				  const struct auth_serversupplied_info *session_info,
-				  struct messaging_context *msg_ctx,
-				  const char *form_name)
+WERROR winreg_printer_getform1_internal(TALLOC_CTX *mem_ctx,
+					const struct auth_serversupplied_info *session_info,
+					struct messaging_context *msg_ctx,
+					const char *form_name,
+					struct spoolss_FormInfo1 *r)
 {
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	struct winreg_String wvalue = { 0, };
-	uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
-	uint32_t i;
-	WERROR result = WERR_OK;
-	NTSTATUS status;
-	TALLOC_CTX *tmp_ctx;
-
-	for (i = 0; i < num_builtin; i++) {
-		if (strequal(builtin_forms1[i].form_name, form_name)) {
-			return WERR_INVALID_PARAMETER;
-		}
-	}
-
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					TOP_LEVEL_CONTROL_FORMS_KEY,
-					"",
-					false,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n",
-			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
-		if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
-			result = WERR_INVALID_FORM_NAME;
-		}
-		goto done;
-	}
-
-	wvalue.name = form_name;
-	status = dcerpc_winreg_DeleteValue(winreg_handle,
-					   tmp_ctx,
-					   &key_hnd,
-					   wvalue,
-					   &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		/* If the value doesn't exist, return WERR_INVALID_FORM_NAME */
-		DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n",
-			  wvalue.name, nt_errstr(status)));
-		result = ntstatus_to_werror(status);
-		goto done;
-	}
-
-	if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
-		result = WERR_INVALID_FORM_NAME;
-	}
-
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
-}
-
-WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx,
-			       const struct auth_serversupplied_info *session_info,
-			       struct messaging_context *msg_ctx,
-			       const char *form_name,
-			       struct spoolss_AddFormInfo1 *form)
-{
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	struct winreg_String wvalue = { 0, };
-	DATA_BLOB blob;
-	uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
-	uint32_t i;
 	WERROR result;
-	NTSTATUS status;
-	TALLOC_CTX *tmp_ctx = NULL;
+	struct dcerpc_binding_handle *b;
 
-	for (i = 0; i < num_builtin; i++) {
-		if (strequal(builtin_forms1[i].form_name, form->form_name)) {
-			result = WERR_INVALID_PARAM;
-			goto done;
-		}
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					TOP_LEVEL_CONTROL_FORMS_KEY,
-					"",
-					true,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
-			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
-		goto done;
-	}
-
-	/* If form_name != form->form_name then we renamed the form */
-	if (strequal(form_name, form->form_name)) {
-		result = winreg_printer_deleteform1(tmp_ctx, session_info,
-						    msg_ctx, form_name);
-		if (!W_ERROR_IS_OK(result)) {
-			DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
-				  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
-			goto done;
-		}
-	}
-
-	wvalue.name = form->form_name;
-
-	blob = data_blob_talloc(tmp_ctx, NULL, 32);
-	SIVAL(blob.data,  0, form->size.width);
-	SIVAL(blob.data,  4, form->size.height);
-	SIVAL(blob.data,  8, form->area.left);
-	SIVAL(blob.data, 12, form->area.top);
-	SIVAL(blob.data, 16, form->area.right);
-	SIVAL(blob.data, 20, form->area.bottom);
-	SIVAL(blob.data, 24, 42);
-	SIVAL(blob.data, 28, form->flags);
-
-	status = dcerpc_winreg_SetValue(winreg_handle,
-					tmp_ctx,
-					&key_hnd,
-					wvalue,
-					REG_BINARY,
-					blob.data,
-					blob.length,
-					&result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n",
-			  wvalue.name, nt_errstr(status)));
-		result = ntstatus_to_werror(status);
-	}
-
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
+	return winreg_printer_getform1(mem_ctx, b,
+				       form_name,
+				       r);
 }
 
-WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
-			       const struct auth_serversupplied_info *session_info,
-			       struct messaging_context *msg_ctx,
-			       const char *form_name,
-			       struct spoolss_FormInfo1 *r)
+WERROR winreg_printer_addform1_internal(TALLOC_CTX *mem_ctx,
+					const struct auth_serversupplied_info *session_info,
+					struct messaging_context *msg_ctx,
+					struct spoolss_AddFormInfo1 *form)
 {
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	struct winreg_String wvalue;
-	enum winreg_Type type_in;
-	uint8_t *data_in;
-	uint32_t data_in_size = 0;
-	uint32_t value_len = 0;
-	uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
-	uint32_t i;
 	WERROR result;
-	NTSTATUS status;
-	TALLOC_CTX *tmp_ctx;
+	struct dcerpc_binding_handle *b;
 
-	/* check builtin forms first */
-	for (i = 0; i < num_builtin; i++) {
-		if (strequal(builtin_forms1[i].form_name, form_name)) {
-			*r = builtin_forms1[i];
-			return WERR_OK;
-		}
-	}
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	result = winreg_printer_openkey(tmp_ctx,
-					session_info,
-					msg_ctx,
-					&winreg_handle,
-					TOP_LEVEL_CONTROL_FORMS_KEY,
-					"",
-					true,
-					access_mask,
-					&hive_hnd,
-					&key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(2, ("winreg_printer_getform1: Could not open key %s: %s\n",
-			  TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
-		goto done;
-	}
-
-	wvalue.name = form_name;
-
-	/*
-	 * call QueryValue once with data == NULL to get the
-	 * needed memory size to be allocated, then allocate
-	 * data buffer and call again.
-	 */
-	status = dcerpc_winreg_QueryValue(winreg_handle,
-					  tmp_ctx,
-					  &key_hnd,
-					  &wvalue,
-					  &type_in,
-					  NULL,
-					  &data_in_size,
-					  &value_len,
-					  &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
-			  wvalue.name, nt_errstr(status)));
-		result = ntstatus_to_werror(status);
-		goto done;
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size);
-	if (data_in == NULL) {
-		result = WERR_NOMEM;
-		goto done;
-	}
-	value_len = 0;
-
-	status = dcerpc_winreg_QueryValue(winreg_handle,
-					  tmp_ctx,
-					  &key_hnd,
-					  &wvalue,
-					  &type_in,
-					  data_in,
-					  &data_in_size,
-					  &value_len,
-					  &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
-			  wvalue.name, nt_errstr(status)));
-		result = ntstatus_to_werror(status);
-		goto done;
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	r->form_name = talloc_strdup(mem_ctx, form_name);
-	if (r->form_name == NULL) {
-		result = WERR_NOMEM;
-		goto done;
-	}
-
-	r->size.width  = IVAL(data_in,  0);
-	r->size.height = IVAL(data_in,  4);
-	r->area.left   = IVAL(data_in,  8);
-	r->area.top    = IVAL(data_in, 12);
-	r->area.right  = IVAL(data_in, 16);
-	r->area.bottom = IVAL(data_in, 20);
-	/* skip index    IVAL(data_in, 24)));*/
-	r->flags       = (enum spoolss_FormFlags) IVAL(data_in, 28);
-
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
+	return winreg_printer_addform1(mem_ctx, b,
+				       form);
 }
 
-WERROR winreg_add_driver(TALLOC_CTX *mem_ctx,
-			 const struct auth_serversupplied_info *session_info,
-			 struct messaging_context *msg_ctx,
-			 struct spoolss_AddDriverInfoCtr *r,
-			 const char **driver_name,
-			 uint32_t *driver_version)
+WERROR winreg_printer_setform1_internal(TALLOC_CTX *mem_ctx,
+					const struct auth_serversupplied_info *session_info,
+					struct messaging_context *msg_ctx,
+					const char *form_name,
+					struct spoolss_AddFormInfo1 *form)
 {
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	struct spoolss_DriverInfo8 info8;
-	TALLOC_CTX *tmp_ctx = NULL;
-	NTSTATUS status;
 	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-	ZERO_STRUCT(info8);
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	if (!driver_info_ctr_to_info8(r, &info8)) {
-		result = WERR_INVALID_PARAMETER;
-		goto done;
-	}
-
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	result = winreg_printer_opendriver(tmp_ctx,
-					   session_info,
-					   msg_ctx,
-					   info8.driver_name,
-					   info8.architecture,
-					   info8.version,
-					   access_mask, true,
-					   &winreg_handle,
-					   &hive_hnd,
-					   &key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_add_driver: "
-			  "Could not open driver key (%s,%s,%d): %s\n",
-			  info8.driver_name, info8.architecture,
-			  info8.version, win_errstr(result)));
-		goto done;
-	}
-
-	/* TODO: "Attributes" ? */
-
-	status = dcerpc_winreg_set_dword(tmp_ctx,
-					 winreg_handle,
-					 &key_hnd,
-					 "Version",
-					 info8.version,
-					 &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "Driver",
-				      info8.driver_path,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "Data File",
-				      info8.data_file,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "Configuration File",
-				      info8.config_file,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "Help File",
-				      info8.help_file,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_multi_sz(tmp_ctx,
-					    winreg_handle,
-					    &key_hnd,
-					    "Dependent Files",
-					    info8.dependent_files,
-					    &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "Monitor",
-				      info8.monitor_name,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "Datatype",
-				      info8.default_datatype,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_multi_sz(tmp_ctx,
-					    winreg_handle,
-					    &key_hnd, "Previous Names",
-					    info8.previous_names,
-					    &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	result = winreg_printer_write_date(tmp_ctx, winreg_handle,
-					   &key_hnd, "DriverDate",
-					   info8.driver_date);
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	result = winreg_printer_write_ver(tmp_ctx, winreg_handle,
-					  &key_hnd, "DriverVersion",
-					  info8.driver_version);
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "Manufacturer",
-				      info8.manufacturer_name,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "OEM URL",
-				      info8.manufacturer_url,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "HardwareID",
-				      info8.hardware_id,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "Provider",
-				      info8.provider,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "Print Processor",
-				      info8.print_processor,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "VendorSetup",
-				      info8.vendor_setup,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_multi_sz(tmp_ctx,
-					    winreg_handle,
-					    &key_hnd,
-					    "Color Profiles",
-					    info8.color_profiles,
-					    &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_sz(tmp_ctx,
-				      winreg_handle,
-				      &key_hnd,
-				      "InfPath",
-				      info8.inf_path,
-				      &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_dword(tmp_ctx,
-					 winreg_handle,
-					 &key_hnd,
-					 "PrinterDriverAttributes",
-					 info8.printer_driver_attributes,
-					 &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	status = dcerpc_winreg_set_multi_sz(tmp_ctx,
-					    winreg_handle,
-					    &key_hnd,
-					    "CoreDependencies",
-					    info8.core_driver_dependencies,
-					    &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	result = winreg_printer_write_date(tmp_ctx, winreg_handle,
-					   &key_hnd, "MinInboxDriverVerDate",
-					   info8.min_inbox_driver_ver_date);
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	result = winreg_printer_write_ver(tmp_ctx, winreg_handle, &key_hnd,
-					  "MinInboxDriverVerVersion",
-					  info8.min_inbox_driver_ver_version);
-	if (!W_ERROR_IS_OK(result)) {
-		goto done;
-	}
-
-	*driver_name = info8.driver_name;
-	*driver_version = info8.version;
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
+	return winreg_printer_setform1(mem_ctx, b,
+				       form_name,
+				       form);
 }
 
-WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
-			 const struct auth_serversupplied_info *session_info,
-			 struct messaging_context *msg_ctx,
-			 const char *architecture,
-			 const char *driver_name,
-			 uint32_t driver_version,
-			 struct spoolss_DriverInfo8 **_info8)
+WERROR winreg_printer_deleteform1_internal(TALLOC_CTX *mem_ctx,
+					   const struct auth_serversupplied_info *session_info,
+					   struct messaging_context *msg_ctx,
+					   const char *form_name)
 {
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	struct spoolss_DriverInfo8 i8, *info8;
-	struct spoolss_PrinterEnumValues *enum_values = NULL;
-	struct spoolss_PrinterEnumValues *v;
-	uint32_t num_values = 0;
-	TALLOC_CTX *tmp_ctx;
 	WERROR result;
-	uint32_t i;
+	struct dcerpc_binding_handle *b;
 
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-	ZERO_STRUCT(i8);
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	if (driver_version == DRIVER_ANY_VERSION) {
-		/* look for Win2k first and then for NT4 */
-		result = winreg_printer_opendriver(tmp_ctx,
-						   session_info,
-						   msg_ctx,
-						   driver_name,
-						   architecture,
-						   3,
-						   access_mask, false,
-						   &winreg_handle,
-						   &hive_hnd,
-						   &key_hnd);
-		if (!W_ERROR_IS_OK(result)) {
-			result = winreg_printer_opendriver(tmp_ctx,
-							   session_info,
-							   msg_ctx,
-							   driver_name,
-							   architecture,
-							   2,
-							   access_mask, false,
-							   &winreg_handle,
-							   &hive_hnd,
-							   &key_hnd);
-		}
-	} else {
-		/* ok normal case */
-		result = winreg_printer_opendriver(tmp_ctx,
-						   session_info,
-						   msg_ctx,
-						   driver_name,
-						   architecture,
-						   driver_version,
-						   access_mask, false,
-						   &winreg_handle,
-						   &hive_hnd,
-						   &key_hnd);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(5, ("winreg_get_driver: "
-			  "Could not open driver key (%s,%s,%d): %s\n",
-			  driver_name, architecture,
-			  driver_version, win_errstr(result)));
-		goto done;
-	}
-
-	result = winreg_printer_enumvalues(tmp_ctx,
-					   winreg_handle,
-					   &key_hnd,
-					   &num_values,
-					   &enum_values);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_get_driver: "
-			  "Could not enumerate values for (%s,%s,%d): %s\n",
-			  driver_name, architecture,
-			  driver_version, win_errstr(result)));
-		goto done;
-	}
-
-	info8 = talloc_zero(tmp_ctx, struct spoolss_DriverInfo8);
-	if (info8 == NULL) {
-		result = WERR_NOMEM;
-		goto done;
-	}
-
-	info8->driver_name = talloc_strdup(info8, driver_name);
-	if (info8->driver_name == NULL) {
-		result = WERR_NOMEM;
-		goto done;
-	}
-
-	info8->architecture = talloc_strdup(info8, architecture);
-	if (info8->architecture == NULL) {
-		result = WERR_NOMEM;
-		goto done;
-	}
-
-	result = WERR_OK;
-
-	for (i = 0; i < num_values; i++) {
-		const char *tmp_str;
-		uint32_t tmp = 0;
-
-		v = &enum_values[i];
-
-		result = winreg_enumval_to_dword(info8, v,
-						 "Version",
-						 &tmp);
-		if (NT_STATUS_IS_OK(result)) {
-			info8->version = (enum spoolss_DriverOSVersion) tmp;
-		}
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "Driver",
-					      &info8->driver_path);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "Data File",
-					      &info8->data_file);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "Configuration File",
-					      &info8->config_file);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "Help File",
-					      &info8->help_file);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_multi_sz(info8, v,
-						    "Dependent Files",
-						    &info8->dependent_files);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "Monitor",
-					      &info8->monitor_name);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "Datatype",
-					      &info8->default_datatype);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_multi_sz(info8, v,
-						    "Previous Names",
-						    &info8->previous_names);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "DriverDate",
-					      &tmp_str);
-		if (W_ERROR_IS_OK(result)) {
-			result = winreg_printer_date_to_NTTIME(tmp_str,
-						&info8->driver_date);
-		}
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "DriverVersion",
-					      &tmp_str);
-		if (W_ERROR_IS_OK(result)) {
-			result = winreg_printer_ver_to_dword(tmp_str,
-						&info8->driver_version);
-		}
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "Manufacturer",
-					      &info8->manufacturer_name);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "OEM URL",
-					      &info8->manufacturer_url);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "HardwareID",
-					      &info8->hardware_id);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "Provider",
-					      &info8->provider);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "Print Processor",
-					      &info8->print_processor);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "VendorSetup",
-					      &info8->vendor_setup);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_multi_sz(info8, v,
-						    "Color Profiles",
-						    &info8->color_profiles);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "InfPath",
-					      &info8->inf_path);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_dword(info8, v,
-						 "PrinterDriverAttributes",
-						 &info8->printer_driver_attributes);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_multi_sz(info8, v,
-						    "CoreDependencies",
-						    &info8->core_driver_dependencies);
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "MinInboxDriverVerDate",
-					      &tmp_str);
-		if (W_ERROR_IS_OK(result)) {
-			result = winreg_printer_date_to_NTTIME(tmp_str,
-					&info8->min_inbox_driver_ver_date);
-		}
-		CHECK_ERROR(result);
-
-		result = winreg_enumval_to_sz(info8, v,
-					      "MinInboxDriverVerVersion",
-					      &tmp_str);
-		if (W_ERROR_IS_OK(result)) {
-			result = winreg_printer_ver_to_dword(tmp_str,
-					&info8->min_inbox_driver_ver_version);
-		}
-		CHECK_ERROR(result);
-	}
-
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_enumval_to_TYPE() failed "
-			  "for %s: %s\n", v->value_name,
-			  win_errstr(result)));
-		goto done;
-	}
-
-	*_info8 = talloc_steal(mem_ctx, info8);
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
+	return winreg_printer_deleteform1(mem_ctx, b,
+					  form_name);
 }
 
-WERROR winreg_del_driver(TALLOC_CTX *mem_ctx,
-			 const struct auth_serversupplied_info *session_info,
-			 struct messaging_context *msg_ctx,
-			 struct spoolss_DriverInfo8 *info8,
-			 uint32_t version)
+WERROR winreg_enum_printer_key_internal(TALLOC_CTX *mem_ctx,
+					const struct auth_serversupplied_info *session_info,
+					struct messaging_context *msg_ctx,
+					const char *printer,
+					const char *key,
+					uint32_t *pnum_subkeys,
+					const char ***psubkeys)
 {
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	TALLOC_CTX *tmp_ctx;
-	char *key_name;
 	WERROR result;
+	struct dcerpc_binding_handle *b;
 
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
+	result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+	W_ERROR_NOT_OK_RETURN(result);
 
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	/* test that the key exists */
-	result = winreg_printer_opendriver(tmp_ctx,
-					   session_info,
-					   msg_ctx,
-					   info8->driver_name,
-					   info8->architecture,
-					   version,
-					   access_mask, false,
-					   &winreg_handle,
-					   &hive_hnd,
-					   &key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		/* key doesn't exist */
-		if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
-			result = WERR_OK;
-			goto done;
-		}
-
-		DEBUG(5, ("winreg_del_driver: "
-			  "Could not open driver (%s,%s,%u): %s\n",
-			  info8->driver_name, info8->architecture,
-			  version, win_errstr(result)));
-		goto done;
-	}
-
-
-	if (is_valid_policy_hnd(&key_hnd)) {
-		dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
-	}
-
-	key_name = talloc_asprintf(tmp_ctx,
-				   "%s\\Environments\\%s\\Drivers\\Version-%u\\%s",
-				   TOP_LEVEL_CONTROL_KEY,
-				   info8->architecture, version,
-				   info8->driver_name);
-	if (key_name == NULL) {
-		result = WERR_NOMEM;
-		goto done;
-	}
-
-	result = winreg_printer_delete_subkeys(tmp_ctx,
-					       winreg_handle,
-					       &hive_hnd,
-					       access_mask,
-					       key_name);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_del_driver: "
-			  "Could not open driver (%s,%s,%u): %s\n",
-			  info8->driver_name, info8->architecture,
-			  version, win_errstr(result)));
-		goto done;
-	}
-
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
+	return winreg_enum_printer_key(mem_ctx, b,
+				       printer,
+				       key,
+				       pnum_subkeys,
+				       psubkeys);
 }
-
-WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
-			      const struct auth_serversupplied_info *session_info,
-			      struct messaging_context *msg_ctx,
-			      const char *architecture,
-			      uint32_t version,
-			      uint32_t *num_drivers,
-			      const char ***drivers_p)
-{
-	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-	struct dcerpc_binding_handle *winreg_handle = NULL;
-	struct policy_handle hive_hnd, key_hnd;
-	const char **drivers;
-	TALLOC_CTX *tmp_ctx;
-	WERROR result;
-	NTSTATUS status;
-
-	*num_drivers = 0;
-	*drivers_p = NULL;
-
-	ZERO_STRUCT(hive_hnd);
-	ZERO_STRUCT(key_hnd);
-
-	tmp_ctx = talloc_stackframe();
-	if (tmp_ctx == NULL) {
-		return WERR_NOMEM;
-	}
-
-	/* use NULL for the driver name so we open the key that is
-	 * parent of all drivers for this architecture and version */
-	result = winreg_printer_opendriver(tmp_ctx,
-					   session_info,
-					   msg_ctx,
-					   NULL,
-					   architecture,
-					   version,
-					   access_mask, false,
-					   &winreg_handle,
-					   &hive_hnd,
-					   &key_hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(5, ("winreg_get_driver_list: "
-			  "Could not open key (%s,%u): %s\n",
-			  architecture, version, win_errstr(result)));
-		result = WERR_OK;
-		goto done;
-	}
-
-	status = dcerpc_winreg_enum_keys(tmp_ctx,
-					 winreg_handle,
-					 &key_hnd,
-					 num_drivers,
-					 &drivers,
-					 &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		result = ntstatus_to_werror(status);
-	}
-	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("winreg_get_driver_list: "
-			  "Could not enumerate drivers for (%s,%u): %s\n",
-			  architecture, version, win_errstr(result)));
-		goto done;
-	}
-
-	*drivers_p = talloc_steal(mem_ctx, drivers);
-
-	result = WERR_OK;
-done:
-	if (winreg_handle != NULL) {
-		WERROR ignore;
-
-		if (is_valid_policy_hnd(&key_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
-		}
-		if (is_valid_policy_hnd(&hive_hnd)) {
-			dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
-		}
-	}
-
-	TALLOC_FREE(tmp_ctx);
-	return result;
-}

Modified: branches/samba/experimental/source3/rpc_server/spoolss/srv_spoolss_util.h
===================================================================
--- branches/samba/experimental/source3/rpc_server/spoolss/srv_spoolss_util.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_server/spoolss/srv_spoolss_util.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -23,569 +23,138 @@
 #define _SRV_SPOOLSS_UITL_H
 
 struct auth_serversupplied_info;
+struct dcerpc_binding_handle;
 
-enum spoolss_PrinterInfo2Mask {
-	SPOOLSS_PRINTER_INFO_ATTRIBUTES      = (int)(0x00000001),
-	SPOOLSS_PRINTER_INFO_AVERAGEPPM      = (int)(0x00000002),
-	SPOOLSS_PRINTER_INFO_CJOBS           = (int)(0x00000004),
-	SPOOLSS_PRINTER_INFO_COMMENT         = (int)(0x00000008),
-	SPOOLSS_PRINTER_INFO_DATATYPE        = (int)(0x00000010),
-	SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY = (int)(0x00000020),
-	SPOOLSS_PRINTER_INFO_DEVMODE         = (int)(0x00000040),
-	SPOOLSS_PRINTER_INFO_DRIVERNAME      = (int)(0x00000080),
-	SPOOLSS_PRINTER_INFO_LOCATION        = (int)(0x00000100),
-	SPOOLSS_PRINTER_INFO_NAME            = (int)(0x00000200),
-	SPOOLSS_PRINTER_INFO_PARAMETERS      = (int)(0x00000400),
-	SPOOLSS_PRINTER_INFO_PORTNAME        = (int)(0x00000800),
-	SPOOLSS_PRINTER_INFO_PRINTERNAME     = (int)(0x00001000),
-	SPOOLSS_PRINTER_INFO_PRINTPROCESSOR  = (int)(0x00002000),
-	SPOOLSS_PRINTER_INFO_PRIORITY        = (int)(0x00004000),
-	SPOOLSS_PRINTER_INFO_SECDESC         = (int)(0x00008000),
-	SPOOLSS_PRINTER_INFO_SEPFILE         = (int)(0x00010000),
-	SPOOLSS_PRINTER_INFO_SERVERNAME      = (int)(0x00020000),
-	SPOOLSS_PRINTER_INFO_SHARENAME       = (int)(0x00040000),
-	SPOOLSS_PRINTER_INFO_STARTTIME       = (int)(0x00080000),
-	SPOOLSS_PRINTER_INFO_STATUS          = (int)(0x00100000),
-	SPOOLSS_PRINTER_INFO_UNTILTIME       = (int)(0x00200000)
-};
+WERROR winreg_printer_binding_handle(TALLOC_CTX *mem_ctx,
+				     const struct auth_serversupplied_info *session_info,
+				     struct messaging_context *msg_ctx,
+				     struct dcerpc_binding_handle **winreg_binding_handle);
 
-#define SPOOLSS_PRINTER_INFO_ALL SPOOLSS_PRINTER_INFO_ATTRIBUTES      | \
-                                 SPOOLSS_PRINTER_INFO_AVERAGEPPM      | \
-                                 SPOOLSS_PRINTER_INFO_CJOBS           | \
-                                 SPOOLSS_PRINTER_INFO_COMMENT         | \
-                                 SPOOLSS_PRINTER_INFO_DATATYPE        | \
-                                 SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY | \
-                                 SPOOLSS_PRINTER_INFO_DEVMODE         | \
-                                 SPOOLSS_PRINTER_INFO_DRIVERNAME      | \
-                                 SPOOLSS_PRINTER_INFO_LOCATION        | \
-                                 SPOOLSS_PRINTER_INFO_NAME            | \
-                                 SPOOLSS_PRINTER_INFO_PARAMETERS      | \
-                                 SPOOLSS_PRINTER_INFO_PORTNAME        | \
-                                 SPOOLSS_PRINTER_INFO_PRINTERNAME     | \
-                                 SPOOLSS_PRINTER_INFO_PRINTPROCESSOR  | \
-                                 SPOOLSS_PRINTER_INFO_PRIORITY        | \
-                                 SPOOLSS_PRINTER_INFO_SECDESC         | \
-                                 SPOOLSS_PRINTER_INFO_SEPFILE         | \
-                                 SPOOLSS_PRINTER_INFO_SERVERNAME      | \
-                                 SPOOLSS_PRINTER_INFO_SHARENAME       | \
-                                 SPOOLSS_PRINTER_INFO_STARTTIME       | \
-                                 SPOOLSS_PRINTER_INFO_STATUS          | \
-                                 SPOOLSS_PRINTER_INFO_UNTILTIME
-
-WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
-			     const struct auth_serversupplied_info *session_info,
-			     struct messaging_context *msg_ctx,
-			     const char *sharename);
-
-/**
- * @internal
- *
- * @brief Update the information of a printer in the registry.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  sharename  The share name.
- *
- * @param[in]  info2_mask A bitmask which defines which values should be set.
- *
- * @param[in]  info2    A SetPrinterInfo2 structure with the data to set.
- *
- * @param[in]  devmode  A device mode structure with the data to set.
- *
- * @param[in]  secdesc  A security descriptor structure with the data to set.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
-			     const struct auth_serversupplied_info *session_info,
-			     struct messaging_context *msg_ctx,
-			     const char *sharename,
-			     uint32_t info2_mask,
-			     struct spoolss_SetPrinterInfo2 *info2,
-			     struct spoolss_DeviceMode *devmode,
-			     struct security_descriptor *secdesc);
-
-
-/**
- * @brief Get the inforamtion of a printer stored in the registry.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
-  * @param[in]  printer  The name of the printer to get.
- *
- * @param[out] pinfo2   A pointer to store a PRINTER_INFO_2 structure.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
-			  const struct auth_serversupplied_info *session_info,
-			  struct messaging_context *msg_ctx,
-			  const char *printer,
-			  struct spoolss_PrinterInfo2 **pinfo2);
-
-/**
- * @brief Get the security descriptor for a printer.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  sharename  The share name.
- *
- * @param[out] psecdesc   A pointer to store the security descriptor.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
+WERROR winreg_delete_printer_key_internal(TALLOC_CTX *mem_ctx,
+					  const struct auth_serversupplied_info *session_info,
+					  struct messaging_context *msg_ctx,
+					  const char *printer,
+					  const char *key);
+WERROR winreg_printer_update_changeid_internal(TALLOC_CTX *mem_ctx,
+					       const struct auth_serversupplied_info *session_info,
+					       struct messaging_context *msg_ctx,
+					       const char *printer);
+WERROR winreg_printer_get_changeid_internal(TALLOC_CTX *mem_ctx,
+					    const struct auth_serversupplied_info *session_info,
+					    struct messaging_context *msg_ctx,
+					    const char *printer,
+					    uint32_t *pchangeid);
+WERROR winreg_get_printer_internal(TALLOC_CTX *mem_ctx,
+				   const struct auth_serversupplied_info *session_info,
+				   struct messaging_context *msg_ctx,
+				   const char *printer,
+				   struct spoolss_PrinterInfo2 **pinfo2);
+WERROR winreg_create_printer_internal(TALLOC_CTX *mem_ctx,
+				      const struct auth_serversupplied_info *session_info,
+				      struct messaging_context *msg_ctx,
+				      const char *sharename);
+WERROR winreg_update_printer_internal(TALLOC_CTX *mem_ctx,
+				      const struct auth_serversupplied_info *session_info,
+				      struct messaging_context *msg_ctx,
+				      const char *sharename,
+				      uint32_t info2_mask,
+				      struct spoolss_SetPrinterInfo2 *info2,
+				      struct spoolss_DeviceMode *devmode,
+				      struct security_descriptor *secdesc);
+WERROR winreg_set_printer_dataex_internal(TALLOC_CTX *mem_ctx,
+					  const struct auth_serversupplied_info *session_info,
+					  struct messaging_context *msg_ctx,
+					  const char *printer,
+					  const char *key,
+					  const char *value,
+					  enum winreg_Type type,
+					  uint8_t *data,
+					  uint32_t data_size);
+WERROR winreg_enum_printer_dataex_internal(TALLOC_CTX *mem_ctx,
+					   const struct auth_serversupplied_info *session_info,
+					   struct messaging_context *msg_ctx,
+					   const char *printer,
+					   const char *key,
+					   uint32_t *pnum_values,
+					   struct spoolss_PrinterEnumValues **penum_values);
+WERROR winreg_get_printer_dataex_internal(TALLOC_CTX *mem_ctx,
+					  const struct auth_serversupplied_info *session_info,
+					  struct messaging_context *msg_ctx,
+					  const char *printer,
+					  const char *key,
+					  const char *value,
+					  enum winreg_Type *type,
+					  uint8_t **data,
+					  uint32_t *data_size);
+WERROR winreg_delete_printer_dataex_internal(TALLOC_CTX *mem_ctx,
+					     const struct auth_serversupplied_info *session_info,
+					     struct messaging_context *msg_ctx,
+					     const char *printer,
+					     const char *key,
+					     const char *value);
+WERROR winreg_get_driver_internal(TALLOC_CTX *mem_ctx,
 				  const struct auth_serversupplied_info *session_info,
 				  struct messaging_context *msg_ctx,
-				  const char *sharename,
-				  struct spoolss_security_descriptor **psecdesc);
-
-/**
- * @brief Set the security descriptor for a printer.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  sharename  The share name.
- *
- * @param[in]  secdesc  The security descriptor to save.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
+				  const char *architecture,
+				  const char *driver_name,
+				  uint32_t driver_version,
+				  struct spoolss_DriverInfo8 **_info8);
+WERROR winreg_get_driver_list_internal(TALLOC_CTX *mem_ctx,
+				       const struct auth_serversupplied_info *session_info,
+				       struct messaging_context *msg_ctx,
+				       const char *architecture,
+				       uint32_t version,
+				       uint32_t *num_drivers,
+				       const char ***drivers_p);
+WERROR winreg_del_driver_internal(TALLOC_CTX *mem_ctx,
 				  const struct auth_serversupplied_info *session_info,
 				  struct messaging_context *msg_ctx,
-				  const char *sharename,
-				  const struct spoolss_security_descriptor *secdesc);
-
-/**
- * @internal
- *
- * @brief Set printer data over the winreg pipe.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  printer  The printer name.
- *
- * @param[in]  key      The key of the printer data to store the value.
- *
- * @param[in]  value    The value name to save.
- *
- * @param[in]  type     The type of the value to use.
- *
- * @param[in]  data     The data which sould be saved under the given value.
- *
- * @param[in]  data_size The size of the data.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
-				 const struct auth_serversupplied_info *session_info,
-				 struct messaging_context *msg_ctx,
-				 const char *printer,
-				 const char *key,
-				 const char *value,
-				 enum winreg_Type type,
-				 uint8_t *data,
-				 uint32_t data_size);
-
-/**
- * @internal
- *
- * @brief Get printer data over a winreg pipe.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  printer  The printer name.
- *
- * @param[in]  key      The key of the printer data to get the value.
- *
- * @param[in]  value    The name of the value to query.
- *
- * @param[in]  type     The type of the value to query.
- *
- * @param[out] data     A pointer to store the data.
- *
- * @param[out] data_size A pointer to store the size of the data.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
-				 const struct auth_serversupplied_info *session_info,
-				 struct messaging_context *msg_ctx,
-				 const char *printer,
-				 const char *key,
-				 const char *value,
-				 enum winreg_Type *type,
-				 uint8_t **data,
-				 uint32_t *data_size);
-
-/**
- * @internal
- *
- * @brief Enumerate on the values of a given key and provide the data.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  printer  The printer name.
- *
- * @param[in]  key      The key of the printer data to get the value.
- *
- * @param[out] pnum_values A pointer to store the number of values we found.
- *
- * @param[out] penum_values A pointer to store the values and its data.
- *
- * @return                   WERR_OK on success, the corresponding DOS error
- *                           code if something gone wrong.
- */
-WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
+				  struct spoolss_DriverInfo8 *info8,
+				  uint32_t version);
+WERROR winreg_add_driver_internal(TALLOC_CTX *mem_ctx,
 				  const struct auth_serversupplied_info *session_info,
 				  struct messaging_context *msg_ctx,
-				  const char *printer,
-				  const char *key,
-				  uint32_t *pnum_values,
-				  struct spoolss_PrinterEnumValues **penum_values);
-
-/**
- * @internal
- *
- * @brief Delete printer data over a winreg pipe.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  printer  The printer name.
- *
- * @param[in]  key      The key of the printer data to delete.
- *
- * @param[in]  value    The name of the value to delete.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx,
-				    const struct auth_serversupplied_info *session_info,
-				    struct messaging_context *msg_ctx,
-				    const char *printer,
-				    const char *key,
-				    const char *value);
-
-/**
- * @internal
- *
- * @brief Enumerate on the subkeys of a given key and provide the data.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  printer  The printer name.
- *
- * @param[in]  key      The key of the printer data to get the value.
- *
- * @param[out] pnum_subkeys A pointer to store the number of subkeys found.
- *
- * @param[in]  psubkeys A pointer to an array to store the names of the subkeys
- *                      found.
- *
- * @return              WERR_OK on success, the corresponding DOS error
- *                      code if something gone wrong.
- */
-WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
-			       const struct auth_serversupplied_info *session_info,
-			       struct messaging_context *msg_ctx,
-			       const char *printer,
-			       const char *key,
-			       uint32_t *pnum_subkeys,
-			       const char ***psubkeys);
-
-/**
- * @internal
- *
- * @brief Delete a key with subkeys of a given printer.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  printer  The printer name.
- *
- * @param[in]  key      The key of the printer to delete.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx,
-				 const struct auth_serversupplied_info *session_info,
-				 struct messaging_context *msg_ctx,
-				 const char *printer,
-				 const char *key);
-
-/**
- * @brief Update the ChangeID of a printer.
- *
- * The ChangeID **must** be increasing over the lifetime of client's spoolss
- * service in order for the client's cache to show updates.
- *
- * If a form is updated of a printer, the we need to update the ChangeID of the
- * pritner.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  printer  The printer name.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx,
-				      const struct auth_serversupplied_info *session_info,
-				      struct messaging_context *msg_ctx,
-				      const char *printer);
-
-/**
- * @brief Get the ChangeID of the given printer.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  printer  The printer name.
- *
- * @param[in]  changeid A pointer to store the changeid.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
-				   const struct auth_serversupplied_info *session_info,
-				   struct messaging_context *msg_ctx,
-				   const char *printer,
-				   uint32_t *pchangeid);
-
-/**
- * @internal
- *
- * @brief This function adds a form to the list of available forms that can be
- * selected for the specified printer.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  form     The form to add.
- *
- * @return              WERR_OK on success.
- *                      WERR_ALREADY_EXISTS if the form already exists or is a
- *                                          builtin form.
- *                      A corresponding DOS error is something went wrong.
- */
-WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx,
-			       const struct auth_serversupplied_info *session_info,
-			       struct messaging_context *msg_ctx,
-			       struct spoolss_AddFormInfo1 *form);
-
-/*
- * @brief This function enumerates the forms supported by the specified printer.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[out] pnum_info A pointer to store the FormInfo count.
- *
- * @param[out] pinfo     A pointer to store an array with FormInfo.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
-				 const struct auth_serversupplied_info *session_info,
-				 struct messaging_context *msg_ctx,
-				 uint32_t *pnum_info,
-				 union spoolss_FormInfo **pinfo);
-
-/**
- * @brief This function removes a form name from the list of supported forms.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  form_name The name of the form to delete.
- *
- * @return              WERR_OK on success.
- *                      WERR_INVALID_PARAM if the form is a builtin form.
- *                      WERR_INVALID_FORM_NAME if the form or key doesn't exist.
- *                      A corresponding DOS error is something went wrong.
- */
-WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx,
-				  const struct auth_serversupplied_info *session_info,
-				  struct messaging_context *msg_ctx,
-				  const char *form_name);
-
-/**
- * @brief This function sets the form information for the specified printer.
- *
- * If one provides both the name in the API call and inside the FormInfo
- * structure, then the form gets renamed.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  form_name The name of the form to set or rename.
- *
- * @param[in]  form     The FormInfo structure to save.
- *
- * @return              WERR_OK on success.
- *                      WERR_INVALID_PARAM if the form is a builtin form.
- *                      A corresponding DOS error is something went wrong.
- */
-WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx,
-			       const struct auth_serversupplied_info *session_info,
-			       struct messaging_context *msg_ctx,
-			       const char *form_name,
-			       struct spoolss_AddFormInfo1 *form);
-
-/**
- * @brief This function retrieves information about a specified form.
- *
- * @param[in]  mem_ctx  The talloc memory context to use.
- *
- * @param[in]  session_info The server supplied session info.
- *
- * @param[in]  form_name The name of the form to query.
- *
- * @param[out] form     A pointer to a form structure to fill out.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
-			       const struct auth_serversupplied_info *session_info,
-			       struct messaging_context *msg_ctx,
-			       const char *form_name,
-			       struct spoolss_FormInfo1 *form);
-
-/**
- * @brief This function adds a new spool driver
- *
- * @param[in]  mem_ctx	       A talloc memory context.
- *
- * @param[in]  session_info     Auth info to open the pipe.
- *
- * @param[in]  r	       The structure containing the new driver data.
- *
- * @param[out] driver_name     Returns the driver name.
- *
- * @param[out] driver_version  Returns the driver version.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-WERROR winreg_add_driver(TALLOC_CTX *mem_ctx,
-			 const struct auth_serversupplied_info *session_info,
-			 struct messaging_context *msg_ctx,
-			 struct spoolss_AddDriverInfoCtr *r,
-			 const char **driver_name,
-			 uint32_t *driver_version);
-
-/**
- * @brief This function gets printer driver information
- *
- * @param[in]  mem_ctx	       A talloc memory context.
- *
- * @param[in]  session_info     Auth info to open the pipe.
- *
- * @param[in]  architecture    The architecture type.
- *
- * @param[in]  driver_name     The driver name.
- *
- * @param[in]  driver_version  The driver version.
- *
- * @param[out] _info8   The structure that holds the full driver information.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-
-WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
-			 const struct auth_serversupplied_info *session_info,
-			 struct messaging_context *msg_ctx,
-			 const char *architecture,
-			 const char *driver_name,
-			 uint32_t driver_version,
-			 struct spoolss_DriverInfo8 **_info8);
-
-/**
- * @brief This function deletes a printer driver information
- *
- * @param[in]  mem_ctx	       A talloc memory context.
- *
- * @param[in]  session_info     Auth info to open the pipe.
- *
- * @param[out] info8    The structure that holds the full driver information.
- *
- * @param[in]  version  The driver type version.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-
-WERROR winreg_del_driver(TALLOC_CTX *mem_ctx,
-			 const struct auth_serversupplied_info *session_info,
-			 struct messaging_context *msg_ctx,
-			 struct spoolss_DriverInfo8 *info8,
-			 uint32_t version);
-
-/**
- * @brief This function gets printer drivers list for the specified
- *        architecture and type version
- *
- * @param[in]  mem_ctx	       A talloc memory context.
- *
- * @param[in]  session_info     Auth info to open the pipe.
- *
- * @param[in]  architecture    The architecture type.
- *
- * @param[in]  version         The driver version.
- *
- * @param[out] num_drivers     The number of drivers.
- *
- * @param[out] version         The drivers names.
- *
- * @return              On success WERR_OK, a corresponding DOS error is
- *                      something went wrong.
- */
-
-WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
-			      const struct auth_serversupplied_info *session_info,
-                              struct messaging_context *msg_ctx,
-			      const char *architecture,
-			      uint32_t version,
-			      uint32_t *num_drivers,
-			      const char ***drivers);
-
+				  struct spoolss_AddDriverInfoCtr *r,
+				  const char **driver_name,
+				  uint32_t *driver_version);
+WERROR winreg_get_printer_secdesc_internal(TALLOC_CTX *mem_ctx,
+					   const struct auth_serversupplied_info *session_info,
+					   struct messaging_context *msg_ctx,
+					   const char *sharename,
+					   struct spoolss_security_descriptor **psecdesc);
+WERROR winreg_set_printer_secdesc_internal(TALLOC_CTX *mem_ctx,
+					   const struct auth_serversupplied_info *session_info,
+					   struct messaging_context *msg_ctx,
+					   const char *sharename,
+					   const struct spoolss_security_descriptor *secdesc);
+WERROR winreg_printer_enumforms1_internal(TALLOC_CTX *mem_ctx,
+					  const struct auth_serversupplied_info *session_info,
+					  struct messaging_context *msg_ctx,
+					  uint32_t *pnum_info,
+					  union spoolss_FormInfo **pinfo);
+WERROR winreg_printer_getform1_internal(TALLOC_CTX *mem_ctx,
+					const struct auth_serversupplied_info *session_info,
+					struct messaging_context *msg_ctx,
+					const char *form_name,
+					struct spoolss_FormInfo1 *r);
+WERROR winreg_printer_addform1_internal(TALLOC_CTX *mem_ctx,
+					const struct auth_serversupplied_info *session_info,
+					struct messaging_context *msg_ctx,
+					struct spoolss_AddFormInfo1 *form);
+WERROR winreg_printer_setform1_internal(TALLOC_CTX *mem_ctx,
+					const struct auth_serversupplied_info *session_info,
+					struct messaging_context *msg_ctx,
+					const char *form_name,
+					struct spoolss_AddFormInfo1 *form);
+WERROR winreg_printer_deleteform1_internal(TALLOC_CTX *mem_ctx,
+					   const struct auth_serversupplied_info *session_info,
+					   struct messaging_context *msg_ctx,
+					   const char *form_name);
+WERROR winreg_enum_printer_key_internal(TALLOC_CTX *mem_ctx,
+					const struct auth_serversupplied_info *session_info,
+					struct messaging_context *msg_ctx,
+					const char *printer,
+					const char *key,
+					uint32_t *pnum_subkeys,
+					const char ***psubkeys);
 #endif /* _SRV_SPOOLSS_UITL_H */

Modified: branches/samba/experimental/source3/rpc_server/srv_access_check.h
===================================================================
--- branches/samba/experimental/source3/rpc_server/srv_access_check.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_server/srv_access_check.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,35 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Andrew Tridgell                   1992-1997,
+ *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
+ *  Copyright (C) Paul Ashton                       1997,
+ *  Copyright (C) Marc Jacobsen			    1999,
+ *  Copyright (C) Jeremy Allison                    2001-2008,
+ *  Copyright (C) Jean François Micouleau           1998-2001,
+ *  Copyright (C) Jim McDonough <jmcd at us.ibm.com>   2002,
+ *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
+ *  Copyright (C) Simo Sorce                        2003.
+ *  Copyright (C) Volker Lendecke		    2005.
+ *  Copyright (C) Guenther Deschner		    2008.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 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/>.
+ */
+
+#ifndef _RPC_SERVER_SRV_ACCESS_CHECK_H_
+#define _RPC_SERVER_SRV_ACCESS_CHECK_H_
+
 /* The following definitions come from rpc_server/srv_access_check.c */
 
 NTSTATUS access_check_object( struct security_descriptor *psd, struct security_token *token,
@@ -8,3 +40,5 @@
 void map_max_allowed_access(const struct security_token *nt_token,
 			    const struct security_unix_token *unix_token,
 			    uint32_t *pacc_requested);
+
+#endif /* _RPC_SERVER_SRV_ACCESS_CHECK_H_ */

Modified: branches/samba/experimental/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
===================================================================
--- branches/samba/experimental/source3/rpc_server/srvsvc/srv_srvsvc_nt.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_server/srvsvc/srv_srvsvc_nt.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -539,8 +539,8 @@
     if (!lp_access_based_share_enum(snum))
         return true;
 
-    return share_access_check(p->session_info->security_token, lp_servicename(snum),
-                              FILE_READ_DATA);
+    return share_access_check(p->session_info->security_token,
+			      lp_servicename(snum), FILE_READ_DATA, NULL);
 }
 
 /*******************************************************************

Modified: branches/samba/experimental/source3/rpc_server/svcctl/srv_svcctl_nt.c
===================================================================
--- branches/samba/experimental/source3/rpc_server/svcctl/srv_svcctl_nt.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_server/svcctl/srv_svcctl_nt.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -668,17 +668,18 @@
 /********************************************************************
 ********************************************************************/
 
-static WERROR fill_svc_config(TALLOC_CTX *ctx,
+static WERROR fill_svc_config(TALLOC_CTX *mem_ctx,
 			      struct messaging_context *msg_ctx,
 			      struct auth_serversupplied_info *session_info,
 			      const char *name,
 			      struct QUERY_SERVICE_CONFIG *config)
 {
-	TALLOC_CTX *mem_ctx = talloc_stackframe();
 	const char *result = NULL;
 
 	/* now fill in the individual values */
 
+	ZERO_STRUCTP(config);
+
 	config->displayname = svcctl_lookup_dispname(mem_ctx,
 						     msg_ctx,
 						     session_info,
@@ -720,9 +721,6 @@
 	else
 		config->start_type = SVCCTL_DEMAND_START;
 
-
-	talloc_free(mem_ctx);
-
 	return WERR_OK;
 }
 
@@ -777,7 +775,8 @@
 				    struct svcctl_QueryServiceConfig2W *r)
 {
 	SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
-	uint32 buffer_size;
+	uint32_t buffer_size;
+	DATA_BLOB blob = data_blob_null;
 
 	/* perform access checks */
 
@@ -797,7 +796,6 @@
 			struct SERVICE_DESCRIPTION desc_buf;
 			const char *description;
 			enum ndr_err_code ndr_err;
-			DATA_BLOB blob;
 
 			description = svcctl_lookup_description(p->mem_ctx,
 								p->msg_ctx,
@@ -812,9 +810,6 @@
 				return WERR_INVALID_PARAM;
 			}
 
-			buffer_size = ndr_size_SERVICE_DESCRIPTION(&desc_buf, 0);
-			r->out.buffer = blob.data;
-
 			break;
 		}
 		break;
@@ -822,7 +817,6 @@
 		{
 			struct SERVICE_FAILURE_ACTIONS actions;
 			enum ndr_err_code ndr_err;
-			DATA_BLOB blob;
 
 			/* nothing to say...just service the request */
 
@@ -834,9 +828,6 @@
 				return WERR_INVALID_PARAM;
 			}
 
-			buffer_size = ndr_size_SERVICE_FAILURE_ACTIONS(&actions, 0);
-			r->out.buffer = blob.data;
-
 			break;
 		}
 		break;
@@ -845,12 +836,15 @@
 		return WERR_UNKNOWN_LEVEL;
 	}
 
+	buffer_size = blob.length;
 	buffer_size += buffer_size % 4;
 	*r->out.needed = (buffer_size > r->in.offered) ? buffer_size : r->in.offered;
 
         if (buffer_size > r->in.offered)
                 return WERR_INSUFFICIENT_BUFFER;
 
+	memcpy(r->out.buffer, blob.data, blob.length);
+
 	return WERR_OK;
 }
 
@@ -942,7 +936,7 @@
 	}
 
 	*r->out.needed = len;
-	r->out.buffer = buffer;
+	memcpy(r->out.buffer, buffer, len);
 
 	return WERR_OK;
 }

Modified: branches/samba/experimental/source3/rpc_server/wscript_build
===================================================================
--- branches/samba/experimental/source3/rpc_server/wscript_build	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/rpc_server/wscript_build	2011-07-28 16:06:15 UTC (rev 3863)
@@ -77,7 +77,7 @@
 
 bld.SAMBA3_SUBSYSTEM('RPC_SVCCTL',
                     source=RPC_SVCCTL_SRC,
-                    deps='SERVICES LIBCLI_WINREG',
+                    deps='SERVICES LIBCLI_WINREG_INTERNAL',
                     vars=locals())
 
 bld.SAMBA3_SUBSYSTEM('RPC_NTSVCS',
@@ -98,12 +98,12 @@
 
 bld.SAMBA3_SUBSYSTEM('RPC_SPOOLSS',
                     source=RPC_SPOOLSS_SRC,
-                    deps='cups PRINTING PRINTBACKEND LIBCLI_WINREG',
+                    deps='cups PRINTING PRINTBACKEND LIBCLI_WINREG_INTERNAL',
                     vars=locals())
 
 bld.SAMBA3_SUBSYSTEM('RPC_EVENTLOG',
                     source=RPC_EVENTLOG_SRC,
-                    deps='LIBEVENTLOG LIBCLI_WINREG',
+                    deps='LIBEVENTLOG LIBCLI_WINREG_INTERNAL',
                     vars=locals())
 
 bld.SAMBA3_SUBSYSTEM('RPC_RPCECHO',

Modified: branches/samba/experimental/source3/script/mkbuildoptions.awk
===================================================================
--- branches/samba/experimental/source3/script/mkbuildoptions.awk	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/script/mkbuildoptions.awk	2011-07-28 16:06:15 UTC (rev 3863)
@@ -96,6 +96,8 @@
 
 	print "       output(screen,\"   SMB_PASSWD_FILE: %s\\n\",get_dyn_SMB_PASSWD_FILE());";
 	print "       output(screen,\"   PRIVATE_DIR: %s\\n\",get_dyn_PRIVATE_DIR());";
+	print "       output(screen,\"   NCALRPCDIR: %s\\n\",get_dyn_NCALRPCDIR());";
+	print "       output(screen,\"   NMBDSOCKETDIR: %s\\n\",get_dyn_NMBDSOCKETDIR());";
 	print "";
 
 

Modified: branches/samba/experimental/source3/script/tests/test_net_registry_roundtrip.sh
===================================================================
--- branches/samba/experimental/source3/script/tests/test_net_registry_roundtrip.sh	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/script/tests/test_net_registry_roundtrip.sh	2011-07-28 16:06:15 UTC (rev 3863)
@@ -67,7 +67,7 @@
 
 conf_roundtrip()
 {
-    local DIR=$(mktemp -d ${PREFIX}/${LOGDIR_PREFIX}_XXXX)
+    local DIR=$(mktemp -d ${PREFIX}/${LOGDIR_PREFIX}_XXXXXX)
     local LOG=$DIR/log
 
     echo conf_roundtrip $1 > $LOG

Modified: branches/samba/experimental/source3/script/tests/test_smbclient_s3.sh
===================================================================
--- branches/samba/experimental/source3/script/tests/test_smbclient_s3.sh	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/script/tests/test_smbclient_s3.sh	2011-07-28 16:06:15 UTC (rev 3863)
@@ -399,7 +399,7 @@
 	rm -rf ${OLDDIR}
 done
 
-LOGDIR=$(mktemp -d ${PREFIX}/${LOGDIR_PREFIX}_XXXX)
+LOGDIR=$(mktemp -d ${PREFIX}/${LOGDIR_PREFIX}_XXXXXX)
 
 
 testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p 139 || failed=`expr $failed + 1`

Modified: branches/samba/experimental/source3/script/tests/test_wbinfo_sids2xids_int.py
===================================================================
--- branches/samba/experimental/source3/script/tests/test_wbinfo_sids2xids_int.py	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/script/tests/test_wbinfo_sids2xids_int.py	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
 import sys,os,subprocess
 

Modified: branches/samba/experimental/source3/smbd/fake_file.c
===================================================================
--- branches/samba/experimental/source3/smbd/fake_file.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/fake_file.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -19,6 +19,7 @@
 
 #include "includes.h"
 #include "smbd/smbd.h"
+#include "smbd/globals.h"
 #include "fake_file.h"
 #include "auth.h"
 
@@ -128,6 +129,18 @@
 	files_struct *fsp = NULL;
 	NTSTATUS status;
 
+	status = smbd_calculate_access_mask(conn, smb_fname,
+					    false, /* fake files do not exist */
+					    access_mask, &access_mask);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(10, ("open_fake_file: smbd_calculate_access_mask "
+			"on service[%s] file[%s] returned %s\n",
+			lp_servicename(SNUM(conn)),
+			smb_fname_str_dbg(smb_fname),
+			nt_errstr(status)));
+		return status;
+	}
+
 	/* access check */
 	if (geteuid() != sec_initial_uid()) {
 		DEBUG(3, ("open_fake_file_shared: access_denied to "

Modified: branches/samba/experimental/source3/smbd/file_access.c
===================================================================
--- branches/samba/experimental/source3/smbd/file_access.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/file_access.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -92,6 +92,11 @@
 		return False;
 	}
 
+	if (!lp_acl_check_permissions(SNUM(conn))) {
+		/* This option means don't check. */
+		return true;
+	}
+
 	/* Get the parent directory permission mask and owners. */
 	if (!parent_dirname(ctx, smb_fname->base_name, &dname, NULL)) {
 		return False;

Modified: branches/samba/experimental/source3/smbd/globals.h
===================================================================
--- branches/samba/experimental/source3/smbd/globals.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/globals.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -224,6 +224,11 @@
 			       int *_last_entry_off,
 			       struct ea_list *name_list);
 
+NTSTATUS smbd_calculate_access_mask(connection_struct *conn,
+				    const struct smb_filename *smb_fname,
+				    bool file_existed,
+				    uint32_t access_mask,
+				    uint32_t *access_mask_out);
 NTSTATUS smbd_check_open_rights(struct connection_struct *conn,
 				const struct smb_filename *smb_fname,
 				uint32_t access_mask,
@@ -483,6 +488,8 @@
 		int dirhandles_open;
 	} searches;
 
+	uint64_t num_requests;
+
 	struct {
 		struct fd_event *fde;
 
@@ -510,7 +517,6 @@
 			int ref_count;
 		} echo_handler;
 
-		uint64_t num_requests;
 		struct {
 			bool encrypted_passwords;
 			bool spnego;

Modified: branches/samba/experimental/source3/smbd/mangle_hash.c
===================================================================
--- branches/samba/experimental/source3/smbd/mangle_hash.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/mangle_hash.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -374,8 +374,8 @@
 	magic = strchr_m( s, magic_char );
 	while( magic && magic[1] && magic[2] ) {         /* 3 chars, 1st is magic. */
 		if( ('.' == magic[3] || '/' == magic[3] || !(magic[3]))          /* Ends with '.' or nul or '/' ?  */
-				&& isbasechar( toupper_ascii(magic[1]) )           /* is 2nd char basechar?  */
-				&& isbasechar( toupper_ascii(magic[2]) ) )         /* is 3rd char basechar?  */
+				&& isbasechar( toupper_m(magic[1]) )           /* is 2nd char basechar?  */
+				&& isbasechar( toupper_m(magic[2]) ) )         /* is 3rd char basechar?  */
 			return( True );                           /* If all above, then true, */
 		magic = strchr_m( magic+1, magic_char );      /*    else seek next magic. */
 	}
@@ -429,7 +429,7 @@
 	s1 = strrchr( mangled_name_key, '.' );
 	if( s1 && (s2 = strrchr( raw_name, '.' )) ) {
 		size_t i = 1;
-		while( s1[i] && (tolower_ascii( s1[i] ) == s2[i]) )
+		while( s1[i] && (tolower_m( s1[i] ) == s2[i]) )
 			i++;
 		if( !s1[i] && !s2[i] ) {
 			/* Truncate at the '.' */

Modified: branches/samba/experimental/source3/smbd/mangle_hash2.c
===================================================================
--- branches/samba/experimental/source3/smbd/mangle_hash2.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/mangle_hash2.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -173,10 +173,10 @@
 		char_flags[c2] |= FLAG_POSSIBLE2;
 		char_flags[c3] |= FLAG_POSSIBLE3;
 		char_flags[c4] |= FLAG_POSSIBLE4;
-		char_flags[tolower_ascii(c1)] |= FLAG_POSSIBLE1;
-		char_flags[tolower_ascii(c2)] |= FLAG_POSSIBLE2;
-		char_flags[tolower_ascii(c3)] |= FLAG_POSSIBLE3;
-		char_flags[tolower_ascii(c4)] |= FLAG_POSSIBLE4;
+		char_flags[tolower_m(c1)] |= FLAG_POSSIBLE1;
+		char_flags[tolower_m(c2)] |= FLAG_POSSIBLE2;
+		char_flags[tolower_m(c3)] |= FLAG_POSSIBLE3;
+		char_flags[tolower_m(c4)] |= FLAG_POSSIBLE4;
 
 		char_flags[(unsigned char)'.'] |= FLAG_POSSIBLE4;
 	}
@@ -734,7 +734,7 @@
 		if (! FLAG_CHECK(lead_chars[i], FLAG_ASCII)) {
 			lead_chars[i] = '_';
 		}
-		lead_chars[i] = toupper_ascii(lead_chars[i]);
+		lead_chars[i] = toupper_m(lead_chars[i]);
 	}
 	for (;i<mangle_prefix;i++) {
 		lead_chars[i] = '_';
@@ -755,7 +755,7 @@
 			char c = dot_p[i];
 			if (FLAG_CHECK(c, FLAG_ASCII)) {
 				extension[extension_length++] =
-					toupper_ascii(c);
+					toupper_m(c);
 			}
 		}
 	}

Modified: branches/samba/experimental/source3/smbd/msdfs.c
===================================================================
--- branches/samba/experimental/source3/smbd/msdfs.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/msdfs.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -27,6 +27,7 @@
 #include "smbd/globals.h"
 #include "msdfs.h"
 #include "auth.h"
+#include "libcli/security/security.h"
 
 /**********************************************************************
  Parse a DFS pathname of the form \hostname\service\reqpath
@@ -278,6 +279,35 @@
 
 	set_conn_connectpath(conn, connpath);
 
+	/*
+	 * New code to check if there's a share security descripter
+	 * added from NT server manager. This is done after the
+	 * smb.conf checks are done as we need a uid and token. JRA.
+	 *
+	 */
+	if (conn->session_info) {
+		share_access_check(conn->session_info->security_token,
+				   lp_servicename(snum), MAXIMUM_ALLOWED_ACCESS,
+				   &conn->share_access);
+
+		if ((conn->share_access & FILE_WRITE_DATA) == 0) {
+			if ((conn->share_access & FILE_READ_DATA) == 0) {
+				/* No access, read or write. */
+				DEBUG(0,("create_conn_struct: connection to %s "
+					 "denied due to security "
+					 "descriptor.\n",
+					 lp_servicename(snum)));
+				conn_free(conn);
+				return NT_STATUS_ACCESS_DENIED;
+			} else {
+				conn->read_only = true;
+			}
+		}
+	} else {
+		conn->share_access = 0;
+		conn->read_only = true;
+	}
+
 	if (!smbd_vfs_init(conn)) {
 		NTSTATUS status = map_nt_error_from_unix(errno);
 		DEBUG(0,("create_conn_struct: smbd_vfs_init failed.\n"));

Modified: branches/samba/experimental/source3/smbd/open.c
===================================================================
--- branches/samba/experimental/source3/smbd/open.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/open.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -76,7 +76,25 @@
 	/* Check if we have rights to open. */
 	NTSTATUS status;
 	struct security_descriptor *sd = NULL;
+	uint32_t rejected_share_access;
 
+	rejected_share_access = access_mask & ~(conn->share_access);
+
+	if (rejected_share_access) {
+		*access_granted = rejected_share_access;
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	if ((access_mask & DELETE_ACCESS) && !lp_acl_check_permissions(SNUM(conn))) {
+		*access_granted = access_mask;
+
+		DEBUG(10,("smbd_check_open_rights: not checking ACL "
+			"on DELETE_ACCESS on file %s. Granting 0x%x\n",
+			smb_fname_str_dbg(smb_fname),
+			(unsigned int)*access_granted ));
+		return NT_STATUS_OK;
+	}
+
 	status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
 			(SECINFO_OWNER |
 			SECINFO_GROUP |
@@ -237,11 +255,13 @@
 			 "was %s\n", fsp_str_dbg(fsp),
 			 (unsigned int)smb_fname_parent->st.st_ex_uid,
 			 strerror(errno) ));
-	}
-
-	DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
+	} else {
+		DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
 		  "parent directory uid %u.\n", fsp_str_dbg(fsp),
 		  (unsigned int)smb_fname_parent->st.st_ex_uid));
+		/* Ensure the uid entry is updated. */
+		fsp->fsp_name->st.st_ex_uid = smb_fname_parent->st.st_ex_uid;
+	}
 
 	TALLOC_FREE(smb_fname_parent);
 }
@@ -316,10 +336,9 @@
 
 	/* Ensure we're pointing at the same place. */
 	if (smb_fname_cwd->st.st_ex_dev != psbuf->st_ex_dev ||
-	    smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino ||
-	    smb_fname_cwd->st.st_ex_mode != psbuf->st_ex_mode ) {
+	    smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino) {
 		DEBUG(0,("change_dir_owner_to_parent: "
-			 "device/inode/mode on directory %s changed. "
+			 "device/inode on directory %s changed. "
 			 "Refusing to chown !\n", fname ));
 		status = NT_STATUS_ACCESS_DENIED;
 		goto chdir;
@@ -379,6 +398,7 @@
 	int accmode = (flags & O_ACCMODE);
 	int local_flags = flags;
 	bool file_existed = VALID_STAT(fsp->fsp_name->st);
+	bool file_created = false;
 
 	fsp->fh->fd = -1;
 	errno = EPERM;
@@ -478,23 +498,7 @@
 		}
 
 		if ((local_flags & O_CREAT) && !file_existed) {
-
-			/* Inherit the ACL if required */
-			if (lp_inherit_perms(SNUM(conn))) {
-				inherit_access_posix_acl(conn, parent_dir,
-							 smb_fname->base_name,
-							 unx_mode);
-			}
-
-			/* Change the owner if required. */
-			if (lp_inherit_owner(SNUM(conn))) {
-				change_file_owner_to_parent(conn, parent_dir,
-							    fsp);
-			}
-
-			notify_fname(conn, NOTIFY_ACTION_ADDED,
-				     FILE_NOTIFY_CHANGE_FILE_NAME,
-				     smb_fname->base_name);
+			file_created = true;
 		}
 
 	} else {
@@ -604,6 +608,47 @@
 			fd_close(fsp);
 			return status;
 		}
+
+		if (file_created) {
+			bool need_re_stat = false;
+			/* Do all inheritance work after we've
+			   done a successful stat call and filled
+			   in the stat struct in fsp->fsp_name. */
+
+			/* Inherit the ACL if required */
+			if (lp_inherit_perms(SNUM(conn))) {
+				inherit_access_posix_acl(conn, parent_dir,
+							 smb_fname->base_name,
+							 unx_mode);
+				need_re_stat = true;
+			}
+
+			/* Change the owner if required. */
+			if (lp_inherit_owner(SNUM(conn))) {
+				change_file_owner_to_parent(conn, parent_dir,
+							    fsp);
+				need_re_stat = true;
+			}
+
+			if (need_re_stat) {
+				if (fsp->fh->fd == -1) {
+					ret = SMB_VFS_STAT(conn, smb_fname);
+				} else {
+					ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
+					/* If we have an fd, this stat should succeed. */
+					if (ret == -1) {
+						DEBUG(0,("Error doing fstat on open file %s "
+							 "(%s)\n",
+							 smb_fname_str_dbg(smb_fname),
+							 strerror(errno) ));
+					}
+				}
+			}
+
+			notify_fname(conn, NOTIFY_ACTION_ADDED,
+				     FILE_NOTIFY_CHANGE_FILE_NAME,
+				     smb_fname->base_name);
+		}
 	}
 
 	/*
@@ -1477,13 +1522,15 @@
  Work out what access_mask to use from what the client sent us.
 ****************************************************************************/
 
-static NTSTATUS calculate_access_mask(connection_struct *conn,
-					const struct smb_filename *smb_fname,
-					bool file_existed,
-					uint32_t access_mask,
-					uint32_t *access_mask_out)
+NTSTATUS smbd_calculate_access_mask(connection_struct *conn,
+				    const struct smb_filename *smb_fname,
+				    bool file_existed,
+				    uint32_t access_mask,
+				    uint32_t *access_mask_out)
 {
 	NTSTATUS status;
+	uint32_t orig_access_mask = access_mask;
+	uint32_t rejected_share_access;
 
 	/*
 	 * Convert GENERIC bits to specific bits.
@@ -1504,8 +1551,8 @@
 					SECINFO_DACL),&sd);
 
 			if (!NT_STATUS_IS_OK(status)) {
-				DEBUG(10, ("calculate_access_mask: Could not get acl "
-					"on file %s: %s\n",
+				DEBUG(10,("smbd_calculate_access_mask: "
+					"Could not get acl on file %s: %s\n",
 					smb_fname_str_dbg(smb_fname),
 					nt_errstr(status)));
 				return NT_STATUS_ACCESS_DENIED;
@@ -1520,8 +1567,9 @@
 			TALLOC_FREE(sd);
 
 			if (!NT_STATUS_IS_OK(status)) {
-				DEBUG(10, ("calculate_access_mask: Access denied on "
-					"file %s: when calculating maximum access\n",
+				DEBUG(10, ("smbd_calculate_access_mask: "
+					"Access denied on file %s: "
+					"when calculating maximum access\n",
 					smb_fname_str_dbg(smb_fname)));
 				return NT_STATUS_ACCESS_DENIED;
 			}
@@ -1530,8 +1578,23 @@
 		} else {
 			access_mask = FILE_GENERIC_ALL;
 		}
+
+		access_mask &= conn->share_access;
 	}
 
+	rejected_share_access = access_mask & ~(conn->share_access);
+
+	if (rejected_share_access) {
+		DEBUG(10, ("smbd_calculate_access_mask: Access denied on "
+			"file %s: rejected by share access mask[0x%08X] "
+			"orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
+			smb_fname_str_dbg(smb_fname),
+			conn->share_access,
+			orig_access_mask, access_mask,
+			rejected_share_access));
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	*access_mask_out = access_mask;
 	return NT_STATUS_OK;
 }
@@ -1853,11 +1916,11 @@
 		}
 	}
 
-	status = calculate_access_mask(conn, smb_fname, file_existed,
+	status = smbd_calculate_access_mask(conn, smb_fname, file_existed,
 					access_mask,
 					&access_mask); 
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(10, ("open_file_ntcreate: calculate_access_mask "
+		DEBUG(10, ("open_file_ntcreate: smbd_calculate_access_mask "
 			"on file %s returned %s\n",
 			smb_fname_str_dbg(smb_fname), nt_errstr(status)));
 		return status;
@@ -2543,6 +2606,7 @@
 	char *parent_dir;
 	NTSTATUS status;
 	bool posix_open = false;
+	bool need_re_stat = false;
 
 	if(!CAN_WRITE(conn)) {
 		DEBUG(5,("mkdir_internal: failing create on read-only share "
@@ -2597,6 +2661,7 @@
 	if (lp_inherit_perms(SNUM(conn))) {
 		inherit_access_posix_acl(conn, parent_dir,
 					 smb_dname->base_name, mode);
+		need_re_stat = true;
 	}
 
 	if (!posix_open) {
@@ -2611,6 +2676,7 @@
 			SMB_VFS_CHMOD(conn, smb_dname->base_name,
 				      (smb_dname->st.st_ex_mode |
 					  (mode & ~smb_dname->st.st_ex_mode)));
+			need_re_stat = true;
 		}
 	}
 
@@ -2619,8 +2685,17 @@
 		change_dir_owner_to_parent(conn, parent_dir,
 					   smb_dname->base_name,
 					   &smb_dname->st);
+		need_re_stat = true;
 	}
 
+	if (need_re_stat) {
+		if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
+			DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
+			  smb_fname_str_dbg(smb_dname), strerror(errno)));
+			return map_nt_error_from_unix(errno);
+		}
+	}
+
 	notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
 		     smb_dname->base_name);
 
@@ -2688,10 +2763,10 @@
 		return NT_STATUS_NOT_A_DIRECTORY;
 	}
 
-	status = calculate_access_mask(conn, smb_dname, dir_existed,
-				       access_mask, &access_mask);
+	status = smbd_calculate_access_mask(conn, smb_dname, dir_existed,
+					    access_mask, &access_mask);
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(10, ("open_directory: calculate_access_mask "
+		DEBUG(10, ("open_directory: smbd_calculate_access_mask "
 			"on file %s returned %s\n",
 			smb_fname_str_dbg(smb_dname),
 			nt_errstr(status)));
@@ -3241,8 +3316,7 @@
 
 	/* Setting FILE_SHARE_DELETE is the hint. */
 
-	if (lp_acl_check_permissions(SNUM(conn))
-	    && (create_disposition != FILE_CREATE)
+	if ((create_disposition != FILE_CREATE)
 	    && (access_mask & DELETE_ACCESS)
 	    && (!(can_delete_file_in_directory(conn, smb_fname) ||
 		 can_access_file_acl(conn, smb_fname, DELETE_ACCESS)))) {

Modified: branches/samba/experimental/source3/smbd/process.c
===================================================================
--- branches/samba/experimental/source3/smbd/process.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/process.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1689,7 +1689,7 @@
 	sconn->trans_num++;
 
 done:
-	sconn->smb1.num_requests++;
+	sconn->num_requests++;
 
 	/* The timeout_processing function isn't run nearly
 	   often enough to implement 'max log size' without
@@ -1698,7 +1698,7 @@
 	   level 10.  Checking every 50 SMBs is a nice
 	   tradeoff of performance vs log file size overrun. */
 
-	if ((sconn->smb1.num_requests % 50) == 0 &&
+	if ((sconn->num_requests % 50) == 0 &&
 	    need_to_check_log_size()) {
 		change_to_root_user();
 		check_log_size();

Modified: branches/samba/experimental/source3/smbd/proto.h
===================================================================
--- branches/samba/experimental/source3/smbd/proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,4 +1,51 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  Main SMB server routines
+ *
+ *  Copyright (C) Andrew Tridgell			1992-2002,2006
+ *  Copyright (C) Jeremy Allison			1992-2010
+ *  Copyright (C) Volker Lendecke			1993-2009
+ *  Copyright (C) John H Terpstra			1995-1998
+ *  Copyright (C) Luke Kenneth Casson Leighton		1996-1998
+ *  Copyright (C) Paul Ashton				1997-1998
+ *  Copyright (C) Tim Potter				1999-2000
+ *  Copyright (C) T.D.Lee at durham.ac.uk			1999
+ *  Copyright (C) Ying Chen				2000
+ *  Copyright (C) Shirish Kalele			2000
+ *  Copyright (C) Andrew Bartlett			2001-2003
+ *  Copyright (C) Alexander Bokovoy			2002,2005
+ *  Copyright (C) Simo Sorce				2001-2002,2009
+ *  Copyright (C) Andreas Gruenbacher			2002
+ *  Copyright (C) Jim McDonough <jmcd at us.ibm.com>	2002
+ *  Copyright (C) Martin Pool				2002
+ *  Copyright (C) Luke Howard				2003
+ *  Copyright (C) Stefan (metze) Metzmacher		2003,2009
+ *  Copyright (C) Steve French				2005
+ *  Copyright (C) Gerald (Jerry) Carter			2006
+ *  Copyright (C) James Peach				2006-2007
+ *  Copyright (C) Jelmer Vernooij			2002-2003
+ *  Copyright (C) Michael Adam				2007
+ *  Copyright (C) Rishi Srivatsavai			2007
+ *  Copyright (C) Tim Prouty				2009
+ *  Copyright (C) Gregor Beck				2011
+ *
+ *  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/>.
+ */
 
+#ifndef _SMBD_PROTO_H_
+#define _SMBD_PROTO_H_
+
 /* The following definitions come from smbd/signing.c  */
 
 struct smbd_server_connection;
@@ -1136,3 +1183,5 @@
 /* The following definitions come from smbd/msg_idmap.c */
 
 void msg_idmap_register_msgs(struct messaging_context *ctx);
+
+#endif /* _SMBD_PROTO_H_ */

Modified: branches/samba/experimental/source3/smbd/quotas.c
===================================================================
--- branches/samba/experimental/source3/smbd/quotas.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/quotas.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -26,6 +26,7 @@
 
 #include "includes.h"
 #include "smbd/smbd.h"
+#include "system/filesys.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_QUOTA

Modified: branches/samba/experimental/source3/smbd/reply.c
===================================================================
--- branches/samba/experimental/source3/smbd/reply.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/reply.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -835,9 +835,7 @@
 				perm1 = FILE_ALL_ACCESS;
 				perm2 = FILE_ALL_ACCESS;
 			} else {
-				perm1 = CAN_WRITE(conn) ?
-						SHARE_ALL_ACCESS :
-						SHARE_READ_ONLY;
+				perm1 = conn->share_access;
 			}
 
 			SIVAL(req->outbuf, smb_vwv3, perm1);

Modified: branches/samba/experimental/source3/smbd/server.c
===================================================================
--- branches/samba/experimental/source3/smbd/server.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/server.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -477,6 +477,15 @@
 					 "because too many files are open\n"));
 				goto exit;
 			}
+			if (lp_clustering() &&
+			    NT_STATUS_EQUAL(status,
+			    NT_STATUS_INTERNAL_DB_ERROR)) {
+				DEBUG(1,("child process cannot initialize "
+					 "because connection to CTDB "
+					 "has failed\n"));
+				goto exit;
+			}
+
 			DEBUG(0,("reinit_after_fork() failed\n"));
 			smb_panic("reinit_after_fork() failed");
 		}

Modified: branches/samba/experimental/source3/smbd/server_exit.c
===================================================================
--- branches/samba/experimental/source3/smbd/server_exit.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/server_exit.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -152,9 +152,6 @@
 		rpc_lsarpc_shutdown();
 	}
 
-	locking_end();
-	printing_end();
-
 	/*
 	 * we need to force the order of freeing the following,
 	 * because smbd_msg_ctx is not a talloc child of smbd_server_conn.
@@ -165,6 +162,9 @@
 	server_event_context_free();
 	TALLOC_FREE(smbd_memcache_ctx);
 
+	locking_end();
+	printing_end();
+
 	if (how != SERVER_EXIT_NORMAL) {
 		DEBUGSEP(0);
 		DEBUG(0,("Abnormal server exit: %s\n",

Modified: branches/samba/experimental/source3/smbd/service.c
===================================================================
--- branches/samba/experimental/source3/smbd/service.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/service.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -853,27 +853,21 @@
 	 *
 	 */
 
-	{
-		bool can_write = False;
+	share_access_check(conn->session_info->security_token,
+			   lp_servicename(snum), MAXIMUM_ALLOWED_ACCESS,
+			   &conn->share_access);
 
-		can_write = share_access_check(conn->session_info->security_token,
-					       lp_servicename(snum),
-					       FILE_WRITE_DATA);
-
-		if (!can_write) {
-			if (!share_access_check(conn->session_info->security_token,
-						lp_servicename(snum),
-						FILE_READ_DATA)) {
-				/* No access, read or write. */
-				DEBUG(0,("make_connection: connection to %s "
-					 "denied due to security "
-					 "descriptor.\n",
-					  lp_servicename(snum)));
-				*pstatus = NT_STATUS_ACCESS_DENIED;
-				goto err_root_exit;
-			} else {
-				conn->read_only = True;
-			}
+	if ((conn->share_access & FILE_WRITE_DATA) == 0) {
+		if ((conn->share_access & FILE_READ_DATA) == 0) {
+			/* No access, read or write. */
+			DEBUG(0,("make_connection: connection to %s "
+				 "denied due to security "
+				 "descriptor.\n",
+				 lp_servicename(snum)));
+			*pstatus = NT_STATUS_ACCESS_DENIED;
+			goto err_root_exit;
+		} else {
+			conn->read_only = True;
 		}
 	}
 	/* Initialise VFS function pointers */

Modified: branches/samba/experimental/source3/smbd/smb2_create.c
===================================================================
--- branches/samba/experimental/source3/smbd/smb2_create.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/smb2_create.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -736,8 +736,13 @@
 				uint32_t max_access_granted;
 				DATA_BLOB blob = data_blob_const(p, sizeof(p));
 
-				status = smbd_check_open_rights(smb1req->conn,
+				status = smbd_calculate_access_mask(smb1req->conn,
 							result->fsp_name,
+							/*
+							 * at this stage
+							 * it exists
+							 */
+							true,
 							SEC_FLAG_MAXIMUM_ALLOWED,
 							&max_access_granted);
 

Modified: branches/samba/experimental/source3/smbd/smb2_ioctl.c
===================================================================
--- branches/samba/experimental/source3/smbd/smb2_ioctl.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/smb2_ioctl.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -398,6 +398,11 @@
 		char *pdata;
 		NTSTATUS status;
 
+		if (fsp == NULL) {
+			tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
+			return tevent_req_post(req, ev);
+		}
+
 		if (in_max_output < 16) {
 			DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: "
 				 "in_max_output(%u) < 16 is invalid!\n",
@@ -584,6 +589,11 @@
 
 	state->out_output.length = nread;
 
+	if (is_data_outstanding) {
+		tevent_req_nterror(req, STATUS_BUFFER_OVERFLOW);
+		return;
+	}
+
 	tevent_req_done(req);
 }
 

Modified: branches/samba/experimental/source3/smbd/smb2_read.c
===================================================================
--- branches/samba/experimental/source3/smbd/smb2_read.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/smb2_read.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -575,6 +575,11 @@
 	state->out_data.length = nread;
 	state->out_remaining = 0;
 
+	/*
+	 * TODO: add STATUS_BUFFER_OVERFLOW handling, once we also
+	 * handle it in SMB1 pipe_read_andx_done().
+	 */
+
 	tevent_req_done(req);
 }
 

Modified: branches/samba/experimental/source3/smbd/smb2_server.c
===================================================================
--- branches/samba/experimental/source3/smbd/smb2_server.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/smb2_server.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -665,10 +665,18 @@
 	}
 
 	newreq->sconn = req->sconn;
+	newreq->session = req->session;
 	newreq->do_signing = req->do_signing;
 	newreq->current_idx = req->current_idx;
 	newreq->async = false;
 	newreq->cancelled = false;
+	/* Note we are leaving:
+		->tcon
+		->smb1req
+		->compat_chain_fsp
+	   uninitialized as NULL here as
+	   they're not used in the interim
+	   response code. JRA. */
 
 	outvec = talloc_zero_array(newreq, struct iovec, count);
 	if (!outvec) {
@@ -915,7 +923,7 @@
 
 	if (req->do_signing) {
 		status = smb2_signing_sign_pdu(req->session->session_key,
-					state->vector, 3);
+					&state->vector[1], 2);
 		if (!NT_STATUS_IS_OK(status)) {
 			return status;
 		}
@@ -1096,6 +1104,14 @@
 		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
 	}
 
+	/*
+	 * Check if the client provided a valid session id,
+	 * if so smbd_smb2_request_check_session() calls
+	 * set_current_user_info().
+	 *
+	 * As some command don't require a valid session id
+	 * we defer the check of the session_status
+	 */
 	session_status = smbd_smb2_request_check_session(req);
 
 	req->do_signing = false;
@@ -1131,6 +1147,9 @@
 
 	switch (opcode) {
 	case SMB2_OP_NEGPROT:
+		/* This call needs to be run as root */
+		change_to_root_user();
+
 		{
 			START_PROFILE(smb2_negprot);
 			return_value = smbd_smb2_request_process_negprot(req);
@@ -1139,6 +1158,9 @@
 		break;
 
 	case SMB2_OP_SESSSETUP:
+		/* This call needs to be run as root */
+		change_to_root_user();
+
 		{
 			START_PROFILE(smb2_sesssetup);
 			return_value = smbd_smb2_request_process_sesssetup(req);
@@ -1152,6 +1174,9 @@
 			break;
 		}
 
+		/* This call needs to be run as root */
+		change_to_root_user();
+
 		{
 			START_PROFILE(smb2_logoff);
 			return_value = smbd_smb2_request_process_logoff(req);
@@ -1164,12 +1189,16 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
-		status = smbd_smb2_request_check_session(req);
-		if (!NT_STATUS_IS_OK(status)) {
-			return_value = smbd_smb2_request_error(req, status);
-			break;
-		}
 
+		/*
+		 * This call needs to be run as root.
+		 *
+		 * smbd_smb2_request_process_tcon()
+		 * calls make_connection_snum(), which will call
+		 * change_to_user(), when needed.
+		 */
+		change_to_root_user();
+
 		{
 			START_PROFILE(smb2_tcon);
 			return_value = smbd_smb2_request_process_tcon(req);
@@ -1182,12 +1211,21 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			return_value = smbd_smb2_request_error(req, status);
 			break;
 		}
+		/* This call needs to be run as root */
+		change_to_root_user();
 
+
 		{
 			START_PROFILE(smb2_tdis);
 			return_value = smbd_smb2_request_process_tdis(req);
@@ -1200,6 +1238,12 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			return_value = smbd_smb2_request_error(req, status);
@@ -1218,6 +1262,12 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			return_value = smbd_smb2_request_error(req, status);
@@ -1236,6 +1286,12 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			return_value = smbd_smb2_request_error(req, status);
@@ -1254,6 +1310,12 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			return_value = smbd_smb2_request_error(req, status);
@@ -1272,6 +1334,12 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			return_value = smbd_smb2_request_error(req, status);
@@ -1294,6 +1362,12 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			/* Too ugly to live ? JRA. */
@@ -1316,6 +1390,12 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			return_value = smbd_smb2_request_error(req, status);
@@ -1330,6 +1410,13 @@
 		break;
 
 	case SMB2_OP_CANCEL:
+		/*
+		 * This call needs to be run as root
+		 *
+		 * That is what we also do in the SMB1 case.
+		 */
+		change_to_root_user();
+
 		{
 			START_PROFILE(smb2_cancel);
 			return_value = smbd_smb2_request_process_cancel(req);
@@ -1338,9 +1425,14 @@
 		break;
 
 	case SMB2_OP_KEEPALIVE:
-		{START_PROFILE(smb2_keepalive);
-		return_value = smbd_smb2_request_process_keepalive(req);
-		END_PROFILE(smb2_keepalive);}
+		/* This call needs to be run as root */
+		change_to_root_user();
+
+		{
+			START_PROFILE(smb2_keepalive);
+			return_value = smbd_smb2_request_process_keepalive(req);
+			END_PROFILE(smb2_keepalive);
+		}
 		break;
 
 	case SMB2_OP_FIND:
@@ -1348,6 +1440,12 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			return_value = smbd_smb2_request_error(req, status);
@@ -1366,6 +1464,12 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			return_value = smbd_smb2_request_error(req, status);
@@ -1384,6 +1488,12 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			return_value = smbd_smb2_request_error(req, status);
@@ -1402,6 +1512,12 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			return_value = smbd_smb2_request_error(req, status);
@@ -1420,6 +1536,12 @@
 			return_value = smbd_smb2_request_error(req, session_status);
 			break;
 		}
+		/*
+		 * This call needs to be run as user.
+		 *
+		 * smbd_smb2_request_check_tcon()
+		 * calls change_to_user() on success.
+		 */
 		status = smbd_smb2_request_check_tcon(req);
 		if (!NT_STATUS_IS_OK(status)) {
 			return_value = smbd_smb2_request_error(req, status);
@@ -2206,6 +2328,8 @@
 		return;
 	}
 	tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);
+
+	sconn->num_requests++;
 }
 
 static void smbd_smb2_request_incoming(struct tevent_req *subreq)
@@ -2262,4 +2386,19 @@
 		return;
 	}
 	tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn);
+
+	sconn->num_requests++;
+
+	/* The timeout_processing function isn't run nearly
+	   often enough to implement 'max log size' without
+	   overrunning the size of the file by many megabytes.
+	   This is especially true if we are running at debug
+	   level 10.  Checking every 50 SMB2s is a nice
+	   tradeoff of performance vs log file size overrun. */
+
+	if ((sconn->num_requests % 50) == 0 &&
+	    need_to_check_log_size()) {
+		change_to_root_user();
+		check_log_size();
+	}
 }

Modified: branches/samba/experimental/source3/smbd/smb2_tcon.c
===================================================================
--- branches/samba/experimental/source3/smbd/smb2_tcon.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/smb2_tcon.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -271,7 +271,7 @@
 		break;
 	}
 
-	*out_maximal_access = FILE_GENERIC_ALL;
+	*out_maximal_access = tcon->compat_conn->share_access;
 
 	*out_tree_id = tcon->tid;
 	return NT_STATUS_OK;

Modified: branches/samba/experimental/source3/smbd/uid.c
===================================================================
--- branches/samba/experimental/source3/smbd/uid.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/smbd/uid.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -121,8 +121,9 @@
 		conn);
 
 	if (!readonly_share &&
-	    !share_access_check(session_info->security_token, lp_servicename(snum),
-				FILE_WRITE_DATA)) {
+	    !share_access_check(session_info->security_token,
+				lp_servicename(snum), FILE_WRITE_DATA,
+				NULL)) {
 		/* smb.conf allows r/w, but the security descriptor denies
 		 * write. Fall back to looking at readonly. */
 		readonly_share = True;
@@ -130,9 +131,11 @@
 			 "security descriptor\n"));
 	}
 
-	if (!share_access_check(session_info->security_token, lp_servicename(snum),
+	if (!share_access_check(session_info->security_token,
+				lp_servicename(snum),
 				readonly_share ?
-				FILE_READ_DATA : FILE_WRITE_DATA)) {
+				FILE_READ_DATA : FILE_WRITE_DATA,
+				NULL)) {
 		return False;
 	}
 

Modified: branches/samba/experimental/source3/utils/net_afs.c
===================================================================
--- branches/samba/experimental/source3/utils/net_afs.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/utils/net_afs.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -19,6 +19,8 @@
 
 #include "includes.h"
 #include "utils/net.h"
+#include "secrets.h"
+#include "system/filesys.h"
 
 int net_afs_usage(struct net_context *c, int argc, const char **argv)
 {
@@ -35,7 +37,7 @@
 	struct afs_keyfile keyfile;
 
 	if (argc != 2) {
-		d_printf(_("Usage:")," net afs key <keyfile> cell\n");
+		d_printf("%s net afs key <keyfile> cell\n", _("Usage:"));
 		return -1;
 	}
 
@@ -70,7 +72,8 @@
 	char *token;
 
 	if (argc != 2) {
-		fprintf(stderr, _("Usage:")," net afs impersonate <user> <cell>\n");
+		d_fprintf(stderr, "%s net afs impersonate <user> <cell>\n",
+			  _("Usage:"));
 	        exit(1);
 	}
 

Modified: branches/samba/experimental/source3/utils/net_cache.c
===================================================================
--- branches/samba/experimental/source3/utils/net_cache.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/utils/net_cache.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -244,7 +244,7 @@
 
 	if (gencache_get_data_blob(keystr, &value, &timeout, NULL)) {
 		print_cache_entry(keystr, value, timeout, NULL);
-		SAFE_FREE(value.data);
+		data_blob_free(&value);
 		return 0;
 	}
 

Modified: branches/samba/experimental/source3/utils/net_conf.c
===================================================================
--- branches/samba/experimental/source3/utils/net_conf.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/utils/net_conf.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -585,7 +585,6 @@
 	const char *comment = NULL;
 	const char *guest_ok = "no";
 	const char *writeable = "no";
-	SMB_STRUCT_STAT sbuf;
 	TALLOC_CTX *mem_ctx = talloc_stackframe();
 
 	if (c->display_usage) {
@@ -685,22 +684,6 @@
 		goto done;
 	}
 
-	if (sys_stat(path, &sbuf, false) != 0) {
-		d_fprintf(stderr,
-			  _("ERROR: cannot stat path '%s' to ensure "
-			    "this is a directory.\n"
-			    "Error was '%s'.\n"),
-			  path, strerror(errno));
-		goto done;
-	}
-
-	if (!S_ISDIR(sbuf.st_ex_mode)) {
-		d_fprintf(stderr,
-			  _("ERROR: path '%s' is not a directory.\n"),
-			  path);
-		goto done;
-	}
-
 	/*
 	 * start a transaction
 	 */

Modified: branches/samba/experimental/source3/utils/net_printing.c
===================================================================
--- branches/samba/experimental/source3/utils/net_printing.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/utils/net_printing.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -23,12 +23,14 @@
 #include "system/filesys.h"
 #include "utils/net.h"
 #include "rpc_client/rpc_client.h"
+#include "rpc_client/cli_pipe.h"
 #include "librpc/gen_ndr/ndr_ntprinting.h"
-#include "librpc/gen_ndr/ndr_spoolss_c.h"
-#include "rpc_client/cli_spoolss.h"
+#include "librpc/gen_ndr/ndr_spoolss.h"
 #include "../libcli/security/security.h"
 #include "../librpc/gen_ndr/ndr_security.h"
+#include "../librpc/gen_ndr/ndr_winreg.h"
 #include "util_tdb.h"
+#include "printing/nt_printing_migrate.h"
 
 #define FORMS_PREFIX "FORMS/"
 #define DRIVERS_PREFIX "DRIVERS/"
@@ -218,419 +220,11 @@
 	return ret;
 }
 
-static NTSTATUS migrate_form(TALLOC_CTX *mem_ctx,
-			 struct rpc_pipe_client *pipe_hnd,
-			 const char *key_name,
-			 unsigned char *data,
-			 size_t length)
-{
-	struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
-	struct policy_handle hnd;
-	enum ndr_err_code ndr_err;
-	struct ntprinting_form r;
-	union spoolss_AddFormInfo f;
-	struct spoolss_AddFormInfo1 f1;
-	DATA_BLOB blob;
-	NTSTATUS status;
-	WERROR result;
-
-	blob = data_blob_const(data, length);
-
-	ZERO_STRUCT(r);
-
-	ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
-		   (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
-	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		d_fprintf(stderr, _("form pull failed: %s\n"),
-			  ndr_errstr(ndr_err));
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	/* Don't migrate builtin forms */
-	if (r.flag == SPOOLSS_FORM_BUILTIN) {
-		return NT_STATUS_OK;
-	}
-
-	d_printf(_("Migrating Form: %s\n"), key_name);
-
-	result = rpccli_spoolss_openprinter_ex(pipe_hnd,
-					       mem_ctx,
-					       pipe_hnd->srv_name_slash,
-					       MAXIMUM_ALLOWED_ACCESS,
-					       &hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		d_fprintf(stderr, _("OpenPrinter(%s) failed: %s\n"),
-				  pipe_hnd->srv_name_slash, win_errstr(result));
-		return werror_to_ntstatus(result);
-	}
-
-	f1.form_name = key_name;
-	f1.flags = r.flag;
-
-	f1.size.width = r.width;
-	f1.size.height = r.length;
-
-	f1.area.top = r.top;
-	f1.area.right = r.right;
-	f1.area.bottom = r.bottom;
-	f1.area.left = r.left;
-
-	f.info1 = &f1;
-
-	status = dcerpc_spoolss_AddForm(b,
-					mem_ctx,
-					&hnd,
-					1,
-					f,
-					&result);
-	if (!NT_STATUS_IS_OK(status)) {
-		d_printf(_("\tAddForm(%s) refused -- %s.\n"),
-			f.info1->form_name, nt_errstr(status));
-	} else if (!W_ERROR_IS_OK(result)) {
-		d_printf(_("\tAddForm(%s) refused -- %s.\n"),
-			f.info1->form_name, win_errstr(result));
-		status = werror_to_ntstatus(result);
-	}
-
-	dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
-
-	return status;
-}
-
-static NTSTATUS migrate_driver(TALLOC_CTX *mem_ctx,
-			       struct rpc_pipe_client *pipe_hnd,
-			       const char *key_name,
-			       unsigned char *data,
-			       size_t length)
-{
-	struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
-	enum ndr_err_code ndr_err;
-	struct ntprinting_driver r;
-	struct spoolss_AddDriverInfoCtr d;
-	struct spoolss_AddDriverInfo3 d3;
-	struct spoolss_StringArray a;
-	DATA_BLOB blob;
-	NTSTATUS status;
-	WERROR result;
-
-	blob = data_blob_const(data, length);
-
-	ZERO_STRUCT(r);
-
-	ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
-		   (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
-	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		d_fprintf(stderr, _("driver pull failed: %s\n"),
-			  ndr_errstr(ndr_err));
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	d_printf(_("Migrating Printer Driver: %s\n"), key_name);
-
-	ZERO_STRUCT(d3);
-	ZERO_STRUCT(a);
-
-	a.string = r.dependent_files;
-
-	d3.architecture = r.environment;
-	d3.config_file = r.configfile;
-	d3.data_file = r.datafile;
-	d3.default_datatype = r.defaultdatatype;
-	d3.dependent_files = &a;
-	d3.driver_path = r.driverpath;
-	d3.help_file = r.helpfile;
-	d3.monitor_name = r.monitorname;
-	d3.driver_name = r.name;
-	d3.version = r.version;
-
-	d.info.info3 = &d3;
-	d.level = 3;
-
-	status = dcerpc_spoolss_AddPrinterDriver(b,
-						 mem_ctx,
-						 NULL,
-						 &d,
-						 &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		d_printf(_("\tAddDriver driver: [%s] refused -- %s.\n"),
-			d3.driver_name, nt_errstr(status));
-	} else if (!W_ERROR_IS_OK(result)) {
-		d_printf(_("\tAddDriver driver: [%s] refused -- %s.\n"),
-			d3.driver_name, win_errstr(result));
-		status = werror_to_ntstatus(result);
-	}
-
-	return status;
-}
-
-static NTSTATUS migrate_printer(TALLOC_CTX *mem_ctx,
-				struct rpc_pipe_client *pipe_hnd,
-				const char *key_name,
-				unsigned char *data,
-				size_t length)
-{
-	struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
-	struct policy_handle hnd;
-	enum ndr_err_code ndr_err;
-	struct ntprinting_printer r;
-	struct spoolss_SetPrinterInfo2 info2;
-	struct spoolss_DeviceMode dm;
-	struct spoolss_SetPrinterInfoCtr info_ctr;
-	struct spoolss_DevmodeContainer devmode_ctr;
-	struct sec_desc_buf secdesc_ctr;
-	DATA_BLOB blob;
-	NTSTATUS status;
-	WERROR result;
-	int j;
-
-	if (strequal(key_name, "printers")) {
-		return NT_STATUS_OK;
-	}
-
-	blob = data_blob_const(data, length);
-
-	ZERO_STRUCT(r);
-
-	ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
-		   (ndr_pull_flags_fn_t) ndr_pull_ntprinting_printer);
-	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		d_fprintf(stderr, _("printer pull failed: %s\n"),
-			  ndr_errstr(ndr_err));
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	d_printf(_("Migrating Printer: %s\n"), key_name);
-
-	result = rpccli_spoolss_openprinter_ex(pipe_hnd,
-					       mem_ctx,
-					       key_name,
-					       MAXIMUM_ALLOWED_ACCESS,
-					       &hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		d_fprintf(stderr, _("OpenPrinter(%s) failed: %s\n"),
-				  key_name, win_errstr(result));
-		return werror_to_ntstatus(result);
-	}
-
-	/* Create printer info level 2 */
-	ZERO_STRUCT(info2);
-	ZERO_STRUCT(devmode_ctr);
-	ZERO_STRUCT(secdesc_ctr);
-
-	info2.attributes = r.info.attributes;
-	info2.averageppm = r.info.averageppm;
-	info2.cjobs = r.info.cjobs;
-	info2.comment = r.info.comment;
-	info2.datatype = r.info.datatype;
-	info2.defaultpriority = r.info.default_priority;
-	info2.drivername = r.info.drivername;
-	info2.location = r.info.location;
-	info2.parameters = r.info.parameters;
-	info2.portname = r.info.portname;
-	info2.printername = r.info.printername;
-	info2.printprocessor = r.info.printprocessor;
-	info2.priority = r.info.priority;
-	info2.sepfile = r.info.sepfile;
-	info2.sharename = r.info.sharename;
-	info2.starttime = r.info.starttime;
-	info2.status = r.info.status;
-	info2.untiltime = r.info.untiltime;
-
-	/* Create Device Mode */
-	if (r.devmode != NULL) {
-		ZERO_STRUCT(dm);
-
-		dm.bitsperpel              = r.devmode->bitsperpel;
-		dm.collate                 = r.devmode->collate;
-		dm.color                   = r.devmode->color;
-		dm.copies                  = r.devmode->copies;
-		dm.defaultsource           = r.devmode->defaultsource;
-		dm.devicename              = r.devmode->devicename;
-		dm.displayflags            = r.devmode->displayflags;
-		dm.displayfrequency        = r.devmode->displayfrequency;
-		dm.dithertype              = r.devmode->dithertype;
-		dm.driverversion           = r.devmode->driverversion;
-		dm.duplex                  = r.devmode->duplex;
-		dm.fields                  = r.devmode->fields;
-		dm.formname                = r.devmode->formname;
-		dm.icmintent               = r.devmode->icmintent;
-		dm.icmmethod               = r.devmode->icmmethod;
-		dm.logpixels               = r.devmode->logpixels;
-		dm.mediatype               = r.devmode->mediatype;
-		dm.orientation             = r.devmode->orientation;
-		dm.panningheight           = r.devmode->pelsheight;
-		dm.panningwidth            = r.devmode->panningwidth;
-		dm.paperlength             = r.devmode->paperlength;
-		dm.papersize               = r.devmode->papersize;
-		dm.paperwidth              = r.devmode->paperwidth;
-		dm.pelsheight              = r.devmode->pelsheight;
-		dm.pelswidth               = r.devmode->pelswidth;
-		dm.printquality            = r.devmode->printquality;
-		dm.scale                   = r.devmode->scale;
-		dm.specversion             = r.devmode->specversion;
-		dm.ttoption                = r.devmode->ttoption;
-		dm.yresolution             = r.devmode->yresolution;
-
-		if (r.devmode->nt_dev_private != NULL) {
-			dm.driverextra_data.data   = r.devmode->nt_dev_private->data;
-			dm.driverextra_data.length = r.devmode->nt_dev_private->length;
-			dm.__driverextra_length    = r.devmode->nt_dev_private->length;
-		}
-
-		devmode_ctr.devmode = &dm;
-
-		info2.devmode_ptr = 1;
-	}
-
-	info_ctr.info.info2 = &info2;
-	info_ctr.level = 2;
-
-	status = dcerpc_spoolss_SetPrinter(b,
-					   mem_ctx,
-					   &hnd,
-					   &info_ctr,
-					   &devmode_ctr,
-					   &secdesc_ctr,
-					   0, /* command */
-					   &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		d_printf(_("\tSetPrinter(%s) level 2 refused -- %s.\n"),
-			key_name, nt_errstr(status));
-		goto done;
-	} else if (!W_ERROR_IS_OK(result)) {
-		d_printf(_("\tSetPrinter(%s) level 2 refused -- %s.\n"),
-			key_name, win_errstr(result));
-		status = werror_to_ntstatus(result);
-		goto done;
-	}
-
-	/* migrate printerdata */
-	for (j = 0; j < r.count; j++) {
-		char *valuename;
-		char *keyname;
-
-		if (r.printer_data[j].type == REG_NONE) {
-			continue;
-		}
-
-		keyname = CONST_DISCARD(char *, r.printer_data[j].name);
-		valuename = strchr(keyname, '\\');
-		if (valuename == NULL) {
-			continue;
-		} else {
-			valuename[0] = '\0';
-			valuename++;
-		}
-
-		printf("          data: %s\\%s\n", keyname, valuename);
-
-		status = dcerpc_spoolss_SetPrinterDataEx(b,
-							 mem_ctx,
-							 &hnd,
-							 keyname,
-							 valuename,
-							 r.printer_data[j].type,
-							 r.printer_data[j].data.data,
-							 r.printer_data[j].data.length,
-							 &result);
-		if (!NT_STATUS_IS_OK(status)) {
-			d_printf(_("\tSetPrinterDataEx: printer [%s], keyname [%s], valuename [%s] refused -- %s.\n"),
-				key_name, keyname, valuename, nt_errstr(status));
-			break;
-		} else if (!W_ERROR_IS_OK(result)) {
-			d_printf(_("\tSetPrinterDataEx: printer [%s], keyname [%s], valuename [%s] refused -- %s.\n"),
-				key_name, keyname, valuename, win_errstr(result));
-			status = werror_to_ntstatus(result);
-			break;
-		}
-	}
-
- done:
-	dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
-
-	return status;
-}
-
-static NTSTATUS migrate_secdesc(TALLOC_CTX *mem_ctx,
-				struct rpc_pipe_client *pipe_hnd,
-				const char *key_name,
-				unsigned char *data,
-				size_t length)
-{
-	struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
-	struct policy_handle hnd;
-	enum ndr_err_code ndr_err;
-	struct sec_desc_buf secdesc_ctr;
-	struct spoolss_SetPrinterInfo3 info3;
-	struct spoolss_SetPrinterInfoCtr info_ctr;
-	struct spoolss_DevmodeContainer devmode_ctr;
-	DATA_BLOB blob;
-	NTSTATUS status;
-	WERROR result;
-
-	if (strequal(key_name, "printers")) {
-		return NT_STATUS_OK;
-	}
-
-	blob = data_blob_const(data, length);
-
-	ZERO_STRUCT(secdesc_ctr);
-
-	ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &secdesc_ctr,
-		   (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
-	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		d_fprintf(stderr, _("security descriptor pull failed: %s\n"),
-			  ndr_errstr(ndr_err));
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	d_printf(_("Migrating Security Descriptor: %s\n"), key_name);
-
-	result = rpccli_spoolss_openprinter_ex(pipe_hnd,
-					       mem_ctx,
-					       key_name,
-					       MAXIMUM_ALLOWED_ACCESS,
-					       &hnd);
-	if (!W_ERROR_IS_OK(result)) {
-		d_fprintf(stderr, _("\tOpenPrinter(%s) failed: %s\n"),
-				  key_name, win_errstr(result));
-		return werror_to_ntstatus(result);
-	}
-
-	ZERO_STRUCT(devmode_ctr);
-
-	info3.sec_desc_ptr = 1;
-
-	info_ctr.info.info3 = &info3;
-	info_ctr.level = 3;
-
-	status = dcerpc_spoolss_SetPrinter(b,
-					   mem_ctx,
-					   &hnd,
-					   &info_ctr,
-					   &devmode_ctr,
-					   &secdesc_ctr,
-					   0, /* command */
-					   &result);
-	if (!NT_STATUS_IS_OK(status)) {
-		d_printf(_("\tSetPrinter(%s) level 3 refused -- %s.\n"),
-			key_name, nt_errstr(status));
-	} else if (!W_ERROR_IS_OK(result)) {
-		d_printf(_("\tSetPrinter(%s) level 3 refused -- %s.\n"),
-			key_name, win_errstr(result));
-		status = werror_to_ntstatus(result);
-	}
-
-	dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
-
-	return status;
-}
-
 static NTSTATUS printing_migrate_internal(struct net_context *c,
 					  const struct dom_sid *domain_sid,
 					  const char *domain_name,
 					  struct cli_state *cli,
-					  struct rpc_pipe_client *pipe_hnd,
+					  struct rpc_pipe_client *winreg_pipe,
 					  TALLOC_CTX *mem_ctx,
 					  int argc,
 					  const char **argv)
@@ -662,8 +256,8 @@
 		}
 
 		if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
-			migrate_form(tmp_ctx,
-				     pipe_hnd,
+			printing_tdb_migrate_form(tmp_ctx,
+				     winreg_pipe,
 				     (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
 				     dbuf.dptr,
 				     dbuf.dsize);
@@ -672,8 +266,8 @@
 		}
 
 		if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
-			migrate_driver(tmp_ctx,
-				       pipe_hnd,
+			printing_tdb_migrate_driver(tmp_ctx,
+				       winreg_pipe,
 				       (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
 				       dbuf.dptr,
 				       dbuf.dsize);
@@ -682,24 +276,36 @@
 		}
 
 		if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
-			migrate_printer(tmp_ctx,
-					pipe_hnd,
+			printing_tdb_migrate_printer(tmp_ctx,
+					winreg_pipe,
 					(const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
 					dbuf.dptr,
 					dbuf.dsize);
 			SAFE_FREE(dbuf.dptr);
 			continue;
 		}
+		SAFE_FREE(dbuf.dptr);
+	}
 
+	for (kbuf = tdb_firstkey(tdb);
+	     kbuf.dptr;
+	     newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
+	{
+		dbuf = tdb_fetch(tdb, kbuf);
+		if (!dbuf.dptr) {
+			continue;
+		}
+
 		if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
-			migrate_secdesc(tmp_ctx,
-					pipe_hnd,
+			printing_tdb_migrate_secdesc(tmp_ctx,
+					winreg_pipe,
 					(const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
 					dbuf.dptr,
 					dbuf.dsize);
 			SAFE_FREE(dbuf.dptr);
 			continue;
 		}
+		SAFE_FREE(dbuf.dptr);
 
 	}
 
@@ -725,7 +331,7 @@
 
 	return run_rpc_command(c,
 			       NULL,
-			       &ndr_table_spoolss.syntax_id,
+			       &ndr_table_winreg.syntax_id,
 			       0,
 			       printing_migrate_internal,
 			       argc,

Modified: branches/samba/experimental/source3/utils/net_registry.c
===================================================================
--- branches/samba/experimental/source3/utils/net_registry.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/utils/net_registry.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -122,23 +122,88 @@
 	return werr;
 }
 
+static WERROR registry_enumkey(struct registry_key* parent, const char* keyname, bool recursive)
+{
+	WERROR werr;
+	TALLOC_CTX *ctx = talloc_stackframe();
+	char*  subkey_name;
+	NTTIME modtime;
+	uint32_t count;
+	char* valname = NULL;
+	struct registry_value *valvalue = NULL;
+	struct registry_key* key = NULL;
+
+	werr = reg_openkey(ctx, parent, keyname, REG_KEY_READ, &key);
+	if (!W_ERROR_IS_OK(werr)) {
+		goto done;
+	}
+
+	if (recursive) {
+		printf("[%s]\n\n", key->key->name);
+	} else {
+		for (count = 0;
+		     werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
+		     W_ERROR_IS_OK(werr);
+		     count++)
+		{
+			print_registry_key(subkey_name, &modtime);
+		}
+		if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
+			goto done;
+		}
+	}
+
+	for (count = 0;
+	     werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
+	     W_ERROR_IS_OK(werr);
+	     count++)
+	{
+		print_registry_value_with_name(valname, valvalue);
+	}
+	if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
+		goto done;
+	}
+
+	if (!recursive) {
+		werr = WERR_OK;
+		goto done;
+	}
+
+	for (count = 0;
+	     werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
+	     W_ERROR_IS_OK(werr);
+	     count++)
+	{
+		werr = registry_enumkey(key, subkey_name, recursive);
+		if (!W_ERROR_IS_OK(werr)) {
+			goto done;
+		}
+	}
+	if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
+		goto done;
+	}
+
+	werr = WERR_OK;
+
+done:
+	TALLOC_FREE(ctx);
+	return werr;
+}
+
+
+
 /*
  *
  * the main "net registry" function implementations
  *
  */
-
 static int net_registry_enumerate(struct net_context *c, int argc,
 				  const char **argv)
 {
 	WERROR werr;
 	struct registry_key *key = NULL;
+	char* name = NULL;
 	TALLOC_CTX *ctx = talloc_stackframe();
-	char *subkey_name;
-	NTTIME modtime;
-	uint32_t count;
-	char *valname = NULL;
-	struct registry_value *valvalue = NULL;
 	int ret = -1;
 
 	if (argc != 1 || c->display_usage) {
@@ -151,40 +216,56 @@
 		goto done;
 	}
 
-	werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
+	werr = open_hive(ctx, argv[0], REG_KEY_READ, &key, &name);
 	if (!W_ERROR_IS_OK(werr)) {
 		d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
 		goto done;
 	}
 
-	for (count = 0;
-	     werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
-	     W_ERROR_IS_OK(werr);
-	     count++)
-	{
-		print_registry_key(subkey_name, &modtime);
+	werr = registry_enumkey(key, name, c->opt_reboot);
+	if (W_ERROR_IS_OK(werr)) {
+		ret = 0;
 	}
-	if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
+done:
+	TALLOC_FREE(ctx);
+	return ret;
+}
+
+static int net_registry_enumerate_recursive(struct net_context *c, int argc,
+					    const char **argv)
+{
+	WERROR werr;
+	struct registry_key *key = NULL;
+	char* name = NULL;
+	TALLOC_CTX *ctx = talloc_stackframe();
+	int ret = -1;
+
+	if (argc != 1 || c->display_usage) {
+		d_printf("%s\n%s",
+			 _("Usage:"),
+			 _("net registry enumerate <path>\n"));
+		d_printf("%s\n%s",
+			 _("Example:"),
+			 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
 		goto done;
 	}
 
-	for (count = 0;
-	     werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
-	     W_ERROR_IS_OK(werr);
-	     count++)
-	{
-		print_registry_value_with_name(valname, valvalue);
-	}
-	if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
+	werr = open_hive(ctx, argv[0], REG_KEY_READ, &key, &name);
+	if (!W_ERROR_IS_OK(werr)) {
+		d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
 		goto done;
 	}
 
-	ret = 0;
+	werr = registry_enumkey(key, name, true);
+	if (W_ERROR_IS_OK(werr)) {
+		ret = 0;
+	}
 done:
 	TALLOC_FREE(ctx);
 	return ret;
 }
 
+
 static int net_registry_createkey(struct net_context *c, int argc,
 				  const char **argv)
 {
@@ -958,9 +1039,11 @@
 		.createkey   = (reg_import_callback_createkey_t)&import_create_key,
 		.deletekey   = (reg_import_callback_deletekey_t)&import_delete_key,
 		.deleteval   = (reg_import_callback_deleteval_t)&import_delete_val,
-		.setval.registry_value = (reg_import_callback_setval_registry_value_t)
-		&import_create_val,
-		.setval_type           = REGISTRY_VALUE,
+		.setval      = {
+			.registry_value = (reg_import_callback_setval_registry_value_t)
+					  &import_create_val,
+		},
+		.setval_type = REGISTRY_VALUE,
 		.data        = &import_ctx
 	};
 
@@ -1174,6 +1257,14 @@
 			   "    Enumerate registry keys and values")
 		},
 		{
+			"enumerate_recursive",
+			net_registry_enumerate_recursive,
+			NET_TRANSPORT_LOCAL,
+			N_("Enumerate registry keys and values"),
+			N_("net registry enumerate_recursive\n"
+			   "    Enumerate registry keys and values")
+		},
+		{
 			"createkey",
 			net_registry_createkey,
 			NET_TRANSPORT_LOCAL,

Modified: branches/samba/experimental/source3/utils/net_rpc_registry.c
===================================================================
--- branches/samba/experimental/source3/utils/net_rpc_registry.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/utils/net_rpc_registry.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1959,7 +1959,9 @@
 		.createkey   = (reg_import_callback_createkey_t)&import_create_key,
 		.deletekey   = (reg_import_callback_deletekey_t)&import_delete_key,
 		.deleteval   = (reg_import_callback_deleteval_t)&import_delete_val,
-		.setval.blob = (reg_import_callback_setval_blob_t)&import_create_val,
+		.setval      = {
+			.blob = (reg_import_callback_setval_blob_t)&import_create_val,
+		},
 		.setval_type = BLOB,
 		.data = &import_ctx
 	};

Modified: branches/samba/experimental/source3/web/cgi.c
===================================================================
--- branches/samba/experimental/source3/web/cgi.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/web/cgi.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -23,6 +23,7 @@
 #include "web/swat_proto.h"
 #include "intl/lang_tdb.h"
 #include "auth.h"
+#include "secrets.h"
 
 #define MAX_VARIABLES 10000
 
@@ -46,6 +47,7 @@
 static const char *baseurl;
 static char *pathinfo;
 static char *C_user;
+static char *C_pass;
 static bool inetd_server;
 static bool got_request;
 
@@ -324,7 +326,24 @@
 		exit(0);
 	}
 
-	setuid(0);
+	C_user = SMB_STRDUP(user);
+
+	if (!setuid(0)) {
+		C_pass = secrets_fetch_generic("root", "SWAT");
+		if (C_pass == NULL) {
+			char *tmp_pass = NULL;
+			tmp_pass = generate_random_password(talloc_tos(),
+							    16, 16);
+			if (tmp_pass == NULL) {
+				printf("%sFailed to create random nonce for "
+				       "SWAT session\n<br>%s\n", head, tail);
+				exit(0);
+			}
+			secrets_store_generic("root", "SWAT", tmp_pass);
+			C_pass = SMB_STRDUP(tmp_pass);
+			TALLOC_FREE(tmp_pass);
+		}
+	}
 	setuid(pwd->pw_uid);
 	if (geteuid() != pwd->pw_uid || getuid() != pwd->pw_uid) {
 		printf("%sFailed to become user %s - uid=%d/%d<br>%s\n", 
@@ -396,6 +415,7 @@
 
 			/* Save the users name */
 			C_user = SMB_STRDUP(user);
+			C_pass = SMB_STRDUP(user_pass);
 			TALLOC_FREE(pass);
 			return True;
 		}
@@ -430,6 +450,13 @@
         return(C_user);
 }
 
+/***************************************************************************
+return a ptr to the users password
+  ***************************************************************************/
+char *cgi_user_pass(void)
+{
+        return(C_pass);
+}
 
 /***************************************************************************
 handle a file download

Modified: branches/samba/experimental/source3/web/statuspage.c
===================================================================
--- branches/samba/experimental/source3/web/statuspage.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/web/statuspage.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -249,9 +249,14 @@
 	int nr_running=0;
 	bool waitup = False;
 	TALLOC_CTX *ctx = talloc_stackframe();
+	const char form_name[] = "status";
 
 	smbd_pid = pid_to_procid(pidfile_pid("smbd"));
 
+	if (!verify_xsrf_token(form_name)) {
+		goto output_page;
+	}
+
 	if (cgi_variable("smbd_restart") || cgi_variable("all_restart")) {
 		stop_smbd();
 		start_smbd();
@@ -328,9 +333,11 @@
 
 	initPid2Machine ();
 
+output_page:
 	printf("<H2>%s</H2>\n", _("Server Status"));
 
 	printf("<FORM method=post>\n");
+	print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
 
 	if (!autorefresh) {
 		printf("<input type=submit value=\"%s\" name=\"autorefresh\">\n", _("Auto Refresh"));

Modified: branches/samba/experimental/source3/web/swat.c
===================================================================
--- branches/samba/experimental/source3/web/swat.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/web/swat.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -35,6 +35,7 @@
 #include "printing/load.h"
 #include "passdb.h"
 #include "intl/lang_tdb.h"
+#include "../lib/crypto/md5.h"
 
 static int demo_mode = False;
 static int passwd_only = False;
@@ -56,6 +57,9 @@
 #define DISABLE_USER_FLAG "disable_user_flag"
 #define ENABLE_USER_FLAG "enable_user_flag"
 #define RHOST "remote_host"
+#define XSRF_TOKEN "xsrf"
+#define XSRF_TIME "xsrf_time"
+#define XSRF_TIMEOUT 300
 
 #define _(x) lang_msg_rotate(talloc_tos(),x)
 
@@ -123,7 +127,7 @@
 	char *p = newstring;
 
 	while (*str) {
-		if (*str != ' ') *p++ = toupper_ascii(*str);
+		if (*str != ' ') *p++ = toupper_m(*str);
 		++str;
 	}
 	*p = '\0';
@@ -144,6 +148,76 @@
 	return parmname;
 }
 
+void get_xsrf_token(const char *username, const char *pass,
+		    const char *formname, time_t xsrf_time, char token_str[33])
+{
+	struct MD5Context md5_ctx;
+	uint8_t token[16];
+	int i;
+
+	token_str[0] = '\0';
+	ZERO_STRUCT(md5_ctx);
+	MD5Init(&md5_ctx);
+
+	MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
+	MD5Update(&md5_ctx, (uint8_t *)&xsrf_time, sizeof(time_t));
+	if (username != NULL) {
+		MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
+	}
+	if (pass != NULL) {
+		MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
+	}
+
+	MD5Final(token, &md5_ctx);
+
+	for(i = 0; i < sizeof(token); i++) {
+		char tmp[3];
+
+		snprintf(tmp, sizeof(tmp), "%02x", token[i]);
+		strncat(token_str, tmp, sizeof(tmp));
+	}
+}
+
+void print_xsrf_token(const char *username, const char *pass,
+		      const char *formname)
+{
+	char token[33];
+	time_t xsrf_time = time(NULL);
+
+	get_xsrf_token(username, pass, formname, xsrf_time, token);
+	printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
+	       XSRF_TOKEN, token);
+	printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
+	       XSRF_TIME, (long long int)xsrf_time);
+}
+
+bool verify_xsrf_token(const char *formname)
+{
+	char expected[33];
+	const char *username = cgi_user_name();
+	const char *pass = cgi_user_pass();
+	const char *token = cgi_variable_nonull(XSRF_TOKEN);
+	const char *time_str = cgi_variable_nonull(XSRF_TIME);
+	time_t xsrf_time = 0;
+	time_t now = time(NULL);
+
+	if (sizeof(time_t) == sizeof(int)) {
+		xsrf_time = atoi(time_str);
+	} else if (sizeof(time_t) == sizeof(long)) {
+		xsrf_time = atol(time_str);
+	} else if (sizeof(time_t) == sizeof(long long)) {
+		xsrf_time = atoll(time_str);
+	}
+
+	if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
+		return false;
+	}
+
+	get_xsrf_token(username, pass, formname, xsrf_time, expected);
+	return (strncmp(expected, token, sizeof(expected)) == 0);
+}
+
+
 /****************************************************************************
   include a lump of html in a page 
 ****************************************************************************/
@@ -620,13 +694,20 @@
 static void viewconfig_page(void)
 {
 	int full_view=0;
+	const char form_name[] = "viewconfig";
 
+	if (!verify_xsrf_token(form_name)) {
+		goto output_page;
+	}
+
 	if (cgi_variable("full_view")) {
 		full_view = 1;
 	}
 
+output_page:
 	printf("<H2>%s</H2>\n", _("Current Config"));
 	printf("<form method=post>\n");
+	print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
 
 	if (full_view) {
 		printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
@@ -646,18 +727,25 @@
 static void wizard_params_page(void)
 {
 	unsigned int parm_filter = FLAG_WIZARD;
+	const char form_name[] = "wizard_params";
 
 	/* Here we first set and commit all the parameters that were selected
  	   in the previous screen. */
 
 	printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
 
+	if (!verify_xsrf_token(form_name)) {
+		goto output_page;
+	}
+
 	if (cgi_variable("Commit")) {
 		commit_parameters(GLOBAL_SECTION_SNUM);
 		save_reload(-1);
 	}
 
+output_page:
 	printf("<form name=\"swatform\" method=post action=wizard_params>\n");
+	print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
 
 	if (have_write_access) {
 		printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
@@ -693,7 +781,12 @@
 	int have_home = -1;
 	int HomeExpo = 0;
 	int SerType = 0;
+	const char form_name[] = "wizard";
 
+	if (!verify_xsrf_token(form_name)) {
+		goto output_page;
+	}
+
 	if (cgi_variable("Rewrite")) {
 		(void) rewritecfg_file();
 		return;
@@ -784,9 +877,11 @@
 
 	role = lp_server_role();
 
+output_page:
 	/* Here we go ... */
 	printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
 	printf("<form method=post action=wizard>\n");
+	print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
 
 	if (have_write_access) {
 		printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
@@ -855,9 +950,14 @@
 {
 	unsigned int parm_filter = FLAG_BASIC;
 	int mode = 0;
+	const char form_name[] = "globals";
 
 	printf("<H2>%s</H2>\n", _("Global Parameters"));
 
+	if (!verify_xsrf_token(form_name)) {
+		goto output_page;
+	}
+
 	if (cgi_variable("Commit")) {
 		commit_parameters(GLOBAL_SECTION_SNUM);
 		save_reload(-1);
@@ -870,7 +970,9 @@
 	if ( cgi_variable("AdvMode"))
 		mode = 1;
 
+output_page:
 	printf("<form name=\"swatform\" method=post action=globals>\n");
+	print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
 
 	ViewModeBoxes( mode );
 	switch ( mode ) {
@@ -910,11 +1012,17 @@
 	int mode = 0;
 	unsigned int parm_filter = FLAG_BASIC;
 	size_t converted_size;
+	const char form_name[] = "shares";
 
+	printf("<H2>%s</H2>\n", _("Share Parameters"));
+
+	if (!verify_xsrf_token(form_name)) {
+		goto output_page;
+	}
+
 	if (share)
 		snum = lp_servicenumber(share);
 
-	printf("<H2>%s</H2>\n", _("Share Parameters"));
 
 	if (cgi_variable("Commit") && snum >= 0) {
 		commit_parameters(snum);
@@ -940,10 +1048,6 @@
 		}
 	}
 
-	printf("<FORM name=\"swatform\" method=post>\n");
-
-	printf("<table>\n");
-
 	if ( cgi_variable("ViewMode") )
 		mode = atoi(cgi_variable_nonull("ViewMode"));
 	if ( cgi_variable("BasicMode"))
@@ -951,6 +1055,12 @@
 	if ( cgi_variable("AdvMode"))
 		mode = 1;
 
+output_page:
+	printf("<FORM name=\"swatform\" method=post>\n");
+	print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
+
+	printf("<table>\n");
+
 	ViewModeBoxes( mode );
 	switch ( mode ) {
 		case 0:
@@ -1129,11 +1239,9 @@
 	if(cgi_variable(CHG_S_PASSWD_FLAG)) {
 		printf("<p>");
 		if (rslt == True) {
-			printf(_(" The passwd for '%s' has been changed."), cgi_variable_nonull(SWAT_USER));
-			printf("\n");
+			printf("%s\n", _(" The passwd has been changed."));
 		} else {
-			printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable_nonull(SWAT_USER));
-			printf("\n");
+			printf("%s\n", _(" The passwd has NOT been changed."));
 		}
 	}
 
@@ -1146,20 +1254,15 @@
 static void passwd_page(void)
 {
 	const char *new_name = cgi_user_name();
+	const char passwd_form[] = "passwd";
+	const char rpasswd_form[] = "rpasswd";
 
-	/* 
-	 * After the first time through here be nice. If the user
-	 * changed the User box text to another users name, remember it.
-	 */
-	if (cgi_variable(SWAT_USER)) {
-		new_name = cgi_variable_nonull(SWAT_USER);
-	} 
-
 	if (!new_name) new_name = "";
 
 	printf("<H2>%s</H2>\n", _("Server Password Management"));
 
 	printf("<FORM name=\"swatform\" method=post>\n");
+	print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
 
 	printf("<table>\n");
 
@@ -1199,14 +1302,16 @@
 	 * Do some work if change, add, disable or enable was
 	 * requested. It could be this is the first time through this
 	 * code, so there isn't anything to do.  */
-	if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
-	    (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
+	if (verify_xsrf_token(passwd_form) &&
+	   ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
+	    (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
 		chg_passwd();		
 	}
 
 	printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
 
 	printf("<FORM name=\"swatform\" method=post>\n");
+	print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
 
 	printf("<table>\n");
 
@@ -1239,7 +1344,7 @@
 	 * password somewhere other than the server. It could be this
 	 * is the first time through this code, so there isn't
 	 * anything to do.  */
-	if (cgi_variable(CHG_R_PASSWD_FLAG)) {
+	if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
 		chg_passwd();		
 	}
 
@@ -1256,18 +1361,15 @@
 	int i;
 	int mode = 0;
 	unsigned int parm_filter = FLAG_BASIC;
+	const char form_name[] = "printers";
 
+	if (!verify_xsrf_token(form_name)) {
+		goto output_page;
+	}
+
 	if (share)
 		snum = lp_servicenumber(share);
 
-        printf("<H2>%s</H2>\n", _("Printer Parameters"));
- 
-        printf("<H3>%s</H3>\n", _("Important Note:"));
-        printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
-        printf("%s",_("are autoloaded printers from "));
-        printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
-        printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
-
 	if (cgi_variable("Commit") && snum >= 0) {
 		commit_parameters(snum);
 		if (snum >= iNumNonAutoPrintServices)
@@ -1296,8 +1398,6 @@
 		}
 	}
 
-	printf("<FORM name=\"swatform\" method=post>\n");
-
 	if ( cgi_variable("ViewMode") )
 		mode = atoi(cgi_variable_nonull("ViewMode"));
         if ( cgi_variable("BasicMode"))
@@ -1305,6 +1405,19 @@
         if ( cgi_variable("AdvMode"))
                 mode = 1;
 
+output_page:
+        printf("<H2>%s</H2>\n", _("Printer Parameters"));
+
+        printf("<H3>%s</H3>\n", _("Important Note:"));
+        printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
+        printf("%s",_("are autoloaded printers from "));
+        printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
+        printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
+
+
+	printf("<FORM name=\"swatform\" method=post>\n");
+	print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
+
 	ViewModeBoxes( mode );
 	switch ( mode ) {
 		case 0:

Modified: branches/samba/experimental/source3/web/swat_proto.h
===================================================================
--- branches/samba/experimental/source3/web/swat_proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/web/swat_proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -31,6 +31,7 @@
 const char *cgi_variable_nonull(const char *name);
 bool am_root(void);
 char *cgi_user_name(void);
+char *cgi_user_pass(void);
 void cgi_setup(const char *rootdir, int auth_required);
 const char *cgi_baseurl(void);
 const char *cgi_pathinfo(void);
@@ -66,5 +67,10 @@
 /* The following definitions come from web/swat.c  */
 
 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid);
+void get_xsrf_token(const char *username, const char *pass,
+		    const char *formname, time_t xsrf_time, char token_str[33]);
+void print_xsrf_token(const char *username, const char *pass,
+		      const char *formname);
+bool verify_xsrf_token(const char *formname);
 
 #endif /*  _SWAT_PROTO_H_  */

Modified: branches/samba/experimental/source3/winbindd/idmap_autorid.c
===================================================================
--- branches/samba/experimental/source3/winbindd/idmap_autorid.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/winbindd/idmap_autorid.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -436,6 +436,13 @@
 	NTSTATUS status;
 	uint32_t hwm;
 
+	if (!strequal(dom->name, "*")) {
+		DEBUG(0, ("idmap_autorid_initialize: Error: autorid configured "
+			  "for domain '%s'. But autorid can only be used for "
+			  "the default idmap configuration.\n", dom->name));
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
 	config = TALLOC_ZERO_P(dom, struct autorid_global_config);
 	if (!config) {
 		DEBUG(0, ("Out of memory!\n"));
@@ -448,7 +455,7 @@
 	}
 
 	config->minvalue = dom->low_id;
-	config->rangesize = lp_parm_int(-1, "autorid", "rangesize", 100000);
+	config->rangesize = lp_parm_int(-1, "idmap config *", "rangesize", 100000);
 
 	if (config->rangesize < 2000) {
 		DEBUG(1, ("autorid rangesize must be at least 2000\n"));
@@ -523,14 +530,12 @@
 
 	dom->private_data = config;
 
-	if (!NT_STATUS_IS_OK(status)) {
-		goto error;
-	}
+	goto done;
 
-	return NT_STATUS_OK;
+error:
+	talloc_free(config);
 
-      error:
-	talloc_free(config);
+done:
 	talloc_free(storedconfig);
 
 	return status;

Modified: branches/samba/experimental/source3/winbindd/idmap_proto.h
===================================================================
--- branches/samba/experimental/source3/winbindd/idmap_proto.h	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/winbindd/idmap_proto.h	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,3 +1,30 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  ID Mapping
+ *
+ *  Copyright (C) Tim Potter 2000
+ *  Copyright (C) Jim McDonough <jmcd at us.ibm.com> 2003
+ *  Copyright (C) Simo Sorce 2003-2007
+ *  Copyright (C) Jeremy Allison 2006
+ *  Copyright (C) Michael Adam 2009-2010
+ *
+ *  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/>.
+ */
+
+#ifndef _WINBINDD_IDMAP_PROTO_H_
+#define _WINBINDD_IDMAP_PROTO_H_
+
 /* The following definitions come from winbindd/idmap.c  */
 
 bool idmap_is_offline(void);
@@ -31,3 +58,5 @@
 NTSTATUS idmap_sid_to_uid(const char *dom_name, struct dom_sid *sid, uid_t *uid);
 NTSTATUS idmap_sid_to_gid(const char *domname, struct dom_sid *sid, gid_t *gid);
 bool idmap_unix_id_is_in_range(uint32_t id, struct idmap_domain *dom);
+
+#endif /* _WINBINDD_IDMAP_PROTO_H_ */

Modified: branches/samba/experimental/source3/winbindd/wb_lookupsids.c
===================================================================
--- branches/samba/experimental/source3/winbindd/wb_lookupsids.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/winbindd/wb_lookupsids.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -198,7 +198,7 @@
 			}
 			subreq = dcerpc_wbint_LookupRids_send(
 				state, state->ev, dom_child_handle(d->domain),
-				&state->rids, &state->domain_name,
+				&d->sid, &state->rids, &state->domain_name,
 				&state->rid_names);
 			if (tevent_req_nomem(subreq, req)) {
 				return false;
@@ -428,6 +428,7 @@
 		req, struct wb_lookupsids_state);
 	struct wb_lookupsids_domain *d;
 	uint32_t i;
+	bool fallback = false;
 
 	NTSTATUS status, result;
 
@@ -437,13 +438,31 @@
 		return;
 	}
 
+	d = &state->domains[state->domains_done];
+
+	if (NT_STATUS_IS_ERR(result)) {
+		fallback = true;
+	} else if (state->tmp_names.count != d->sids.num_sids) {
+		fallback = true;
+	}
+
+	if (fallback) {
+		for (i=0; i < d->sids.num_sids; i++) {
+			uint32_t res_sid_index = d->sid_indexes[i];
+
+			state->single_sids[state->num_single_sids] =
+				res_sid_index;
+			state->num_single_sids += 1;
+		}
+		state->domains_done += 1;
+		wb_lookupsids_next(req, state);
+		return;
+	}
+
 	/*
-	 * Ignore "result" here. We depend on the individual states in
-	 * the translated names.
+	 * Look at the individual states in the translated names.
 	 */
 
-	d = &state->domains[state->domains_done];
-
 	for (i=0; i<state->tmp_names.count; i++) {
 
 		uint32_t res_sid_index = d->sid_indexes[i];
@@ -544,6 +563,7 @@
 	NTSTATUS status, result;
 	struct wb_lookupsids_domain *d;
 	uint32_t i;
+	bool fallback = false;
 
 	status = dcerpc_wbint_LookupRids_recv(subreq, state, &result);
 	TALLOC_FREE(subreq);
@@ -552,6 +572,30 @@
 	}
 
 	d = &state->domains[state->domains_done];
+
+	if (NT_STATUS_IS_ERR(result)) {
+		fallback = true;
+	} else if (state->rid_names.num_principals != d->sids.num_sids) {
+		fallback = true;
+	}
+
+	if (fallback) {
+		for (i=0; i < d->sids.num_sids; i++) {
+			uint32_t res_sid_index = d->sid_indexes[i];
+
+			state->single_sids[state->num_single_sids] =
+				res_sid_index;
+			state->num_single_sids += 1;
+		}
+		state->domains_done += 1;
+		wb_lookupsids_next(req, state);
+		return;
+	}
+
+	/*
+	 * Look at the individual states in the translated names.
+	 */
+
 	sid_copy(&src_domain_sid, get_global_sam_sid());
 	src_domain.name.string = get_global_sam_name();
 	src_domain.sid = &src_domain_sid;
@@ -595,6 +639,24 @@
 	if (tevent_req_is_nterror(req, &status)) {
 		return status;
 	}
+
+	/*
+	 * The returned names need to match the given sids,
+	 * if not we have a bug in the code!
+	 *
+	 */
+	SMB_ASSERT(state->res_names->count == state->num_sids);
+
+	/*
+	 * Not strictly needed, but it might make debugging in the callers
+	 * easier in future, if the talloc_array_length() returns the
+	 * expected result...
+	 */
+	state->res_domains->domains = talloc_realloc(state->res_domains,
+						     state->res_domains->domains,
+						     struct lsa_DomainInfo,
+						     state->res_domains->count);
+
 	*domains = talloc_move(mem_ctx, &state->res_domains);
 	*names = talloc_move(mem_ctx, &state->res_names);
 	return NT_STATUS_OK;

Modified: branches/samba/experimental/source3/winbindd/winbindd_dual_srv.c
===================================================================
--- branches/samba/experimental/source3/winbindd/winbindd_dual_srv.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/winbindd/winbindd_dual_srv.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -548,7 +548,7 @@
 	}
 
 	status = domain->methods->rids_to_names(
-		domain, talloc_tos(), &domain->sid, r->in.rids->rids,
+		domain, talloc_tos(), r->in.domain_sid, r->in.rids->rids,
 		r->in.rids->num_rids, &domain_name, &names, &types);
 	reset_cm_connection_on_error(domain, status);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -564,7 +564,8 @@
 	}
 
 	for (i=0; i<r->in.rids->num_rids; i++) {
-		sid_compose(&result[i].sid, &domain->sid, r->in.rids->rids[i]);
+		sid_compose(&result[i].sid, r->in.domain_sid,
+			    r->in.rids->rids[i]);
 		result[i].type = types[i];
 		result[i].name = talloc_move(result, &names[i]);
 	}

Modified: branches/samba/experimental/source3/winbindd/winbindd_lookuprids.c
===================================================================
--- branches/samba/experimental/source3/winbindd/winbindd_lookuprids.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/winbindd/winbindd_lookuprids.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -24,6 +24,7 @@
 
 struct winbindd_lookuprids_state {
 	struct tevent_context *ev;
+	struct dom_sid domain_sid;
 	const char *domain_name;
 	struct wbint_RidArray rids;
 	struct wbint_Principals names;
@@ -42,7 +43,6 @@
 	struct tevent_req *req, *subreq;
 	struct winbindd_lookuprids_state *state;
 	struct winbindd_domain *domain;
-	struct dom_sid sid;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct winbindd_lookuprids_state);
@@ -56,16 +56,16 @@
 
 	DEBUG(3, ("lookuprids (%s)\n", request->data.sid));
 
-	if (!string_to_sid(&sid, request->data.sid)) {
+	if (!string_to_sid(&state->domain_sid, request->data.sid)) {
 		DEBUG(5, ("%s not a SID\n", request->data.sid));
 		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
 		return tevent_req_post(req, ev);
 	}
 
-	domain = find_lookup_domain_from_sid(&sid);
+	domain = find_lookup_domain_from_sid(&state->domain_sid);
 	if (domain == NULL) {
 		DEBUG(5, ("Domain for sid %s not found\n",
-			  sid_string_dbg(&sid)));
+			  sid_string_dbg(&state->domain_sid)));
 		tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN);
 		return tevent_req_post(req, ev);
 	}
@@ -84,8 +84,8 @@
 	}
 
 	subreq = dcerpc_wbint_LookupRids_send(
-		state, ev, dom_child_handle(domain), &state->rids,
-		&state->domain_name, &state->names);
+		state, ev, dom_child_handle(domain), &state->domain_sid,
+		&state->rids, &state->domain_name, &state->names);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}

Modified: branches/samba/experimental/source3/winbindd/winbindd_pam.c
===================================================================
--- branches/samba/experimental/source3/winbindd/winbindd_pam.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/winbindd/winbindd_pam.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1250,18 +1250,30 @@
 					info3);
 		}
 
-		if (NT_STATUS_EQUAL(result, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)
-		    && domain->can_do_samlogon_ex) {
-			DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
-				  "retrying with NetSamLogon\n"));
-			domain->can_do_samlogon_ex = false;
+		if (NT_STATUS_EQUAL(result, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
+
 			/*
 			 * It's likely that the server also does not support
 			 * validation level 6
 			 */
 			domain->can_do_validation6 = false;
-			retry = true;
-			continue;
+
+			if (domain->can_do_samlogon_ex) {
+				DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
+					  "retrying with NetSamLogon\n"));
+				domain->can_do_samlogon_ex = false;
+				retry = true;
+				continue;
+			}
+
+
+			/* Got DCERPC_FAULT_OP_RNG_ERROR for SamLogon
+			 * (no Ex). This happens against old Samba
+			 * DCs. Drop the connection.
+			 */
+			invalidate_cm_connection(&domain->conn);
+			result = NT_STATUS_LOGON_FAILURE;
+			break;
 		}
 
 		if (domain->can_do_validation6 &&

Modified: branches/samba/experimental/source3/winbindd/winbindd_sids_to_xids.c
===================================================================
--- branches/samba/experimental/source3/winbindd/winbindd_sids_to_xids.c	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/winbindd/winbindd_sids_to_xids.c	2011-07-28 16:06:15 UTC (rev 3863)
@@ -201,7 +201,7 @@
 			break;
 		};
 		t->domain_index = n->sid_index;
-		sid_peek_rid(&state->sids[i], &t->rid);
+		sid_peek_rid(&state->non_cached[i], &t->rid);
 		t->unix_id = (uint64_t)-1;
 	}
 
@@ -268,6 +268,9 @@
 			}
 		} else {
 			unix_id = state->ids.ids[num_non_cached].unix_id;
+			if (unix_id == -1) {
+				found = false;
+			}
 			switch(state->ids.ids[num_non_cached].type) {
 			case WBC_ID_TYPE_UID:
 				type = 'U';

Modified: branches/samba/experimental/source3/wscript_build
===================================================================
--- branches/samba/experimental/source3/wscript_build	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/source3/wscript_build	2011-07-28 16:06:15 UTC (rev 3863)
@@ -50,9 +50,6 @@
 
 LIBRPCCLI_NETLOGON_SRC = 'rpc_client/cli_netlogon.c rpc_client/util_netlogon.c'
 
-LIBCLI_WINREG_SRC = '''rpc_client/cli_winreg.c
-                       rpc_client/cli_winreg_int.c'''
-
 # this includes only the low level parse code, not stuff
 # that requires knowledge of security contexts
 REG_PARSE_PRS_SRC = '''registry/reg_parse_prs.c'''
@@ -404,7 +401,7 @@
 PRINTBACKEND_SRC = '''printing/printing.c
                       printing/nt_printing.c
                       printing/nt_printing_tdb.c
-                      printing/nt_printing_migrate.c
+                      printing/nt_printing_migrate_internal.c
                       printing/nt_printing_ads.c'''
 
 SMBD_SRC = '''${SMBD_SRC_BASE} ${SMBD_SRC_MAIN}'''
@@ -640,13 +637,6 @@
 t.env.SRCDIR = bld.path.abspath()
 t.env.BUILDDIR = bld.path.abspath()
 
-if not bld.env.toplevel_build:
-    bld.SAMBA_GENERATOR('smbtorture4',
-			source='',
-			target='',
-			rule='cd ../; make -f Makefile-smbtorture4 bin/smbtorture4',
-			always=True)
-
 bld.SETUP_BUILD_GROUPS()
 
 if not bld.env.toplevel_build:
@@ -889,9 +879,15 @@
 
 bld.SAMBA3_SUBSYSTEM('PRINTBACKEND',
                     source=PRINTBACKEND_SRC,
-                    deps='PRINTBASE NDR_NTPRINTING LIBADS_PRINTER',
+                    deps='PRINTBASE LIBADS_PRINTER tdb printing_migrate',
                     vars=locals())
 
+bld.SAMBA3_LIBRARY('printing_migrate',
+                    source='printing/nt_printing_migrate.c rpc_client/cli_winreg_spoolss.c printing/nt_printing_os2.c',
+                    deps='NDR_NTPRINTING LIBCLI_SPOOLSS RPC_NDR_WINREG LIBCLI_WINREG param',
+                    vars=locals(),
+                    private_library=True)
+
 bld.SAMBA3_SUBSYSTEM('PRINTING',
                     source=PRINTING_SRC,
                     deps='NDR_PRINTCAP',
@@ -997,14 +993,19 @@
                     source=LIBRPCCLI_NETLOGON_SRC,
                     deps='RPC_NDR_NETLOGON')
 
-bld.SAMBA3_SUBSYSTEM('LIBCLI_SPOOLSS',
-                    source=LIBCLI_SPOOLSS_SRC,
-                    deps='RPC_NDR_SPOOLSS')
+bld.SAMBA3_LIBRARY('LIBCLI_SPOOLSS',
+                   source=LIBCLI_SPOOLSS_SRC,
+                   deps='RPC_NDR_SPOOLSS param SECRETS3',
+                   private_library=True)
 
 bld.SAMBA3_SUBSYSTEM('LIBCLI_WINREG',
-                    source=LIBCLI_WINREG_SRC,
+                    source='rpc_client/cli_winreg.c',
                     deps='RPC_NDR_WINREG')
 
+bld.SAMBA3_SUBSYSTEM('LIBCLI_WINREG_INTERNAL',
+                    source='rpc_client/cli_winreg_int.c',
+                    deps='LIBCLI_WINREG RPC_NCACN_NP')
+
 bld.SAMBA3_SUBSYSTEM('RPC_CLIENT_SCHANNEL',
 	source=RPC_CLIENT_SCHANNEL_SRC,
 	vars=locals())
@@ -1092,6 +1093,7 @@
                  LIBCLI_SAMR LIBCLI_LSA3 LIBRPCCLI_NETLOGON LIBCLI_SPOOLSS
                  RPC_NDR_SRVSVC RPC_NDR_WKSSVC RPC_NDR_SVCCTL RPC_NDR_DSSETUP
                  RPC_NDR_INITSHUTDOWN RPC_NDR_DRSUAPI INIT_NETLOGON INIT_SAMR
+                 printing_migrate
 		 ''',
                  vars=locals())
 

Deleted: branches/samba/experimental/upgrading-samba4.txt
===================================================================
--- branches/samba/experimental/upgrading-samba4.txt	2011-07-28 15:49:50 UTC (rev 3862)
+++ branches/samba/experimental/upgrading-samba4.txt	2011-07-28 16:06:15 UTC (rev 3863)
@@ -1,18 +0,0 @@
-Upgrading from an older samba4 installation.
-
-* Compile the new version of samba4 by following the HOWTO, but do
-  not install it yet, and do not run provision.
-* Stop any samba process
-* Backup your samba4 provision:
-  go into the directory where your samba4 provision is stored (/usr/local/samba by default)
-  do tar cf $HOME/backup.tar private etc var sysvol
-* Go into the source4 dir
-* run ./scripting/bin/upgradeprovision -s <path to smb.conf in samba4 install>
-* do make install
-
-This will do the minimum (safest) upgrade of the data.  
-
-Runing upgradeprovision with --full will do a more comprehensive
-upgrade of the data (including schema and display specifiers).  This
-attempts to do a new provision, and to then copy existing data into
-that database.





More information about the Pkg-samba-maint mailing list